diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
index 12fa4de..7724649 100644
--- a/.github/workflows/e2e.yml
+++ b/.github/workflows/e2e.yml
@@ -1,99 +1,29 @@
---
-name: e2e test
-
-on:
- pull_request:
- types: ['opened', 'reopened', 'synchronize']
- merge_group:
- workflow_dispatch:
-
-permissions:
- contents: read
- id-token: write
-
-jobs:
- getexamples:
- if: github.event.repository.name != 'terraform-azurerm-avm-template'
- runs-on: ubuntu-latest
- outputs:
- examples: ${{ steps.getexamples.outputs.examples }}
- steps:
- - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7
- - name: get examples
- id: getexamples
- uses: Azure/terraform-azurerm-avm-template/.github/actions/e2e-getexamples@main
- with:
- github-token: ${{ secrets.GITHUB_TOKEN }}
-
- testexamples:
- if: github.event.repository.name != 'terraform-azurerm-avm-template'
- runs-on: [ self-hosted, 1ES.Pool=e78e43ca15cb1c862867ae2068c00e497f4dd342 ]
- needs: getexamples
- environment: test
- env:
- TF_IN_AUTOMATION: 1
- TF_VAR_enable_telemetry: false
- strategy:
- matrix:
- example: ${{ fromJson(needs.getexamples.outputs.examples) }}
- fail-fast: false
- steps:
- - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7
-
- - name: Test example
- shell: bash
- env:
- SECRETS_CONTEXT: ${{ toJson(secrets) }}
- VARS_CONTEXT: ${{ toJson(vars) }}
- run: |
- set -e
- MAX_RETRIES=10
- RETRY_COUNT=0
- until [ $RETRY_COUNT -ge $MAX_RETRIES ]
- do
- az login --identity --username $MSI_ID > /dev/null && break
- RETRY_COUNT=$[$RETRY_COUNT+1]
- sleep 10
- done
- if [ $RETRY_COUNT -eq $MAX_RETRIES ]; then
- echo "Failed to login after $MAX_RETRIES attempts."
- exit 1
- fi
-
- declare -A secrets
- eval "$(echo $SECRETS_CONTEXT | jq -r 'to_entries[] | @sh "secrets[\(.key|tostring)]=\(.value|tostring)"')"
-
- declare -A variables
- eval "$(echo $VARS_CONTEXT | jq -r 'to_entries[] | @sh "variables[\(.key|tostring)]=\(.value|tostring)"')"
-
- for key in "${!secrets[@]}"; do
- if [[ $key = \TF_VAR_* ]]; then
- lowerKey=$(echo "$key" | tr '[:upper:]' '[:lower:]')
- finalKey=${lowerKey/tf_var_/TF_VAR_}
- export "$finalKey"="${secrets[$key]}"
- fi
- done
-
- for key in "${!variables[@]}"; do
- if [[ $key = \TF_VAR_* ]]; then
- lowerKey=$(echo "$key" | tr '[:upper:]' '[:lower:]')
- finalKey=${lowerKey/tf_var_/TF_VAR_}
- export "$finalKey"="${variables[$key]}"
- fi
- done
-
- echo -e "Custom environment variables:\n$(env | grep TF_VAR_ | grep -v ' "TF_VAR_')"
-
- export ARM_SUBSCRIPTION_ID=$(az login --identity --username $MSI_ID | jq -r '.[0] | .id')
- export ARM_TENANT_ID=$(az login --identity --username $MSI_ID | jq -r '.[0] | .tenantId')
- export ARM_CLIENT_ID=$(az identity list | jq -r --arg MSI_ID "$MSI_ID" '.[] | select(.principalId == $MSI_ID) | .clientId')
- docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v $(pwd):/src -w /src --network=host -e TF_IN_AUTOMATION -e TF_VAR_enable_telemetry -e AVM_MOD_PATH=/src -e AVM_EXAMPLE=${{ matrix.example }} -e MSI_ID -e ARM_SUBSCRIPTION_ID -e ARM_TENANT_ID -e ARM_CLIENT_ID -e ARM_USE_MSI=true --env-file <(env | grep TF_VAR_ | grep -v ' "TF_VAR_') mcr.microsoft.com/azterraform:latest make test-example
-
- # This job is only run when all the previous jobs are successful.
- # We can use it for PR validation to ensure all examples have completed.
- testexamplescomplete:
- if: github.event.repository.name != 'terraform-azurerm-avm-template'
- runs-on: ubuntu-latest
- needs: testexamples
- steps:
- - run: echo "All tests passed"
+ name: test examples
+ on:
+ pull_request:
+ types: ['opened', 'reopened', 'synchronize']
+ merge_group:
+ workflow_dispatch:
+
+ jobs:
+ check:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checking for Fork
+ shell: pwsh
+ run: |
+ $isFork = "${{ github.event.pull_request.head.repo.fork }}"
+ if($isFork -eq "true") {
+ echo "### WARNING: This workflow is disabled for forked repositories. Please follow the [release branch process](https://azure.github.io/Azure-Verified-Modules/contributing/terraform/terraform-contribution-flow/#5-create-a-pull-request-to-the-upstream-repository) if end to end tests are required." >> $env:GITHUB_STEP_SUMMARY
+ }
+
+ run-e2e-tests:
+ if: github.event.repository.name != 'terraform-azurerm-avm-template' && github.event.pull_request.head.repo.fork == false
+ uses: Azure/terraform-azurerm-avm-template/.github/workflows/test-examples-template.yml@main
+ name: end to end
+ secrets: inherit
+ permissions:
+ id-token: write
+ contents: read
+
\ No newline at end of file
diff --git a/README.md b/README.md
index eedff9a..8d52edd 100644
--- a/README.md
+++ b/README.md
@@ -327,7 +327,7 @@ Default: `null`
### [container\_app\_subnet\_name](#input\_container\_app\_subnet\_name)
-Description: The name of the subnet. Must be specified if `virtual_network_creation_enabled == false`.
+Description: The name of the subnet. Must be specified if `virtual_network_creation_enabled` is `true`.
Type: `string`
@@ -886,7 +886,7 @@ Default: `"repo"`
### [virtual\_network\_address\_space](#input\_virtual\_network\_address\_space)
-Description: The address space for the virtual network. Must be specified if `virtual_network_creation_enabled == false`.
+Description: The address space for the virtual network. Must be specified if `virtual_network_creation_enabled` is `true`.
Type: `string`
@@ -900,9 +900,17 @@ Type: `bool`
Default: `true`
+### [virtual\_network\_id](#input\_virtual\_network\_id)
+
+Description: The ID of the virtual network. Only required if `virtual_network_creation_enabled` is `false`.
+
+Type: `string`
+
+Default: `null`
+
### [virtual\_network\_name](#input\_virtual\_network\_name)
-Description: The name of the virtual network. Must be specified if `virtual_network_creation_enabled == false`.
+Description: The name of the virtual network. Must be specified if `virtual_network_creation_enabled` is `true`.
Type: `string`
diff --git a/avm b/avm
index 1bbbe36..1c6b0d2 100755
--- a/avm
+++ b/avm
@@ -27,7 +27,7 @@ fi
# Check if we are running in a container
# If we are then just run make directly
if [ -z "$AVM_IN_CONTAINER" ]; then
- $CONTAINER_RUNTIME run --pull always --user "$(id -u):$(id -g)" --rm $AZURE_VOLUME -v /etc/passwd:/etc/passwd -v /etc/group:/etc/group -v "$(pwd)":/src -w /src -e GITHUB_REPOSITORY -e GITHUB_REPOSITORY_OWNER mcr.microsoft.com/azterraform make "$1"
+ $CONTAINER_RUNTIME run --pull always --user "$(id -u):$(id -g)" --rm $AZURE_VOLUME -v "$(pwd)":/src -w /src -e GITHUB_REPOSITORY -e ARM_SUBSCRIPTION_ID -e GITHUB_REPOSITORY_OWNER mcr.microsoft.com/azterraform make "$1"
else
make "$1"
fi
diff --git a/avm.bat b/avm.bat
index 9138191..6b177be 100644
--- a/avm.bat
+++ b/avm.bat
@@ -18,6 +18,6 @@ IF "%~1"=="" (
)
REM Run the make target with CONTAINER_RUNTIME
-%CONTAINER_RUNTIME% run --pull always --rm -v "%cd%":/src -w /src --user "1000:1000" -e GITHUB_REPOSITORY -e GITHUB_REPOSITORY_OWNER mcr.microsoft.com/azterraform make %1
+%CONTAINER_RUNTIME% run --pull always --rm -v "%cd%":/src -w /src --user "1000:1000" -e ARM_SUBSCRIPTION_ID -e GITHUB_REPOSITORY -e GITHUB_REPOSITORY_OWNER mcr.microsoft.com/azterraform make %1
ENDLOCAL
diff --git a/examples/azure_devops_public_networking/README.md b/examples/azure_devops_public_networking/README.md
index 0057b98..e048bb1 100644
--- a/examples/azure_devops_public_networking/README.md
+++ b/examples/azure_devops_public_networking/README.md
@@ -30,6 +30,10 @@ locals {
terraform {
required_version = ">= 1.9"
required_providers {
+ azapi = {
+ source = "azure/azapi"
+ version = "~> 1.14"
+ }
azuredevops = {
source = "microsoft/azuredevops"
version = "~> 1.1"
@@ -134,6 +138,25 @@ resource "azuredevops_pipeline_authorization" "this" {
pipeline_id = azuredevops_build_definition.this.id
}
+locals {
+ resource_providers_to_register = {
+ dev_center = {
+ resource_provider = "Microsoft.App"
+ }
+ }
+}
+
+data "azurerm_client_config" "this" {}
+
+resource "azapi_resource_action" "resource_provider_registration" {
+ for_each = local.resource_providers_to_register
+
+ resource_id = "/subscriptions/${data.azurerm_client_config.this.subscription_id}"
+ type = "Microsoft.Resources/subscriptions@2021-04-01"
+ action = "providers/${each.value.resource_provider}/register"
+ method = "POST"
+}
+
# This is the module call
module "azure_devops_agents" {
source = "../.."
@@ -194,6 +217,8 @@ The following requirements are needed by this module:
- [terraform](#requirement\_terraform) (>= 1.9)
+- [azapi](#requirement\_azapi) (~> 1.14)
+
- [azuredevops](#requirement\_azuredevops) (~> 1.1)
- [azurerm](#requirement\_azurerm) (~> 3.113)
@@ -204,6 +229,7 @@ The following requirements are needed by this module:
The following resources are used by this module:
+- [azapi_resource_action.resource_provider_registration](https://registry.terraform.io/providers/azure/azapi/latest/docs/resources/resource_action) (resource)
- [azuredevops_agent_pool.this](https://registry.terraform.io/providers/microsoft/azuredevops/latest/docs/resources/agent_pool) (resource)
- [azuredevops_agent_queue.this](https://registry.terraform.io/providers/microsoft/azuredevops/latest/docs/resources/agent_queue) (resource)
- [azuredevops_build_definition.this](https://registry.terraform.io/providers/microsoft/azuredevops/latest/docs/resources/build_definition) (resource)
@@ -213,6 +239,7 @@ The following resources are used by this module:
- [azuredevops_project.this](https://registry.terraform.io/providers/microsoft/azuredevops/latest/docs/resources/project) (resource)
- [random_integer.region_index](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/integer) (resource)
- [random_string.name](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) (resource)
+- [azurerm_client_config.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config) (data source)
## Required Inputs
diff --git a/examples/azure_devops_public_networking/main.tf b/examples/azure_devops_public_networking/main.tf
index b08f248..a7e0538 100644
--- a/examples/azure_devops_public_networking/main.tf
+++ b/examples/azure_devops_public_networking/main.tf
@@ -24,6 +24,10 @@ locals {
terraform {
required_version = ">= 1.9"
required_providers {
+ azapi = {
+ source = "azure/azapi"
+ version = "~> 1.14"
+ }
azuredevops = {
source = "microsoft/azuredevops"
version = "~> 1.1"
@@ -128,6 +132,25 @@ resource "azuredevops_pipeline_authorization" "this" {
pipeline_id = azuredevops_build_definition.this.id
}
+locals {
+ resource_providers_to_register = {
+ dev_center = {
+ resource_provider = "Microsoft.App"
+ }
+ }
+}
+
+data "azurerm_client_config" "this" {}
+
+resource "azapi_resource_action" "resource_provider_registration" {
+ for_each = local.resource_providers_to_register
+
+ resource_id = "/subscriptions/${data.azurerm_client_config.this.subscription_id}"
+ type = "Microsoft.Resources/subscriptions@2021-04-01"
+ action = "providers/${each.value.resource_provider}/register"
+ method = "POST"
+}
+
# This is the module call
module "azure_devops_agents" {
source = "../.."
diff --git a/examples/bring_your_own_vnet/README.md b/examples/bring_your_own_vnet/README.md
new file mode 100644
index 0000000..7aaab76
--- /dev/null
+++ b/examples/bring_your_own_vnet/README.md
@@ -0,0 +1,380 @@
+
+# Azure DevOps example with private networking and bring your own virtual network
+
+This example deploys Azure DevOps Agents to Azure Container Apps and Azure Container Instance using private networking and bring your own virtual network.
+
+```hcl
+variable "azure_devops_organization_name" {
+ type = string
+ description = "Azure DevOps Organisation Name"
+}
+
+variable "azure_devops_personal_access_token" {
+ type = string
+ description = "The personal access token used for agent authentication to Azure DevOps."
+ sensitive = true
+}
+
+variable "azure_devops_agents_personal_access_token" {
+ description = "Personal access token for Azure DevOps self-hosted agents (the token requires the 'Agent Pools - Read & Manage' scope and should have the maximum expiry)."
+ type = string
+ sensitive = true
+}
+
+locals {
+ tags = {
+ scenario = "default"
+ }
+}
+
+terraform {
+ required_version = ">= 1.9"
+ required_providers {
+ azapi = {
+ source = "azure/azapi"
+ version = "~> 1.14"
+ }
+ azuredevops = {
+ source = "microsoft/azuredevops"
+ version = "~> 1.1"
+ }
+ azurerm = {
+ source = "hashicorp/azurerm"
+ version = "~> 3.113"
+ }
+ random = {
+ source = "hashicorp/random"
+ version = "~> 3.5"
+ }
+ }
+}
+
+provider "azurerm" {
+ features {}
+}
+
+locals {
+ azure_devops_organization_url = "https://dev.azure.com/${var.azure_devops_organization_name}"
+}
+
+provider "azuredevops" {
+ personal_access_token = var.azure_devops_personal_access_token
+ org_service_url = local.azure_devops_organization_url
+}
+
+resource "random_string" "name" {
+ length = 6
+ numeric = true
+ special = false
+ upper = false
+}
+
+module "naming" {
+ source = "Azure/naming/azurerm"
+ version = ">= 0.3.0"
+}
+
+resource "azuredevops_project" "this" {
+ name = random_string.name.result
+}
+
+resource "azuredevops_agent_pool" "this" {
+ name = random_string.name.result
+ auto_provision = false
+ auto_update = true
+}
+
+resource "azuredevops_agent_queue" "this" {
+ project_id = azuredevops_project.this.id
+ agent_pool_id = azuredevops_agent_pool.this.id
+}
+
+locals {
+ default_branch = "refs/heads/main"
+ pipeline_file = "pipeline.yml"
+ repository_name = "example-repo"
+}
+
+resource "azuredevops_git_repository" "this" {
+ project_id = azuredevops_project.this.id
+ name = local.repository_name
+ default_branch = local.default_branch
+ initialization {
+ init_type = "Clean"
+ }
+}
+
+resource "azuredevops_git_repository_file" "this" {
+ repository_id = azuredevops_git_repository.this.id
+ file = local.pipeline_file
+ content = templatefile("${path.module}/${local.pipeline_file}", {
+ agent_pool_name = azuredevops_agent_pool.this.name
+ })
+ branch = local.default_branch
+ commit_message = "[skip ci]"
+ overwrite_on_create = true
+}
+
+resource "azuredevops_build_definition" "this" {
+ project_id = azuredevops_project.this.id
+ name = "Example Build Definition"
+
+ ci_trigger {
+ use_yaml = true
+ }
+
+ repository {
+ repo_type = "TfsGit"
+ repo_id = azuredevops_git_repository.this.id
+ branch_name = azuredevops_git_repository.this.default_branch
+ yml_path = local.pipeline_file
+ }
+}
+
+resource "azuredevops_pipeline_authorization" "this" {
+ project_id = azuredevops_project.this.id
+ resource_id = azuredevops_agent_queue.this.id
+ type = "queue"
+ pipeline_id = azuredevops_build_definition.this.id
+}
+
+locals {
+ resource_providers_to_register = {
+ dev_center = {
+ resource_provider = "Microsoft.App"
+ }
+ }
+}
+
+data "azurerm_client_config" "this" {}
+
+resource "azapi_resource_action" "resource_provider_registration" {
+ for_each = local.resource_providers_to_register
+
+ resource_id = "/subscriptions/${data.azurerm_client_config.this.subscription_id}"
+ type = "Microsoft.Resources/subscriptions@2021-04-01"
+ action = "providers/${each.value.resource_provider}/register"
+ method = "POST"
+}
+
+locals {
+ subnets = {
+ container_registry_private_endpoint = {
+ name = "subnet-container-registry-private-endpoint"
+ address_prefix = "10.0.0.0/29"
+ }
+ container_app = {
+ name = "subnet-container-app"
+ address_prefix = "10.0.1.0/27"
+ delegation = [
+ {
+ name = "Microsoft.App/environments"
+ service_delegation = {
+ name = "Microsoft.App/environments"
+ }
+ }
+ ]
+ }
+ container_instance = {
+ name = "subnet-container-instance"
+ address_prefix = "10.0.2.0/28"
+ delegation = [
+ {
+ name = "Microsoft.ContainerInstance/containerGroups"
+ service_delegation = {
+ name = "Microsoft.ContainerInstance/containerGroups"
+ }
+ }
+ ]
+ }
+ }
+ virtual_network_address_space = "10.0.0.0/16"
+}
+
+resource "azurerm_resource_group" "this" {
+ location = local.selected_region
+ name = "rg-${random_string.name.result}"
+}
+
+module "virtual_network" {
+ source = "Azure/avm-res-network-virtualnetwork/azurerm"
+ version = "0.4.2"
+ name = "vnet-${random_string.name.result}"
+ resource_group_name = azurerm_resource_group.this.name
+ location = local.selected_region
+ address_space = [local.virtual_network_address_space]
+ subnets = local.subnets
+}
+
+# This is the module call
+module "azure_devops_agents" {
+ source = "../.."
+ postfix = random_string.name.result
+ location = local.selected_region
+ compute_types = ["azure_container_app", "azure_container_instance"]
+ version_control_system_type = "azuredevops"
+ version_control_system_personal_access_token = var.azure_devops_agents_personal_access_token
+ version_control_system_organization = local.azure_devops_organization_url
+ version_control_system_pool_name = azuredevops_agent_pool.this.name
+ virtual_network_id = module.virtual_network.resource_id
+ virtual_network_creation_enabled = false
+ resource_group_creation_enabled = false
+ resource_group_name = azurerm_resource_group.this.name
+ container_app_subnet_id = module.virtual_network.subnets["container_app"].resource_id
+ container_instance_subnet_id = module.virtual_network.subnets["container_instance"].resource_id
+ container_registry_private_endpoint_subnet_id = module.virtual_network.subnets["container_registry_private_endpoint"].resource_id
+ tags = local.tags
+ depends_on = [azuredevops_pipeline_authorization.this]
+}
+
+output "container_app_environment_resource_id" {
+ value = module.azure_devops_agents.resource_id
+}
+
+output "container_app_environment_name" {
+ value = module.azure_devops_agents.name
+}
+
+output "container_app_job_resource_id" {
+ value = module.azure_devops_agents.job_resource_id
+}
+
+output "container_app_job_name" {
+ value = module.azure_devops_agents.job_name
+}
+
+# Region helpers
+module "regions" {
+ source = "Azure/avm-utl-regions/azurerm"
+ version = "0.1.0"
+}
+
+resource "random_integer" "region_index" {
+ max = length(local.regions) - 1
+ min = 0
+}
+
+locals {
+ excluded_regions = [
+ "westeurope" # Capacity issues
+ ]
+ included_regions = [
+ "northcentralusstage", "westus2", "southeastasia", "canadacentral", "westeurope", "northeurope", "eastus", "eastus2", "eastasia", "australiaeast", "germanywestcentral", "japaneast", "uksouth", "westus", "centralus", "northcentralus", "southcentralus", "koreacentral", "brazilsouth", "westus3", "francecentral", "southafricanorth", "norwayeast", "switzerlandnorth", "uaenorth", "canadaeast", "westcentralus", "ukwest", "centralindia", "italynorth", "polandcentral", "southindia"
+ ]
+ regions = [for region in module.regions.regions : region.name if !contains(local.excluded_regions, region.name) && contains(local.included_regions, region.name)]
+ selected_region = local.regions[random_integer.region_index.result]
+}
+```
+
+
+## Requirements
+
+The following requirements are needed by this module:
+
+- [terraform](#requirement\_terraform) (>= 1.9)
+
+- [azapi](#requirement\_azapi) (~> 1.14)
+
+- [azuredevops](#requirement\_azuredevops) (~> 1.1)
+
+- [azurerm](#requirement\_azurerm) (~> 3.113)
+
+- [random](#requirement\_random) (~> 3.5)
+
+## Resources
+
+The following resources are used by this module:
+
+- [azapi_resource_action.resource_provider_registration](https://registry.terraform.io/providers/azure/azapi/latest/docs/resources/resource_action) (resource)
+- [azuredevops_agent_pool.this](https://registry.terraform.io/providers/microsoft/azuredevops/latest/docs/resources/agent_pool) (resource)
+- [azuredevops_agent_queue.this](https://registry.terraform.io/providers/microsoft/azuredevops/latest/docs/resources/agent_queue) (resource)
+- [azuredevops_build_definition.this](https://registry.terraform.io/providers/microsoft/azuredevops/latest/docs/resources/build_definition) (resource)
+- [azuredevops_git_repository.this](https://registry.terraform.io/providers/microsoft/azuredevops/latest/docs/resources/git_repository) (resource)
+- [azuredevops_git_repository_file.this](https://registry.terraform.io/providers/microsoft/azuredevops/latest/docs/resources/git_repository_file) (resource)
+- [azuredevops_pipeline_authorization.this](https://registry.terraform.io/providers/microsoft/azuredevops/latest/docs/resources/pipeline_authorization) (resource)
+- [azuredevops_project.this](https://registry.terraform.io/providers/microsoft/azuredevops/latest/docs/resources/project) (resource)
+- [azurerm_resource_group.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) (resource)
+- [random_integer.region_index](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/integer) (resource)
+- [random_string.name](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) (resource)
+- [azurerm_client_config.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config) (data source)
+
+
+## Required Inputs
+
+The following input variables are required:
+
+### [azure\_devops\_agents\_personal\_access\_token](#input\_azure\_devops\_agents\_personal\_access\_token)
+
+Description: Personal access token for Azure DevOps self-hosted agents (the token requires the 'Agent Pools - Read & Manage' scope and should have the maximum expiry).
+
+Type: `string`
+
+### [azure\_devops\_organization\_name](#input\_azure\_devops\_organization\_name)
+
+Description: Azure DevOps Organisation Name
+
+Type: `string`
+
+### [azure\_devops\_personal\_access\_token](#input\_azure\_devops\_personal\_access\_token)
+
+Description: The personal access token used for agent authentication to Azure DevOps.
+
+Type: `string`
+
+## Optional Inputs
+
+No optional inputs.
+
+## Outputs
+
+The following outputs are exported:
+
+### [container\_app\_environment\_name](#output\_container\_app\_environment\_name)
+
+Description: n/a
+
+### [container\_app\_environment\_resource\_id](#output\_container\_app\_environment\_resource\_id)
+
+Description: n/a
+
+### [container\_app\_job\_name](#output\_container\_app\_job\_name)
+
+Description: n/a
+
+### [container\_app\_job\_resource\_id](#output\_container\_app\_job\_resource\_id)
+
+Description: n/a
+
+## Modules
+
+The following Modules are called:
+
+### [azure\_devops\_agents](#module\_azure\_devops\_agents)
+
+Source: ../..
+
+Version:
+
+### [naming](#module\_naming)
+
+Source: Azure/naming/azurerm
+
+Version: >= 0.3.0
+
+### [regions](#module\_regions)
+
+Source: Azure/avm-utl-regions/azurerm
+
+Version: 0.1.0
+
+### [virtual\_network](#module\_virtual\_network)
+
+Source: Azure/avm-res-network-virtualnetwork/azurerm
+
+Version: 0.4.2
+
+
+## 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 . 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.
+
\ No newline at end of file
diff --git a/examples/bring_your_own_vnet/_footer.md b/examples/bring_your_own_vnet/_footer.md
new file mode 100644
index 0000000..bc56bcb
--- /dev/null
+++ b/examples/bring_your_own_vnet/_footer.md
@@ -0,0 +1,4 @@
+
+## 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 . 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.
diff --git a/examples/bring_your_own_vnet/_header.md b/examples/bring_your_own_vnet/_header.md
new file mode 100644
index 0000000..3b84b4b
--- /dev/null
+++ b/examples/bring_your_own_vnet/_header.md
@@ -0,0 +1,3 @@
+# Azure DevOps example with private networking and bring your own virtual network
+
+This example deploys Azure DevOps Agents to Azure Container Apps and Azure Container Instance using private networking and bring your own virtual network.
diff --git a/examples/bring_your_own_vnet/main.tf b/examples/bring_your_own_vnet/main.tf
new file mode 100644
index 0000000..b19d2d9
--- /dev/null
+++ b/examples/bring_your_own_vnet/main.tf
@@ -0,0 +1,260 @@
+variable "azure_devops_organization_name" {
+ type = string
+ description = "Azure DevOps Organisation Name"
+}
+
+variable "azure_devops_personal_access_token" {
+ type = string
+ description = "The personal access token used for agent authentication to Azure DevOps."
+ sensitive = true
+}
+
+variable "azure_devops_agents_personal_access_token" {
+ description = "Personal access token for Azure DevOps self-hosted agents (the token requires the 'Agent Pools - Read & Manage' scope and should have the maximum expiry)."
+ type = string
+ sensitive = true
+}
+
+locals {
+ tags = {
+ scenario = "default"
+ }
+}
+
+terraform {
+ required_version = ">= 1.9"
+ required_providers {
+ azapi = {
+ source = "azure/azapi"
+ version = "~> 1.14"
+ }
+ azuredevops = {
+ source = "microsoft/azuredevops"
+ version = "~> 1.1"
+ }
+ azurerm = {
+ source = "hashicorp/azurerm"
+ version = "~> 3.113"
+ }
+ random = {
+ source = "hashicorp/random"
+ version = "~> 3.5"
+ }
+ }
+}
+
+provider "azurerm" {
+ features {}
+}
+
+locals {
+ azure_devops_organization_url = "https://dev.azure.com/${var.azure_devops_organization_name}"
+}
+
+provider "azuredevops" {
+ personal_access_token = var.azure_devops_personal_access_token
+ org_service_url = local.azure_devops_organization_url
+}
+
+resource "random_string" "name" {
+ length = 6
+ numeric = true
+ special = false
+ upper = false
+}
+
+module "naming" {
+ source = "Azure/naming/azurerm"
+ version = ">= 0.3.0"
+}
+
+resource "azuredevops_project" "this" {
+ name = random_string.name.result
+}
+
+resource "azuredevops_agent_pool" "this" {
+ name = random_string.name.result
+ auto_provision = false
+ auto_update = true
+}
+
+resource "azuredevops_agent_queue" "this" {
+ project_id = azuredevops_project.this.id
+ agent_pool_id = azuredevops_agent_pool.this.id
+}
+
+locals {
+ default_branch = "refs/heads/main"
+ pipeline_file = "pipeline.yml"
+ repository_name = "example-repo"
+}
+
+resource "azuredevops_git_repository" "this" {
+ project_id = azuredevops_project.this.id
+ name = local.repository_name
+ default_branch = local.default_branch
+ initialization {
+ init_type = "Clean"
+ }
+}
+
+resource "azuredevops_git_repository_file" "this" {
+ repository_id = azuredevops_git_repository.this.id
+ file = local.pipeline_file
+ content = templatefile("${path.module}/${local.pipeline_file}", {
+ agent_pool_name = azuredevops_agent_pool.this.name
+ })
+ branch = local.default_branch
+ commit_message = "[skip ci]"
+ overwrite_on_create = true
+}
+
+resource "azuredevops_build_definition" "this" {
+ project_id = azuredevops_project.this.id
+ name = "Example Build Definition"
+
+ ci_trigger {
+ use_yaml = true
+ }
+
+ repository {
+ repo_type = "TfsGit"
+ repo_id = azuredevops_git_repository.this.id
+ branch_name = azuredevops_git_repository.this.default_branch
+ yml_path = local.pipeline_file
+ }
+}
+
+resource "azuredevops_pipeline_authorization" "this" {
+ project_id = azuredevops_project.this.id
+ resource_id = azuredevops_agent_queue.this.id
+ type = "queue"
+ pipeline_id = azuredevops_build_definition.this.id
+}
+
+locals {
+ resource_providers_to_register = {
+ dev_center = {
+ resource_provider = "Microsoft.App"
+ }
+ }
+}
+
+data "azurerm_client_config" "this" {}
+
+resource "azapi_resource_action" "resource_provider_registration" {
+ for_each = local.resource_providers_to_register
+
+ resource_id = "/subscriptions/${data.azurerm_client_config.this.subscription_id}"
+ type = "Microsoft.Resources/subscriptions@2021-04-01"
+ action = "providers/${each.value.resource_provider}/register"
+ method = "POST"
+}
+
+locals {
+ subnets = {
+ container_registry_private_endpoint = {
+ name = "subnet-container-registry-private-endpoint"
+ address_prefix = "10.0.0.0/29"
+ }
+ container_app = {
+ name = "subnet-container-app"
+ address_prefix = "10.0.1.0/27"
+ delegation = [
+ {
+ name = "Microsoft.App/environments"
+ service_delegation = {
+ name = "Microsoft.App/environments"
+ }
+ }
+ ]
+ }
+ container_instance = {
+ name = "subnet-container-instance"
+ address_prefix = "10.0.2.0/28"
+ delegation = [
+ {
+ name = "Microsoft.ContainerInstance/containerGroups"
+ service_delegation = {
+ name = "Microsoft.ContainerInstance/containerGroups"
+ }
+ }
+ ]
+ }
+ }
+ virtual_network_address_space = "10.0.0.0/16"
+}
+
+resource "azurerm_resource_group" "this" {
+ location = local.selected_region
+ name = "rg-${random_string.name.result}"
+}
+
+module "virtual_network" {
+ source = "Azure/avm-res-network-virtualnetwork/azurerm"
+ version = "0.4.2"
+ name = "vnet-${random_string.name.result}"
+ resource_group_name = azurerm_resource_group.this.name
+ location = local.selected_region
+ address_space = [local.virtual_network_address_space]
+ subnets = local.subnets
+}
+
+# This is the module call
+module "azure_devops_agents" {
+ source = "../.."
+ postfix = random_string.name.result
+ location = local.selected_region
+ compute_types = ["azure_container_app", "azure_container_instance"]
+ version_control_system_type = "azuredevops"
+ version_control_system_personal_access_token = var.azure_devops_agents_personal_access_token
+ version_control_system_organization = local.azure_devops_organization_url
+ version_control_system_pool_name = azuredevops_agent_pool.this.name
+ virtual_network_id = module.virtual_network.resource_id
+ virtual_network_creation_enabled = false
+ resource_group_creation_enabled = false
+ resource_group_name = azurerm_resource_group.this.name
+ container_app_subnet_id = module.virtual_network.subnets["container_app"].resource_id
+ container_instance_subnet_id = module.virtual_network.subnets["container_instance"].resource_id
+ container_registry_private_endpoint_subnet_id = module.virtual_network.subnets["container_registry_private_endpoint"].resource_id
+ tags = local.tags
+ depends_on = [azuredevops_pipeline_authorization.this]
+}
+
+output "container_app_environment_resource_id" {
+ value = module.azure_devops_agents.resource_id
+}
+
+output "container_app_environment_name" {
+ value = module.azure_devops_agents.name
+}
+
+output "container_app_job_resource_id" {
+ value = module.azure_devops_agents.job_resource_id
+}
+
+output "container_app_job_name" {
+ value = module.azure_devops_agents.job_name
+}
+
+# Region helpers
+module "regions" {
+ source = "Azure/avm-utl-regions/azurerm"
+ version = "0.1.0"
+}
+
+resource "random_integer" "region_index" {
+ max = length(local.regions) - 1
+ min = 0
+}
+
+locals {
+ excluded_regions = [
+ "westeurope" # Capacity issues
+ ]
+ included_regions = [
+ "northcentralusstage", "westus2", "southeastasia", "canadacentral", "westeurope", "northeurope", "eastus", "eastus2", "eastasia", "australiaeast", "germanywestcentral", "japaneast", "uksouth", "westus", "centralus", "northcentralus", "southcentralus", "koreacentral", "brazilsouth", "westus3", "francecentral", "southafricanorth", "norwayeast", "switzerlandnorth", "uaenorth", "canadaeast", "westcentralus", "ukwest", "centralindia", "italynorth", "polandcentral", "southindia"
+ ]
+ regions = [for region in module.regions.regions : region.name if !contains(local.excluded_regions, region.name) && contains(local.included_regions, region.name)]
+ selected_region = local.regions[random_integer.region_index.result]
+}
diff --git a/examples/bring_your_own_vnet/pipeline.yml b/examples/bring_your_own_vnet/pipeline.yml
new file mode 100644
index 0000000..78b11ff
--- /dev/null
+++ b/examples/bring_your_own_vnet/pipeline.yml
@@ -0,0 +1,8 @@
+trigger:
+- main
+
+pool: ${agent_pool_name}
+
+steps:
+- script: echo Hello, world!
+ displayName: 'Run a one-line script'
\ No newline at end of file
diff --git a/examples/default/README.md b/examples/default/README.md
index 8b72a7f..bf9d99f 100644
--- a/examples/default/README.md
+++ b/examples/default/README.md
@@ -30,6 +30,10 @@ locals {
terraform {
required_version = ">= 1.9"
required_providers {
+ azapi = {
+ source = "azure/azapi"
+ version = "~> 1.14"
+ }
azuredevops = {
source = "microsoft/azuredevops"
version = "~> 1.1"
@@ -134,6 +138,25 @@ resource "azuredevops_pipeline_authorization" "this" {
pipeline_id = azuredevops_build_definition.this.id
}
+locals {
+ resource_providers_to_register = {
+ dev_center = {
+ resource_provider = "Microsoft.App"
+ }
+ }
+}
+
+data "azurerm_client_config" "this" {}
+
+resource "azapi_resource_action" "resource_provider_registration" {
+ for_each = local.resource_providers_to_register
+
+ resource_id = "/subscriptions/${data.azurerm_client_config.this.subscription_id}"
+ type = "Microsoft.Resources/subscriptions@2021-04-01"
+ action = "providers/${each.value.resource_provider}/register"
+ method = "POST"
+}
+
# This is the module call
module "azure_devops_agents" {
source = "../.."
@@ -194,6 +217,8 @@ The following requirements are needed by this module:
- [terraform](#requirement\_terraform) (>= 1.9)
+- [azapi](#requirement\_azapi) (~> 1.14)
+
- [azuredevops](#requirement\_azuredevops) (~> 1.1)
- [azurerm](#requirement\_azurerm) (~> 3.113)
@@ -204,6 +229,7 @@ The following requirements are needed by this module:
The following resources are used by this module:
+- [azapi_resource_action.resource_provider_registration](https://registry.terraform.io/providers/azure/azapi/latest/docs/resources/resource_action) (resource)
- [azuredevops_agent_pool.this](https://registry.terraform.io/providers/microsoft/azuredevops/latest/docs/resources/agent_pool) (resource)
- [azuredevops_agent_queue.this](https://registry.terraform.io/providers/microsoft/azuredevops/latest/docs/resources/agent_queue) (resource)
- [azuredevops_build_definition.this](https://registry.terraform.io/providers/microsoft/azuredevops/latest/docs/resources/build_definition) (resource)
@@ -213,6 +239,7 @@ The following resources are used by this module:
- [azuredevops_project.this](https://registry.terraform.io/providers/microsoft/azuredevops/latest/docs/resources/project) (resource)
- [random_integer.region_index](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/integer) (resource)
- [random_string.name](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) (resource)
+- [azurerm_client_config.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config) (data source)
## Required Inputs
diff --git a/examples/default/main.tf b/examples/default/main.tf
index a7b4a3a..363088b 100644
--- a/examples/default/main.tf
+++ b/examples/default/main.tf
@@ -24,6 +24,10 @@ locals {
terraform {
required_version = ">= 1.9"
required_providers {
+ azapi = {
+ source = "azure/azapi"
+ version = "~> 1.14"
+ }
azuredevops = {
source = "microsoft/azuredevops"
version = "~> 1.1"
@@ -128,6 +132,25 @@ resource "azuredevops_pipeline_authorization" "this" {
pipeline_id = azuredevops_build_definition.this.id
}
+locals {
+ resource_providers_to_register = {
+ dev_center = {
+ resource_provider = "Microsoft.App"
+ }
+ }
+}
+
+data "azurerm_client_config" "this" {}
+
+resource "azapi_resource_action" "resource_provider_registration" {
+ for_each = local.resource_providers_to_register
+
+ resource_id = "/subscriptions/${data.azurerm_client_config.this.subscription_id}"
+ type = "Microsoft.Resources/subscriptions@2021-04-01"
+ action = "providers/${each.value.resource_provider}/register"
+ method = "POST"
+}
+
# This is the module call
module "azure_devops_agents" {
source = "../.."
diff --git a/examples/github_basic/README.md b/examples/github_basic/README.md
index 311fd78..3d6ad2d 100644
--- a/examples/github_basic/README.md
+++ b/examples/github_basic/README.md
@@ -30,6 +30,10 @@ locals {
terraform {
required_version = ">= 1.9"
required_providers {
+ azapi = {
+ source = "azure/azapi"
+ version = "~> 1.14"
+ }
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.113"
@@ -97,6 +101,25 @@ resource "github_repository_file" "this" {
overwrite_on_create = true
}
+locals {
+ resource_providers_to_register = {
+ dev_center = {
+ resource_provider = "Microsoft.App"
+ }
+ }
+}
+
+data "azurerm_client_config" "this" {}
+
+resource "azapi_resource_action" "resource_provider_registration" {
+ for_each = local.resource_providers_to_register
+
+ resource_id = "/subscriptions/${data.azurerm_client_config.this.subscription_id}"
+ type = "Microsoft.Resources/subscriptions@2021-04-01"
+ action = "providers/${each.value.resource_provider}/register"
+ method = "POST"
+}
+
# This is the module call
module "github_runners" {
source = "../.."
@@ -141,6 +164,8 @@ The following requirements are needed by this module:
- [terraform](#requirement\_terraform) (>= 1.9)
+- [azapi](#requirement\_azapi) (~> 1.14)
+
- [azurerm](#requirement\_azurerm) (~> 3.113)
- [github](#requirement\_github) (~> 5.36)
@@ -151,10 +176,12 @@ The following requirements are needed by this module:
The following resources are used by this module:
+- [azapi_resource_action.resource_provider_registration](https://registry.terraform.io/providers/azure/azapi/latest/docs/resources/resource_action) (resource)
- [github_repository.this](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository) (resource)
- [github_repository_file.this](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository_file) (resource)
- [random_integer.region_index](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/integer) (resource)
- [random_string.name](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) (resource)
+- [azurerm_client_config.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config) (data source)
- [github_organization.alz](https://registry.terraform.io/providers/integrations/github/latest/docs/data-sources/organization) (data source)
diff --git a/examples/github_basic/main.tf b/examples/github_basic/main.tf
index 8082363..0070653 100644
--- a/examples/github_basic/main.tf
+++ b/examples/github_basic/main.tf
@@ -24,6 +24,10 @@ locals {
terraform {
required_version = ">= 1.9"
required_providers {
+ azapi = {
+ source = "azure/azapi"
+ version = "~> 1.14"
+ }
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.113"
@@ -91,6 +95,25 @@ resource "github_repository_file" "this" {
overwrite_on_create = true
}
+locals {
+ resource_providers_to_register = {
+ dev_center = {
+ resource_provider = "Microsoft.App"
+ }
+ }
+}
+
+data "azurerm_client_config" "this" {}
+
+resource "azapi_resource_action" "resource_provider_registration" {
+ for_each = local.resource_providers_to_register
+
+ resource_id = "/subscriptions/${data.azurerm_client_config.this.subscription_id}"
+ type = "Microsoft.Resources/subscriptions@2021-04-01"
+ action = "providers/${each.value.resource_provider}/register"
+ method = "POST"
+}
+
# This is the module call
module "github_runners" {
source = "../.."
diff --git a/examples/github_public_networking/README.md b/examples/github_public_networking/README.md
index 7b573bd..869d625 100644
--- a/examples/github_public_networking/README.md
+++ b/examples/github_public_networking/README.md
@@ -30,6 +30,10 @@ locals {
terraform {
required_version = ">= 1.9"
required_providers {
+ azapi = {
+ source = "azure/azapi"
+ version = "~> 1.14"
+ }
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.113"
@@ -97,6 +101,25 @@ resource "github_repository_file" "this" {
overwrite_on_create = true
}
+locals {
+ resource_providers_to_register = {
+ dev_center = {
+ resource_provider = "Microsoft.App"
+ }
+ }
+}
+
+data "azurerm_client_config" "this" {}
+
+resource "azapi_resource_action" "resource_provider_registration" {
+ for_each = local.resource_providers_to_register
+
+ resource_id = "/subscriptions/${data.azurerm_client_config.this.subscription_id}"
+ type = "Microsoft.Resources/subscriptions@2021-04-01"
+ action = "providers/${each.value.resource_provider}/register"
+ method = "POST"
+}
+
# This is the module call
module "github_runners" {
source = "../.."
@@ -141,6 +164,8 @@ The following requirements are needed by this module:
- [terraform](#requirement\_terraform) (>= 1.9)
+- [azapi](#requirement\_azapi) (~> 1.14)
+
- [azurerm](#requirement\_azurerm) (~> 3.113)
- [github](#requirement\_github) (~> 5.36)
@@ -151,10 +176,12 @@ The following requirements are needed by this module:
The following resources are used by this module:
+- [azapi_resource_action.resource_provider_registration](https://registry.terraform.io/providers/azure/azapi/latest/docs/resources/resource_action) (resource)
- [github_repository.this](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository) (resource)
- [github_repository_file.this](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository_file) (resource)
- [random_integer.region_index](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/integer) (resource)
- [random_string.name](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) (resource)
+- [azurerm_client_config.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config) (data source)
- [github_organization.alz](https://registry.terraform.io/providers/integrations/github/latest/docs/data-sources/organization) (data source)
diff --git a/examples/github_public_networking/main.tf b/examples/github_public_networking/main.tf
index 5c96894..48be998 100644
--- a/examples/github_public_networking/main.tf
+++ b/examples/github_public_networking/main.tf
@@ -24,6 +24,10 @@ locals {
terraform {
required_version = ">= 1.9"
required_providers {
+ azapi = {
+ source = "azure/azapi"
+ version = "~> 1.14"
+ }
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.113"
@@ -91,6 +95,25 @@ resource "github_repository_file" "this" {
overwrite_on_create = true
}
+locals {
+ resource_providers_to_register = {
+ dev_center = {
+ resource_provider = "Microsoft.App"
+ }
+ }
+}
+
+data "azurerm_client_config" "this" {}
+
+resource "azapi_resource_action" "resource_provider_registration" {
+ for_each = local.resource_providers_to_register
+
+ resource_id = "/subscriptions/${data.azurerm_client_config.this.subscription_id}"
+ type = "Microsoft.Resources/subscriptions@2021-04-01"
+ action = "providers/${each.value.resource_provider}/register"
+ method = "POST"
+}
+
# This is the module call
module "github_runners" {
source = "../.."
diff --git a/examples/multi_region/README.md b/examples/multi_region/README.md
index 926e0fe..392bba4 100644
--- a/examples/multi_region/README.md
+++ b/examples/multi_region/README.md
@@ -32,6 +32,10 @@ locals {
terraform {
required_version = ">= 1.9"
required_providers {
+ azapi = {
+ source = "azure/azapi"
+ version = "~> 1.14"
+ }
azuredevops = {
source = "microsoft/azuredevops"
version = "~> 1.1"
@@ -141,6 +145,25 @@ locals {
secondary_polling_interval_prime_number = 31
}
+locals {
+ resource_providers_to_register = {
+ dev_center = {
+ resource_provider = "Microsoft.App"
+ }
+ }
+}
+
+data "azurerm_client_config" "this" {}
+
+resource "azapi_resource_action" "resource_provider_registration" {
+ for_each = local.resource_providers_to_register
+
+ resource_id = "/subscriptions/${data.azurerm_client_config.this.subscription_id}"
+ type = "Microsoft.Resources/subscriptions@2021-04-01"
+ action = "providers/${each.value.resource_provider}/register"
+ method = "POST"
+}
+
# This is the module call
module "azure_devops_agents_primary" {
source = "../.."
@@ -247,6 +270,8 @@ The following requirements are needed by this module:
- [terraform](#requirement\_terraform) (>= 1.9)
+- [azapi](#requirement\_azapi) (~> 1.14)
+
- [azuredevops](#requirement\_azuredevops) (~> 1.1)
- [azurerm](#requirement\_azurerm) (~> 3.113)
@@ -257,6 +282,7 @@ The following requirements are needed by this module:
The following resources are used by this module:
+- [azapi_resource_action.resource_provider_registration](https://registry.terraform.io/providers/azure/azapi/latest/docs/resources/resource_action) (resource)
- [azuredevops_agent_pool.this](https://registry.terraform.io/providers/microsoft/azuredevops/latest/docs/resources/agent_pool) (resource)
- [azuredevops_agent_queue.this](https://registry.terraform.io/providers/microsoft/azuredevops/latest/docs/resources/agent_queue) (resource)
- [azuredevops_build_definition.this](https://registry.terraform.io/providers/microsoft/azuredevops/latest/docs/resources/build_definition) (resource)
@@ -267,6 +293,7 @@ The following resources are used by this module:
- [random_integer.region_index_primary](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/integer) (resource)
- [random_integer.region_index_secondary](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/integer) (resource)
- [random_string.name](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) (resource)
+- [azurerm_client_config.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config) (data source)
## Required Inputs
diff --git a/examples/multi_region/main.tf b/examples/multi_region/main.tf
index bfafb8f..f1839db 100644
--- a/examples/multi_region/main.tf
+++ b/examples/multi_region/main.tf
@@ -24,6 +24,10 @@ locals {
terraform {
required_version = ">= 1.9"
required_providers {
+ azapi = {
+ source = "azure/azapi"
+ version = "~> 1.14"
+ }
azuredevops = {
source = "microsoft/azuredevops"
version = "~> 1.1"
@@ -133,6 +137,25 @@ locals {
secondary_polling_interval_prime_number = 31
}
+locals {
+ resource_providers_to_register = {
+ dev_center = {
+ resource_provider = "Microsoft.App"
+ }
+ }
+}
+
+data "azurerm_client_config" "this" {}
+
+resource "azapi_resource_action" "resource_provider_registration" {
+ for_each = local.resource_providers_to_register
+
+ resource_id = "/subscriptions/${data.azurerm_client_config.this.subscription_id}"
+ type = "Microsoft.Resources/subscriptions@2021-04-01"
+ action = "providers/${each.value.resource_provider}/register"
+ method = "POST"
+}
+
# This is the module call
module "azure_devops_agents_primary" {
source = "../.."
diff --git a/local.virtual.network.tf b/local.virtual.network.tf
index 06266ce..cfb4526 100644
--- a/local.virtual.network.tf
+++ b/local.virtual.network.tf
@@ -1,13 +1,13 @@
locals {
- container_app_subnet_address_prefix = var.use_private_networking ? (var.container_app_subnet_address_prefix == null ? element(local.subnet_address_prefixes, 0) : var.container_app_subnet_address_prefix) : ""
- container_instance_subnet_address_prefix = var.use_private_networking ? (var.container_instance_subnet_address_prefix == null ? element(local.subnet_address_prefixes, length(local.default_subnet_newbits) - 2) : var.container_instance_subnet_address_prefix) : ""
- container_registry_private_endpoint_subnet_address_prefix = var.use_private_networking ? (var.container_registry_private_endpoint_subnet_address_prefix == null ? element(local.subnet_address_prefixes, length(local.default_subnet_newbits) - 1) : var.container_registry_private_endpoint_subnet_address_prefix) : ""
+ container_app_subnet_address_prefix = var.use_private_networking && var.virtual_network_creation_enabled ? (var.container_app_subnet_address_prefix == null ? element(local.subnet_address_prefixes, 0) : var.container_app_subnet_address_prefix) : ""
+ container_instance_subnet_address_prefix = var.use_private_networking && var.virtual_network_creation_enabled ? (var.container_instance_subnet_address_prefix == null ? element(local.subnet_address_prefixes, length(local.default_subnet_newbits) - 2) : var.container_instance_subnet_address_prefix) : ""
+ container_registry_private_endpoint_subnet_address_prefix = var.use_private_networking && var.virtual_network_creation_enabled ? (var.container_registry_private_endpoint_subnet_address_prefix == null ? element(local.subnet_address_prefixes, length(local.default_subnet_newbits) - 1) : var.container_registry_private_endpoint_subnet_address_prefix) : ""
default_subnet_newbits = concat(
local.deploy_container_app ? [var.container_app_subnet_cidr_size - local.virtual_network_address_space_cidr_size] : [],
local.deploy_container_instance ? [var.container_instance_subnet_cidr_size - local.virtual_network_address_space_cidr_size] : [],
[var.container_registry_subnet_cidr_size - local.virtual_network_address_space_cidr_size]
)
- subnet_address_prefixes = var.use_private_networking ? cidrsubnets(var.virtual_network_address_space, local.default_subnet_newbits...) : []
+ subnet_address_prefixes = var.use_private_networking && var.virtual_network_creation_enabled ? cidrsubnets(var.virtual_network_address_space, local.default_subnet_newbits...) : []
virtual_network_address_space_cidr_size = var.use_private_networking ? (var.virtual_network_creation_enabled ? tonumber(split("/", var.virtual_network_address_space)[1]) : 24) : 0
}
diff --git a/locals.tf b/locals.tf
index b79a7fd..d744983 100644
--- a/locals.tf
+++ b/locals.tf
@@ -12,6 +12,7 @@ locals {
resource_group_name = var.resource_group_creation_enabled ? azurerm_resource_group.this[0].name : var.resource_group_name
resource_group_name_container_app_infrastructure = var.container_app_infrastructure_resource_group_name == null ? "rg-${var.postfix}-container-apps-infrastructure" : var.container_app_infrastructure_resource_group_name
user_assigned_managed_identity_principal_id = var.user_assigned_managed_identity_creation_enabled ? module.user_assigned_managed_identity[0].principal_id : var.user_assigned_managed_identity_principal_id
+ virtual_network_id = var.use_private_networking ? (var.virtual_network_creation_enabled ? module.virtual_network[0].resource_id : var.virtual_network_id) : ""
}
locals {
diff --git a/main.virtual.network.tf b/main.virtual.network.tf
index 408117c..6d8d478 100644
--- a/main.virtual.network.tf
+++ b/main.virtual.network.tf
@@ -28,7 +28,7 @@ resource "azurerm_private_dns_zone_virtual_network_link" "container_registry" {
name = "privatelink.azurecr.io"
private_dns_zone_name = azurerm_private_dns_zone.container_registry[0].name
resource_group_name = local.resource_group_name
- virtual_network_id = module.virtual_network[0].resource_id
+ virtual_network_id = local.virtual_network_id
tags = var.tags
}
diff --git a/variables.virtual.network.tf b/variables.virtual.network.tf
index 71a7e60..9aae81f 100644
--- a/variables.virtual.network.tf
+++ b/variables.virtual.network.tf
@@ -7,19 +7,25 @@ variable "virtual_network_creation_enabled" {
variable "virtual_network_name" {
type = string
default = null
- description = "The name of the virtual network. Must be specified if `virtual_network_creation_enabled == false`."
+ description = "The name of the virtual network. Must be specified if `virtual_network_creation_enabled` is `true`."
+}
+
+variable "virtual_network_id" {
+ type = string
+ default = null
+ description = "The ID of the virtual network. Only required if `virtual_network_creation_enabled` is `false`."
}
variable "virtual_network_address_space" {
type = string
default = null
- description = "The address space for the virtual network. Must be specified if `virtual_network_creation_enabled == false`."
+ description = "The address space for the virtual network. Must be specified if `virtual_network_creation_enabled` is `true`."
}
variable "container_app_subnet_name" {
type = string
default = null
- description = "The name of the subnet. Must be specified if `virtual_network_creation_enabled == false`."
+ description = "The name of the subnet. Must be specified if `virtual_network_creation_enabled` is `true`."
}
variable "container_app_subnet_cidr_size" {