Skip to content
 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

186 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

avm-res-remotebackend-oidc-wif-git-flow

This module provisions all required Azure resources for Terraform remote backend and Terraform Git Flow Automation pipeline configurations

Fully modular and flexible (see examples)

  • Everything optional
  • Any quantity
  • Resources automatically linked (eg key vault ref in app config)
  • Attributes fully customizable (eg. sku_name, public_access, etc.)

It provisions on Azure:

  • Resource group
  • App Configuration (tfvars)
  • Storage container (remote backend)
  • DevOps Pool (agents)
  • Service Connection with WorkloadIdentityFederation (OIDC)
  • Scope specific RBAC role assignments for above resources (service principal)

Architecture

Requirements

The following requirements are needed by this module:

Resources

The following resources are used by this module:

Required Inputs

The following input variables are required:

Description: This variable helps connect the pool to the devops organization.

Type: string

Description: Name of the resource group.

Type: string

Optional Inputs

The following input variables are optional (have default values):

Description: A map of app configurations to create for tfvars. The map key is arbitrary; the value supports the following attributes. Defaults to {} (no app configurations).

  • name - (Required) The name of the Container which should be created within the Storage Account. Changing this forces a new resource to be created.

  • location - (Optional) The Azure location where the resources will be deployed. Defaults to the location of the storage account.

  • resource_group_name - (Optional) The resource group where the resources will be deployed. Defaults to the resource group of the storage account.

  • public_network_access_enabled (Optional) Whether to enable public network access, default is false.

  • sku- (Optional) The SKU of the resource. Valid values are free, developer, standard, and premium. Set soft_delete_retention_days to null for free sku. Default is developer

  • purge_protection_enabled - (Optional) Whether to enable purge protection, default is false.

  • soft_delete_retention_days - (Optional) The number of days that items are retained before being permanently deleted. Default is null.

  • vault_references - (Optional) Map of objects for vault references. secret_key refers to the key value from the keys object within keyvaults input variable.

  • key_values - (Optional) A map a key-value pairs to prefill the configuration with.

  • role_assignments - (Optional) A map of role assignments to create on the container. Defaults to {}. See var.role_assignments for the attribute schema.

Example Input:

appconfigurations = {
  tf_tfvars = {
    name                       = module.naming.app_configuration.name_unique
    purge_protection_enabled   = false
    soft_delete_retention_days = null
    vault_references = {
      key_ref_1 = {
        name = "vault_ref1"
        secret_key = "secret_1"
      }
    }
  }
}

Type:

map(object({
    name                          = string
    location                      = optional(string, null)
    resource_group_name           = optional(string, null)
    public_network_access_enabled = optional(bool, false)
    sku                           = optional(string, "developer")
    purge_protection_enabled      = optional(bool, false)
    soft_delete_retention_days    = optional(number, null)
    vault_references = optional(map(object({
      name       = string
      secret_key = string
    })), {})
    key_values = optional(map(object({
      key          = string
      value        = string
      content_type = optional(string, null)
      label        = optional(string, null)
      tags         = optional(map(string), null)
    })), {})

    role_assignments = optional(map(object({
      role_definition_id_or_name             = string
      principal_id                           = string
      principal_type                         = optional(string, null)
      description                            = optional(string, null)
      skip_service_principal_aad_check       = optional(bool, false)
      condition                              = optional(string, null)
      condition_version                      = optional(string, null)
      delegated_managed_identity_resource_id = optional(string, null)
    })), {})
  }))

Default: {}

Description: A map of dev centers to create for a pool. The map key is arbitrary; the value supports the following attributes. Defaults to {} (no dev centers).

  • name - (Required) The name of the Container which should be created within the Storage Account. Changing this forces a new resource to be created.
  • location - (Optional) The Azure location where the resources will be deployed. Defaults to the location of the storage account.
  • resource_group_name - (Optional) The resource group where the resources will be deployed. Defaults to the resource group of the storage account.
  • projects - (Optional) A map of project objects. Defaults to {}.
  • role_assignments - (Optional) A map of role assignments to create on the container. Defaults to {}. See var.role_assignments for the attribute schema.

Example Input:

devcenters = {
  center_1 = {
    name = module.naming.app_configuration.name_unique
    projects = {
      project_1 = {
        name = module.naming.app_configuration.name_unique
        pools = {
          pool1 = {
            name                 = module.naming.app_configuration.name_unique
            storage_account_type = "Standard"
            maximum_concurrency  = 1
            profile_images = [
              {
                "aliases" : [
                  "ubuntu-24.04-g2",
                  "git-automation",
                ],
                "well_known_image_name" : "ubuntu-24.04-g2/latest"
              }
            ]
          }
          pool2 = {
            name                = module.naming.app_configuration.name_unique
            maximum_concurrency = 1
          }
        }
      }
    }
  }
}

Type:

map(object({
    name                = string
    location            = optional(string, null)
    resource_group_name = optional(string, null)

    projects = optional(map(object({
      name                = string
      location            = optional(string, null)
      resource_group_name = optional(string, null)
      # center_key          = string
      pools = optional(map(object({
        name = string
        # project_key         = string
        maximum_concurrency           = number
        storage_account_type          = optional(string, "Standard")
        sku_name                      = optional(string, "Standard_D2ads_v5")
        enable_telemetry              = optional(bool, false)
        prediction_profile_automatice = optional(string, "MostCostEffective")
        # image_alias                   = optional(string, "az-pipeline")
        # well_known_image_name         = optional(string, "ubuntu-24.04-g2/latest")
        profile_images = optional(list(object({
          resource_id           = optional(string)
          well_known_image_name = optional(string)
          buffer                = optional(string, "*")
          aliases               = optional(list(string))
          })), [
          {
            "aliases" : [
              "ubuntu-24.04-g2",
              "az-pipeline",
            ],
            "well_known_image_name" : "ubuntu-24.04-g2/latest"
          }
        ])

      })), {})

      role_assignments = optional(map(object({
        role_definition_id_or_name             = string
        principal_id                           = string
        principal_type                         = optional(string, null)
        description                            = optional(string, null)
        skip_service_principal_aad_check       = optional(bool, false)
        condition                              = optional(string, null)
        condition_version                      = optional(string, null)
        delegated_managed_identity_resource_id = optional(string, null)
      })), {})
    })), {})
    role_assignments = optional(map(object({
      role_definition_id_or_name             = string
      principal_id                           = string
      principal_type                         = optional(string, null)
      description                            = optional(string, null)
      skip_service_principal_aad_check       = optional(bool, false)
      condition                              = optional(string, null)
      condition_version                      = optional(string, null)
      delegated_managed_identity_resource_id = optional(string, null)
    })), {})
  }))

Default: {}

Description: ID of the Azure DevOps project.

Type: string

Default: null

Description: This variable controls whether or not telemetry is enabled for the module.
For more information see https://aka.ms/avm/telemetryinfo.
If it is set to false, then no telemetry will be collected.

Type: bool

Default: true

Description: Name of the environment to manage.

Type: string

Default: "todo"

Description: Optional. A map of key vaults to create which can be linked to an app config. The map key is arbitrary; the value supports the following attributes. Defaults to {} (no key vaults).

  • name - (Required) The name of the Container which should be created within the Storage Account. Changing this forces a new resource to be created.
  • location - (Optional) The Azure location where the resources will be deployed. Defaults to the location of the storage account.
  • resource_group_name - (Optional) The resource group where the resources will be deployed. Defaults to the resource group of the storage account.
  • role_assignments - (Optional) A map of role assignments to create on the container. Defaults to {}. See var.role_assignments for the attribute schema.
  • network_acls - (Optional) The network ACL configuration for the Key Vault. If not specified then the Key Vault will be created with a firewall that blocks access. Specify null to create the Key Vault with no firewall. - bypass - (Optional) Should Azure Services bypass the ACL. Possible values are AzureServices and None. Defaults to None. - default_action - (Optional) The default action when no rule matches. Possible values are Allow and Deny. Defaults to Deny. - ip_rules - (Optional) A list of IP rules in CIDR format. Defaults to []. - virtual_network_subnet_ids - (Optional) When using with Service Endpoints, a list of subnet IDs to associate with the Key Vault. Defaults to [].
  • public_network_access_enabled - (Optional) Specifies whether public access is permitted. Default false
  • sku - (Optional) The SKU name of the Key Vault. Default is standard. Possible values are standard and premium.
  • purge_protection_enabled - (Optional) Specifies whether protection against purge is enabled for this Key Vault. Note once enabled this cannot be disabled.
  • soft_delete_retention_days - (Optional) The number of days that items should be retained for once soft-deleted. This value can be between 7 and 90 (the default) days.
  • keys - (Optional) A map of keys to create on the Key Vault. The map key is deliberately arbitrary to avoid issues where map keys maybe unknown at plan time. - name - The name of the key. - key_type - The type of the key. Possible values are EC and RSA. - key_opts - A list of key options. Possible values are decrypt, encrypt, sign, unwrapKey, verify, and wrapKey. - key_size - The size of the key. Required for RSA keys. - curve - The curve of the key. Required for EC keys. Possible values are P-256, P-256K, P-384, and P-521. The API will default to P-256 if nothing is specified. - not_before_date - The not before date of the key. - expiration_date - The expiration date of the key. - tags - A mapping of tags to assign to the key. - rotation_policy - The rotation policy of the key. - automatic - The automatic rotation policy of the key. - time_after_creation - The time after creation of the key before it is automatically rotated. - time_before_expiry - The time before expiry of the key before it is automatically rotated. - expire_after - The time after which the key expires. - notify_before_expiry - The time before expiry of the key when notification emails will be sent. Supply role assignments in the same way as for var.role_assignments.
  • secrets - (Optional) A map of secrets to create on the Key Vault. The map key is deliberately arbitrary to avoid issues where map keys maybe unknown at plan time. - name - The name of the secret. - content_type - The content type of the secret. - tags - A mapping of tags to assign to the secret. - not_before_date - The not before date of the secret. - expiration_date - The expiration date of the secret. Supply role assignments in the same way as for var.role_assignments. > Note: the value of the secret is supplied via the var.secrets_value variable. Make sure to use the same map key.
  • secrets_value - (Optional) A map of secret keys to values. The map key is the supplied input to var.secrets. The map value is the secret value. This is a separate variable to var.secrets because it is sensitive and therefore cannot be used in a for_each loop.

Example Input:

keyvaults = {
  key_vault_1 = {
    name = module.naming.key_vault.name_unique
    keys = {
      secret_1 = {
        name     = module.naming.key_vault_key.name_unique
        key_type = "RSA"
        key_size = 2048
        key_opts = [
          "decrypt",
          "encrypt",
          "sign",
          "unwrapKey",
          "verify",
          "wrapKey"
        ]
        enabled = true
      }
    }

    secrets = {
      secret_1 = {
        name = module.naming.key_vault_secret.name_unique
      }
    }

    secrets_value = {
      secret_1 = "supersecretpassword123"
    }
  }
}

Type:

map(object({
    name                = string
    location            = optional(string, null)
    resource_group_name = optional(string, null)

    network_acls = optional(object({
      bypass                     = optional(string, "None")
      default_action             = optional(string, "Deny")
      ip_rules                   = optional(list(string), [])
      virtual_network_subnet_ids = optional(list(string), [])
      })
    , null)
    public_network_access_enabled = optional(bool, false)
    sku                           = optional(string, "standard")
    purge_protection_enabled      = optional(bool, false)
    soft_delete_retention_days    = optional(number, null)

    keys = optional(map(object({
      name            = string
      key_type        = string
      key_opts        = optional(list(string), ["sign", "verify"])
      key_size        = optional(number, null)
      curve           = optional(string, null)
      not_before_date = optional(string, null)
      expiration_date = optional(string, null)
      tags            = optional(map(any), null)
      role_assignments = optional(map(object({
        role_definition_id_or_name             = string
        principal_id                           = string
        description                            = optional(string, null)
        skip_service_principal_aad_check       = optional(bool, false)
        condition                              = optional(string, null)
        condition_version                      = optional(string, null)
        delegated_managed_identity_resource_id = optional(string, null)
        principal_type                         = optional(string, null)
      })), {})
      rotation_policy = optional(object({
        automatic = optional(object({
          time_after_creation = optional(string, null)
          time_before_expiry  = optional(string, null)
        }), null)
        expire_after         = optional(string, null)
        notify_before_expiry = optional(string, null)
      }), null)
    })), {})

    secrets = optional(map(object({
      name            = string
      content_type    = optional(string, null)
      tags            = optional(map(any), null)
      not_before_date = optional(string, null)
      expiration_date = optional(string, null)

      role_assignments = optional(map(object({
        role_definition_id_or_name             = string
        principal_id                           = string
        description                            = optional(string, null)
        skip_service_principal_aad_check       = optional(bool, false)
        condition                              = optional(string, null)
        condition_version                      = optional(string, null)
        delegated_managed_identity_resource_id = optional(string, null)
        principal_type                         = optional(string, null)
      })), {})
    })), {})

    secrets_value = optional(map(string), null)

    role_assignments = optional(map(object({
      role_definition_id_or_name             = string
      principal_id                           = string
      principal_type                         = optional(string, null)
      description                            = optional(string, null)
      skip_service_principal_aad_check       = optional(bool, false)
      condition                              = optional(string, null)
      condition_version                      = optional(string, null)
      delegated_managed_identity_resource_id = optional(string, null)
    })), {})
  }))

Default: {}

Description: Azure region where the resource should be deployed.

Type: string

Default: "West Europe"

Description: Controls the Resource Lock configuration for this resource. The following properties can be specified:

  • kind - (Required) The type of lock. Possible values are \"CanNotDelete\" and \"ReadOnly\".
  • name - (Optional) The name of the lock. If not specified, a name will be generated based on the kind value. Changing this forces the creation of a new resource.

Type:

object({
    kind = string
    name = optional(string, null)
  })

Default: null

Description: This variable controls whether or not purge_protection is enabled for the module.

Type: bool

Default: true

Description: Override the AzAPI <provider>/<resource>@<api-version> strings used by this module. Each key defaults to a tested value; supply only the keys you want to override. Useful when targeting a sovereign cloud with older API versions, or when opting into a newer preview API.

  • devcenter - The devcenter, used by the project.
  • project - The project, used by the pool.
  • lock - Management lock applied to the storage account (and to private endpoints when configured).

Type:

object({
    resourcegroup = optional(string, "Microsoft.Resources/resourceGroups@2025-04-01")
    devcenter     = optional(string, "Microsoft.DevCenter/devCenters@2025-02-01")
    project       = optional(string, "Microsoft.DevCenter/projects@2025-02-01")
    lock          = optional(string, "Microsoft.Authorization/locks@2020-05-01")
  })

Default: {}

Description: A map of role assignments to create on this resource. The map key is deliberately arbitrary to avoid issues where map keys maybe unknown at plan time.

  • role_definition_id_or_name - The ID or name of the role definition to assign to the principal.
  • principal_id - The ID of the principal to assign the role to.
  • description - The description of the role assignment.
  • skip_service_principal_aad_check - If set to true, skips the Azure Active Directory check for the service principal in the tenant. Defaults to false.
  • condition - The condition which will be used to scope the role assignment.
  • condition_version - The version of the condition syntax. Valid values are '2.0'.
  • delegated_managed_identity_resource_id - The delegated Azure Resource Id which contains a Managed Identity. Changing this forces a new resource to be created.
  • principal_type - The type of the principal_id. Possible values are User, Group and ServicePrincipal. Changing this forces a new resource to be created. It is necessary to explicitly set this attribute when creating role assignments if the principal creating the assignment is constrained by ABAC rules that filters on the PrincipalType attribute.

Note: only set skip_service_principal_aad_check to true if you are assigning a role to a service principal.

Type:

map(object({
    role_definition_id_or_name             = string
    principal_id                           = string
    description                            = optional(string, null)
    skip_service_principal_aad_check       = optional(bool, false)
    condition                              = optional(string, null)
    condition_version                      = optional(string, null)
    delegated_managed_identity_resource_id = optional(string, null)
    principal_type                         = optional(string, null)
  }))

Default: {}

Description: A reference to the service connection object and used to assign roles to a service principal. Required if serviceconnections is defined.

Example Input:

serviceconnections = {
  oidc_wip = {
    name = "Managed Terraform Git Automation Service Connection"
    ...
  }
}
service_connection_key = "oidc_wip"

Type: string

Default: null

Description: A map of service connections to create on the parent subscription. The map key is arbitrary; the value supports the following attributes. Defaults to {} (no service connections).

  • name - (Required) The Service Endpoint Name.
  • devops_project_name - (Required) The Project Name.
  • app_registration_name - (Optional) The display name for the application.
  • service_endpoint_authentication_scheme (WIP) Specifies the type of Azure Resource Manager Service Endpoint. Possible values are WorkloadIdentityFederation, ManagedServiceIdentity or ServicePrincipal. Defaults to ServicePrincipal for backwards compatibility.

Example Input:

serviceconnections = {
  oidc_wip = {
    name                = "Managed Terraform Git Automation Service Connection"
    devops_project_name = local.project_name
    application_name    = "Managed Terraform Git Automation Application"
  }
}
service_connection_key = "oidc_wip"

Type:

map(object({
    name                                   = string
    application_name                       = optional(string, null)
    service_endpoint_authentication_scheme = optional(string, "ServicePrincipal")
  }))

Default: {}

Description: The number of days that items are retained before being permanently deleted. Default is 7. Set to null for free sku.

Type: number

Default: 7

Description: A map of to create on the parent resource group. The map key is arbitrary; the value supports the following attributes. Defaults to {} (no storage containers).

  • name - (Required) The name of the Container which should be created within the Storage Account. Changing this forces a new resource to be created.
  • location - (Optional) The Azure location where the resources will be deployed. Defaults to the location of the storage account.
  • resource_group_name - (Optional) The resource group where the resources will be deployed. Defaults to the resource group of the storage account.
  • account_sku_name (Optional) Explicit storage account SKU name (e.g. Standard_LRS, Premium_ZRS, PremiumV2_LRS, StandardV2_GZRS). When set, this value is sent to Azure verbatim and overrides the SKU derived from account_tier, account_replication_type and provisioned_billing_model_version - those variables are only honoured when account_sku_name is explicitly set to null. Defaults to Standard_ZRS. Note: the *V2_* SKUs (e.g. StandardV2_ZRS, PremiumV2_ZRS) require account_kind = "FileStorage". Default: "Standard_ZRS"
  • public_network_access_enabled (Optional) Whether the public network access is enabled? Defaults to false.
  • network_rules (Optional) Network rules restricting access to the storage account. Defaults to {}, which applies the object's own per-attribute defaults (effectively default_action = "Deny" with bypass = ["AzureServices"]). > Note: the default value blocks all public access to the storage account. If you want to disable all network rules, set this value to null. - bypass - (Optional) Specifies whether traffic is bypassed for Logging/Metrics/AzureServices. Valid options are any combination of Logging, Metrics, AzureServices, or None. Defaults to ["AzureServices"]. - default_action - (Optional) Specifies the default action of allow or deny when no other rules match. Valid options are Deny or Allow. Defaults to Deny. - ip_rules - (Optional) List of public IP or IP ranges in CIDR format. Only IPv4 addresses are allowed. Private IP address ranges (as defined in RFC 1918) are not allowed. Defaults to []. - virtual_network_subnet_ids - (Optional) A set of virtual network subnet IDs to secure the storage account. Defaults to []. - private_link_access - (Optional) A list of private link access rules. Defaults to null. Each entry supports: - endpoint_resource_id - (Required) The resource ID of the resource access rule to be granted access. - endpoint_tenant_id - (Optional) The tenant ID of the resource of the resource access rule to be granted access. Defaults to the current tenant ID. - timeouts - (Optional) Per-operation timeouts for the network rules resource. Defaults to null (uses provider defaults). Supports: - create - (Optional) Timeout for create operations. - delete - (Optional) Timeout for delete operations. - read - (Optional) Timeout for read operations. - update - (Optional) Timeout for update operations. Default {}
  • role_assignments - (Optional) A map of role assignments to create on the container. Defaults to {}. See var.role_assignments for the attribute schema.

Example Input:

storageaccounts = {
  tf_state_account = {
    name = module.naming.storage_account.name_unique
    containers = {
      tf_state_container = {
        name = "tfstate"
      }
    }
  }
}

Type:

map(object({
    name                            = string
    location                        = optional(string, null)
    resource_group_name             = optional(string, null)
    account_sku_name                = optional(string, "Standard_LRS")
    shared_access_key_enabled       = optional(bool, false)
    default_to_oauth_authentication = optional(bool, true)
    public_network_access_enabled   = optional(bool, false)
    network_rules = optional(object({
      bypass                     = optional(set(string), ["AzureServices"])
      default_action             = optional(string, "Deny")
      ip_rules                   = optional(set(string), [])
      virtual_network_subnet_ids = optional(set(string), [])
      private_link_access = optional(list(object({
        endpoint_resource_id = string
        endpoint_tenant_id   = optional(string)
      })))
      timeouts = optional(object({
        create = optional(string)
        delete = optional(string)
        read   = optional(string)
        update = optional(string)
      }))
    }), null)

    containers = optional(map(object({
      name                       = optional(string, "tfstate")
      container_access_type      = optional(string, "private")
      rbac_authorization_enabled = optional(bool, true)

      role_assignments = optional(map(object({
        role_definition_id_or_name             = string
        principal_id                           = string
        principal_type                         = optional(string, null)
        description                            = optional(string, null)
        skip_service_principal_aad_check       = optional(bool, false)
        condition                              = optional(string, null)
        condition_version                      = optional(string, null)
        delegated_managed_identity_resource_id = optional(string, null)
      })), {})
    })), {})

  }))

Default: {}

Description: (Optional) Tags of the resource.

Type: map(string)

Default: null

Outputs

The following outputs are exported:

Description: A map of all created app config endpoints

Description: A map of all created storage account names

Description: A map of all created storage container names

Description: The resource group.

Description: The azapi_client_config tenant ID

Description: The service principal client ID

Description: The service principal client ID

Modules

The following Modules are called:

Source: Azure/avm-res-appconfiguration-configurationstore/azure

Version: 0.5.1

Source: Azure/avm-res-resources-resourcegroup/azurerm

Version: 0.4.0

Source: ./modules/devcenter

Version:

Source: Azure/avm-res-keyvault-vault/azurerm

Version: 0.10.2

Source: Azure/avm-res-devopsinfrastructure-pool/azurerm

Version: 0.3.1

Source: ./modules/project

Version:

Source: ./modules/serviceconnection

Version:

Source: Azure/avm-res-storage-storageaccount/azurerm

Version: 0.7.2

Pipelines

Azure DevOps pipeline integration (see pipelines folder):

  • Generate Terraform pipeline plan on PR creation
  • Apply Terraform pipeline plan on PR merge
  • Agnostic multi-environment (eg. development, staging, prod1, prod2)
  • Connected with the service connection
  • DevOps Pool integration
  • App config integration
  • Simple one-time setup using Variable(s) (groups)

It will connect everything automatically:

  • TFVARS pre-filled in the app config (with key vault compatibility)
  • Example backend config pre-filled (for state migration)
  • DevOps pools using alias

Terraform-git-automation

Requirements

Azure DevOps Marketplace extension:

Pipelines

The following pipelines are used by this module:

Description: The Plan stage in this pipeline can be configured to trigger on the creation of a PR to generate a Terraform plan for those changes. Will be used in conjunction with the service connection that was provisioned by the module.

Jobs

  • Generate - Job for generating and posting a plan based on the Terraform config changes in the PR.

Variables:

  • environment_name - (Required) The source folder for the Terraform configuration, used to make the pipeline multi-environment.
  • trigger - (Optional) The trigger is configured through branch policies. Defaults to none.
  • pool - (Optional) The agent pool where the pipeline will be deployed. Defaults to $(environment_name)-motte-pipeline.

Steps:

  • Configure git authentication header - Uses Git CLI to set OIDC WIP Authentication Headers
  • Extract App Config as File - Uses Azure CLI to fetch tfvars from App Configuration using the app-config-endpoint pipeline variable.
  • Terraform Init - Uses Terraform Extension task to initialize Terraform.
  • Terraform Plan - Uses Terraform Extension task to generate a plan and convert it to a text format.
  • Publish Artifact - Uses Azure task to publish the plan as artifact
  • Post Comment - Uses Azure CLI to post the plan as a comment to the connected PR.

Description: This pipeline can be configured to trigger when changes are merged to a branch that manages Terraform configurations. Will be used in conjunction with the service connection that was provisioned by the module.

Jobs:

  • Apply - Job for applying a Terraform plan after the PR is approved and merged.
  • Comment - Job for retrieving and posting apply output from applying a Terraform Plan.

Variables:

  • environment_name - (Required) The source folder for the Terraform configuration, used to make the pipeline multi-environment.
  • trigger - (Optional) The trigger is configured on branch merge and can be overridden for secondary staging environments. Defaults to master.
  • pool - (Optional) The agent pool where the pipeline will be deployed. Defaults to $(environment_name)-motte-pipeline.

Steps:

  • Configure git authentication header - Uses Git CLI to set OIDC WIP Authentication Headers
  • Download Artifact - Download the Artifact from the Plan pipeline.
  • Terraform Init - Uses Terraform Extension task to initialize Terraform.
  • Terraform Apply - Uses Terraform Extension task to apply a plan and convert the output to a text format.
  • Get PR ID - Uses Azure CLI to retrieve the PR ID.
  • Post Comment - Uses Azure CLI to post the output as a comment to the connected PR.

Data Collection

The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the repository. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.

About

This module provisions all required Azure resources for Terraform remote backend and Terraform Git Flow Automation pipeline configurations for Azure DevOps.

Topics

Resources

Code of conduct

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages