├── .github └── workflows │ ├── terraform-docs.yaml │ └── terraform-test.yaml ├── .gitignore ├── LICENSE ├── README.md ├── examples ├── azure-dual-backend │ ├── README.md │ ├── main.tf │ ├── variables.tf │ └── versions.tf ├── azure-fn-app-stand-alone │ ├── README.md │ ├── main.tf │ ├── variables.tf │ └── versions.tf ├── azure-fn-app │ ├── README.md │ ├── main.tf │ ├── variables.tf │ └── versions.tf ├── azure-fn-core │ ├── README.md │ ├── main.tf │ ├── variables.tf │ └── versions.tf ├── azure-jekyll-site │ ├── README.md │ ├── main.tf │ ├── variables.tf │ └── versions.tf ├── azure-starter-app-stand-alone │ ├── README.md │ ├── main.tf │ ├── variables.tf │ └── versions.tf ├── azure-starter-app │ ├── README.md │ ├── main.tf │ ├── variables.tf │ └── versions.tf ├── azure-vm-app │ ├── README.md │ ├── main.tf │ ├── variables.tf │ └── versions.tf └── azure-vm-core │ ├── README.md │ ├── main.tf │ ├── variables.tf │ └── versions.tf ├── main.tf ├── modules ├── azure-dual-backend │ ├── README.md │ ├── main.tf │ ├── outputs.tf │ ├── variables.tf │ └── versions.tf ├── azure-fn-app │ ├── README.md │ ├── codebase.tf │ ├── environments.tf │ ├── identity.tf │ ├── main.tf │ ├── pipelines.tf │ ├── variables.tf │ └── versions.tf ├── azure-fn-core │ ├── README.md │ ├── codebase.tf │ ├── environments.tf │ ├── identity.tf │ ├── main.tf │ ├── pipelines.tf │ ├── variables.tf │ └── versions.tf ├── azure-jekyll-site │ ├── README.md │ ├── codebase.tf │ ├── environments.tf │ ├── identity.tf │ ├── main.tf │ ├── outputs.tf │ ├── pipelines.tf │ ├── variables.tf │ └── versions.tf ├── azure-starter-app │ ├── README.md │ ├── codebase.tf │ ├── environments.tf │ ├── identity.tf │ ├── main.tf │ ├── outputs.tf │ ├── pipelines.tf │ ├── variables.tf │ └── versions.tf ├── azure-vm-app │ ├── README.md │ ├── codebase.tf │ ├── environments.tf │ ├── identity.tf │ ├── main.tf │ ├── pipelines.tf │ ├── variables.tf │ └── versions.tf └── azure-vm-core │ ├── README.md │ ├── codebase.tf │ ├── environments.tf │ ├── identity.tf │ ├── main.tf │ ├── pipelines.tf │ ├── variables.tf │ └── versions.tf └── tests ├── azure-fn-app-stand-alone.tftest.hcl ├── azure-starter-app-stand-alone.tftest.hcl └── setup ├── README.md ├── main.tf └── terraform.tf /.github/workflows/terraform-docs.yaml: -------------------------------------------------------------------------------- 1 | name: Terraform Docs 2 | 3 | on: 4 | pull_request: 5 | 6 | jobs: 7 | docs: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v3 11 | with: 12 | token: ${{ secrets.TERRAFORM_DOCS_PAT_TOKEN }} 13 | ref: ${{ github.event.pull_request.head.ref }} 14 | - name: Generate TF docs 15 | uses: terraform-docs/gh-actions@v1.0.0 16 | with: 17 | find-dir: / 18 | git-push: true -------------------------------------------------------------------------------- /.github/workflows/terraform-test.yaml: -------------------------------------------------------------------------------- 1 | name: Terraform-Test 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | 8 | terraform-test: 9 | runs-on: ubuntu-latest 10 | 11 | environment: 12 | name: ${{ inputs.environment }} 13 | 14 | steps: 15 | - uses: actions/checkout@v3 16 | 17 | - id: setup 18 | name: Setup `terraform` 19 | uses: hashicorp/setup-terraform@v3 20 | with: 21 | terraform_version: ${{ inputs.terraform_version }} 22 | 23 | - id: terraform-test 24 | name: Terraform Test 25 | env: 26 | ARM_SUBSCRIPTION_ID: ${{ vars.DEV_SUBSCRIPTION_ID }} 27 | ARM_TENANT_ID: ${{ vars.ARM_TENANT_ID }} 28 | ARM_CLIENT_ID: ${{ vars.TERRAFORM_ARM_CLIENT_ID }} 29 | ARM_CLIENT_SECRET: ${{ secrets.TERRAFORM_ARM_CLIENT_SECRET }} 30 | working-directory: ${{ inputs.working_directory }} 31 | run: | 32 | terraform init 33 | terraform test -verbose -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/*.tfstate* 2 | **/.terraform* 3 | **/.terraform/* 4 | **/.debug*.sh 5 | **/.debug.tfvars 6 | **/.debug*.tfvars 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introduction to GitHub - Automate the Automation with Terraform (GH-ATAT) 2 | 3 | Welcome to the GitHub Automate the Automation with Terraform (AT-AT) Module, or the GitHub AT-AT for short. This is a multi-module repository meaning that it contains multiple reusable modules that you can use together or independently with your own code. 4 | 5 | ## Key Features: 6 | 7 | 1. **Application-Environment Repository**: This module provisions a GitHub Repository that is completely setup to provision an environment for an application. The repository will contain a template Azure Terraform root module in the `/src/terraform` folder that provisions a Resource Group. All you have to do is start adding things to it! 8 | 9 | 2. **Multi-Environment Support**: This module allows you to setup one or more environments for your application (e.g., dev, test, or prod). 10 | 11 | 3. **Terraform GitHub Actions Workflows**: This module features Terraform plan, apply and destroy GitHub Actions workflows that you can manually execute--or customize to your desired GitFlow process. 12 | 13 | 4. **Backend Isolation**: This module allows you to (optionally) provision an isolated backend for each environment with its own Azure Storage account. 14 | 15 | 5. **Multi-Subscription Support**: This module allows you to segment your environments across different Azure Subscriptions so that you can organize your environments to the appropriate Azure Subscription structure of your organization. 16 | 17 | ## Prerequisites: 18 | 19 | - **GitHub Personal Access Token**: Essential for GitHub account interactions. 20 | - **Azure Access**: You need to be able to provision Resource Groups and Storage Accounts. 21 | - **Entra Access**: You need to be able to create Applications, Service Principals and Federated Identity Credentials. 22 | 23 | Make sure you can delete repos when doing destroy: 24 | 25 | ``` 26 | gh auth refresh -h github.com -s delete_repo 27 | ``` 28 | 29 | ## Release Notes 30 | 31 | ### v1.0.20 32 | 33 | - Added EventGrid Topic to `azure-fn-core` to support shared event-based communication. 34 | 35 | ### v1.0.19 36 | 37 | - Added EventGrid Topic to `azure-fn-app` to support internal event-based communication within each Azure Function hosted Microservice. 38 | 39 | 40 | ## Requirements 41 | 42 | No requirements. 43 | 44 | ## Providers 45 | 46 | No providers. 47 | 48 | ## Modules 49 | 50 | No modules. 51 | 52 | ## Resources 53 | 54 | No resources. 55 | 56 | ## Inputs 57 | 58 | No inputs. 59 | 60 | ## Outputs 61 | 62 | No outputs. 63 | -------------------------------------------------------------------------------- /examples/azure-dual-backend/README.md: -------------------------------------------------------------------------------- 1 | The Dual-Backend Example Module is a Terraform module designed to provision dual Terraform state backends for your infrastructure state management. Serving as a foundational example, this module sets up two separate state backends to ensure clean separation of environments between Production and Non-Production. 2 | 3 | It is specifically intended to be integrated with other GitHub AT-AT modules that utilize dual Terraform state backends. By implementing this dual-backend configuration, the module supports efficient disaster recovery, improves operational continuity, and ensures consistent state synchronization, making it an essential component for scalable and secure infrastructure deployments within the GitHub AT-AT ecosystem. 4 | 5 | 6 | ## Requirements 7 | 8 | | Name | Version | 9 | |------|---------| 10 | | [azuread](#requirement\_azuread) | ~> 3.0.2 | 11 | | [azurerm](#requirement\_azurerm) | ~> 4.10.0 | 12 | | [github](#requirement\_github) | ~> 5.0 | 13 | 14 | ## Providers 15 | 16 | No providers. 17 | 18 | ## Modules 19 | 20 | | Name | Source | Version | 21 | |------|--------|---------| 22 | | [backend](#module\_backend) | ../../modules/azure-dual-backend | n/a | 23 | 24 | ## Resources 25 | 26 | No resources. 27 | 28 | ## Inputs 29 | 30 | | Name | Description | Type | Default | Required | 31 | |------|-------------|------|---------|:--------:| 32 | | [azure\_nonprod\_subscription](#input\_azure\_nonprod\_subscription) | The Azure Subscription ID where the Non-PROD Terraform State Backend will be provisioned. | `string` | n/a | yes | 33 | | [azure\_prod\_subscription](#input\_azure\_prod\_subscription) | The Azure Subscription ID where the PROD Terraform State Backend will be provisioned. | `string` | n/a | yes | 34 | | [location](#input\_location) | The Azure region where the Terraform State Backends will be provisioned. | `string` | n/a | yes | 35 | | [name](#input\_name) | The name of the environment containing dual Terraform State Backends that you'd like to create. | `string` | n/a | yes | 36 | 37 | ## Outputs 38 | 39 | No outputs. 40 | -------------------------------------------------------------------------------- /examples/azure-dual-backend/main.tf: -------------------------------------------------------------------------------- 1 | module "backend" { 2 | 3 | source = "../../modules/azure-dual-backend" 4 | 5 | providers = { 6 | azurerm.nonprod = azurerm.nonprod 7 | azurerm.prod = azurerm.prod 8 | } 9 | 10 | name = var.name 11 | location = var.location 12 | 13 | } 14 | -------------------------------------------------------------------------------- /examples/azure-dual-backend/variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" { 2 | type = string 3 | description = < 2 | ## Requirements 3 | 4 | | Name | Version | 5 | |------|---------| 6 | | [azuread](#requirement\_azuread) | ~> 3.0.2 | 7 | | [azurerm](#requirement\_azurerm) | ~> 4.10.0 | 8 | | [github](#requirement\_github) | ~> 5.0 | 9 | 10 | ## Providers 11 | 12 | | Name | Version | 13 | |------|---------| 14 | | [random](#provider\_random) | n/a | 15 | 16 | ## Modules 17 | 18 | | Name | Source | Version | 19 | |------|--------|---------| 20 | | [app](#module\_app) | ../../modules/azure-fn-app | n/a | 21 | | [backend](#module\_backend) | ../../modules/azure-dual-backend | n/a | 22 | | [core](#module\_core) | ../../modules/azure-fn-core | n/a | 23 | 24 | ## Resources 25 | 26 | | Name | Type | 27 | |------|------| 28 | | [random_string.backend_suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource | 29 | 30 | ## Inputs 31 | 32 | | Name | Description | Type | Default | Required | 33 | |------|-------------|------|---------|:--------:| 34 | | [application\_name](#input\_application\_name) | The name of the application to be deployed. This name is used for resource identification and naming conventions within the infrastructure.

It's best to keep this short and simple while also ensuring it is easily identifiable and relatively unique within your organization (or at least within the Subscriptions you are targetting). | `string` | n/a | yes | 35 | | [azure\_nonprod\_subscription](#input\_azure\_nonprod\_subscription) | The Azure Subscription ID for the non-production environment where non-production resources will be provisioned. | `string` | n/a | yes | 36 | | [azure\_prod\_subscription](#input\_azure\_prod\_subscription) | The Azure Subscription ID for the production environment where production resources will be provisioned. | `string` | n/a | yes | 37 | | [github\_email](#input\_github\_email) | The email address associated with the GitHub account used for committing changes. This is used to attribute commits to the correct user." | `string` | n/a | yes | 38 | | [github\_organization](#input\_github\_organization) | The GitHub organization under which the repository will be created. This should be the exact name of the GitHub organization. | `string` | n/a | yes | 39 | | [github\_username](#input\_github\_username) | The GitHub username that will be used for committing changes to the repository. Ensure this account has the necessary permissions within the GitHub organization." | `string` | n/a | yes | 40 | | [location](#input\_location) | The Azure region where the Terraform State Backends will be provisioned. | `string` | n/a | yes | 41 | | [repository\_description](#input\_repository\_description) | A brief description of the GitHub repository. This helps in understanding the purpose and scope of the repository.

This should describe the workload represented by the `application_name`. | `string` | n/a | yes | 42 | | [repository\_name](#input\_repository\_name) | The name of the GitHub repository to be created. This name should be unique within the specified GitHub organization.

The GitHub repository name should correlate to the `application_name` as it will contain the source code for the infrastructure
that is provisioned to Azure. | `string` | n/a | yes | 43 | | [repository\_visibility](#input\_repository\_visibility) | The visibility level of the GitHub repository. Accepted values are 'public', 'private', or 'internal'. Determines who can view and access the repository. | `string` | n/a | yes | 44 | | [terraform\_version](#input\_terraform\_version) | Specifies the version of Terraform to use for the deployment. | `string` | n/a | yes | 45 | 46 | ## Outputs 47 | 48 | No outputs. 49 | -------------------------------------------------------------------------------- /examples/azure-fn-app-stand-alone/main.tf: -------------------------------------------------------------------------------- 1 | resource "random_string" "backend_suffix" { 2 | length = 8 3 | upper = false 4 | special = false 5 | } 6 | 7 | module "backend" { 8 | 9 | source = "../../modules/azure-dual-backend" 10 | 11 | providers = { 12 | azurerm.nonprod = azurerm.nonprod 13 | azurerm.prod = azurerm.prod 14 | } 15 | 16 | name = "tf${random_string.backend_suffix.result}" 17 | location = var.location 18 | 19 | } 20 | 21 | module "core" { 22 | 23 | source = "../../modules/azure-fn-core" 24 | 25 | application_name = var.application_name 26 | github_organization = var.github_organization 27 | repository_name = var.repository_name 28 | repository_description = var.repository_description 29 | repository_visibility = var.repository_visibility 30 | terraform_version = var.terraform_version 31 | primary_location = "westus3" 32 | sku_name = "Y1" 33 | os_type = "Windows" 34 | retention_in_days = 30 35 | 36 | commit_user = { 37 | name = var.github_username 38 | email = var.github_email 39 | } 40 | 41 | environments = { 42 | dev = { 43 | subscription_id = var.azure_nonprod_subscription 44 | branch_name = "develop" 45 | backend = module.backend.nonprod 46 | } 47 | test = { 48 | subscription_id = var.azure_nonprod_subscription 49 | branch_name = "release" 50 | backend = module.backend.nonprod 51 | } 52 | prod = { 53 | subscription_id = var.azure_prod_subscription 54 | branch_name = "main" 55 | backend = module.backend.prod 56 | } 57 | } 58 | 59 | } 60 | 61 | module "app" { 62 | 63 | source = "../../modules/azure-fn-app" 64 | 65 | application_name = "${var.application_name}-fn" 66 | github_organization = var.github_organization 67 | repository_name = var.repository_name 68 | repository_description = var.repository_description 69 | repository_visibility = var.repository_visibility 70 | terraform_version = var.terraform_version 71 | primary_location = "eastus2" 72 | os_type = "Windows" 73 | core_name = var.application_name 74 | root_namespace = "ATAT.Core" 75 | 76 | commit_user = { 77 | name = var.github_username 78 | email = var.github_email 79 | } 80 | 81 | environments = { 82 | dev = { 83 | subscription_id = var.azure_nonprod_subscription 84 | branch_name = "develop" 85 | reviewing_teams = [] 86 | reviewing_users = [] 87 | backend = module.backend.nonprod 88 | } 89 | test = { 90 | subscription_id = var.azure_nonprod_subscription 91 | branch_name = "release" 92 | reviewing_teams = [] 93 | reviewing_users = [] 94 | backend = module.backend.nonprod 95 | } 96 | prod = { 97 | subscription_id = var.azure_prod_subscription 98 | branch_name = "main" 99 | reviewing_teams = [] 100 | reviewing_users = [] 101 | backend = module.backend.prod 102 | } 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /examples/azure-fn-app-stand-alone/variables.tf: -------------------------------------------------------------------------------- 1 | variable "application_name" { 2 | type = string 3 | description = < 6 | ## Requirements 7 | 8 | | Name | Version | 9 | |------|---------| 10 | | [azuread](#requirement\_azuread) | ~> 3.0.2 | 11 | | [azurerm](#requirement\_azurerm) | ~> 4.10.0 | 12 | | [github](#requirement\_github) | ~> 5.0 | 13 | 14 | ## Providers 15 | 16 | No providers. 17 | 18 | ## Modules 19 | 20 | | Name | Source | Version | 21 | |------|--------|---------| 22 | | [app](#module\_app) | ../../modules/azure-fn-app | n/a | 23 | 24 | ## Resources 25 | 26 | No resources. 27 | 28 | ## Inputs 29 | 30 | | Name | Description | Type | Default | Required | 31 | |------|-------------|------|---------|:--------:| 32 | | [application\_name](#input\_application\_name) | The name of the application to be deployed. This name is used for resource identification and naming conventions within the infrastructure.

It's best to keep this short and simple while also ensuring it is easily identifiable and relatively unique within your organization (or at least within the Subscriptions you are targetting). | `string` | n/a | yes | 33 | | [azure\_nonprod\_subscription](#input\_azure\_nonprod\_subscription) | The Azure Subscription ID for the non-production environment where non-production resources will be provisioned. | `string` | n/a | yes | 34 | | [azure\_prod\_subscription](#input\_azure\_prod\_subscription) | The Azure Subscription ID for the production environment where production resources will be provisioned. | `string` | n/a | yes | 35 | | [core\_name](#input\_core\_name) | The name used for the Azure Functions Core environment we want to deploy into. | `string` | n/a | yes | 36 | | [github\_email](#input\_github\_email) | The email address associated with the GitHub account used for committing changes. This is used to attribute commits to the correct user." | `string` | n/a | yes | 37 | | [github\_organization](#input\_github\_organization) | The GitHub organization under which the repository will be created. This should be the exact name of the GitHub organization. | `string` | n/a | yes | 38 | | [github\_username](#input\_github\_username) | The GitHub username that will be used for committing changes to the repository. Ensure this account has the necessary permissions within the GitHub organization." | `string` | n/a | yes | 39 | | [nonprod\_backend](#input\_nonprod\_backend) | Configuration for the backend storage used in the non-production environment. Includes resource group, storage account, and container names for Terraform state and plans. |
object({
resource_group_name = string
storage_account_name = string
state_container_name = string
plan_container_name = string
})
| n/a | yes | 40 | | [prod\_backend](#input\_prod\_backend) | Configuration for the backend storage used in the production environment. Includes resource group, storage account, and container names for Terraform state and plans. |
object({
resource_group_name = string
storage_account_name = string
state_container_name = string
plan_container_name = string
})
| n/a | yes | 41 | | [repository\_description](#input\_repository\_description) | A brief description of the GitHub repository. This helps in understanding the purpose and scope of the repository.

This should describe the workload represented by the `application_name`. | `string` | n/a | yes | 42 | | [repository\_name](#input\_repository\_name) | The name of the GitHub repository to be created. This name should be unique within the specified GitHub organization.

The GitHub repository name should correlate to the `application_name` as it will contain the source code for the infrastructure
that is provisioned to Azure. | `string` | n/a | yes | 43 | | [repository\_visibility](#input\_repository\_visibility) | The visibility level of the GitHub repository. Accepted values are 'public', 'private', or 'internal'. Determines who can view and access the repository. | `string` | n/a | yes | 44 | | [root\_namespace](#input\_root\_namespace) | The .NET Namespace that will be used to the names of the Visual Studio Solution and Project files as well as the default .NET namespace within the
C# codebase. | `string` | n/a | yes | 45 | | [terraform\_version](#input\_terraform\_version) | Specifies the version of Terraform to use for the deployment. | `string` | n/a | yes | 46 | 47 | ## Outputs 48 | 49 | No outputs. 50 | -------------------------------------------------------------------------------- /examples/azure-fn-app/main.tf: -------------------------------------------------------------------------------- 1 | module "app" { 2 | 3 | source = "../../modules/azure-fn-app" 4 | 5 | application_name = var.application_name 6 | github_organization = var.github_organization 7 | repository_name = var.repository_name 8 | repository_description = var.repository_description 9 | repository_visibility = var.repository_visibility 10 | terraform_version = var.terraform_version 11 | primary_location = "eastus2" 12 | os_type = "Windows" 13 | core_name = var.core_name 14 | root_namespace = var.root_namespace 15 | 16 | commit_user = { 17 | name = var.github_username 18 | email = var.github_email 19 | } 20 | 21 | environments = { 22 | dev = { 23 | subscription_id = var.azure_nonprod_subscription 24 | branch_name = "develop" 25 | reviewing_teams = [] 26 | reviewing_users = [] 27 | backend = var.nonprod_backend 28 | } 29 | test = { 30 | subscription_id = var.azure_nonprod_subscription 31 | branch_name = "release" 32 | reviewing_teams = [] 33 | reviewing_users = [] 34 | backend = var.nonprod_backend 35 | } 36 | prod = { 37 | subscription_id = var.azure_prod_subscription 38 | branch_name = "main" 39 | reviewing_teams = [] 40 | reviewing_users = [] 41 | backend = var.prod_backend 42 | } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /examples/azure-fn-app/variables.tf: -------------------------------------------------------------------------------- 1 | variable "application_name" { 2 | type = string 3 | description = < 8 | ## Requirements 9 | 10 | | Name | Version | 11 | |------|---------| 12 | | [azuread](#requirement\_azuread) | ~> 3.0.2 | 13 | | [azurerm](#requirement\_azurerm) | ~> 4.10.0 | 14 | | [github](#requirement\_github) | ~> 5.0 | 15 | 16 | ## Providers 17 | 18 | No providers. 19 | 20 | ## Modules 21 | 22 | | Name | Source | Version | 23 | |------|--------|---------| 24 | | [app](#module\_app) | ../../modules/azure-fn-core | n/a | 25 | 26 | ## Resources 27 | 28 | No resources. 29 | 30 | ## Inputs 31 | 32 | | Name | Description | Type | Default | Required | 33 | |------|-------------|------|---------|:--------:| 34 | | [application\_name](#input\_application\_name) | The name of the application to be deployed. This name is used for resource identification and naming conventions within the infrastructure.

It's best to keep this short and simple while also ensuring it is easily identifiable and relatively unique within your organization (or at least within the Subscriptions you are targetting). | `string` | n/a | yes | 35 | | [azure\_nonprod\_subscription](#input\_azure\_nonprod\_subscription) | The Azure Subscription ID for the non-production environment where non-production resources will be provisioned. | `string` | n/a | yes | 36 | | [azure\_prod\_subscription](#input\_azure\_prod\_subscription) | The Azure Subscription ID for the production environment where production resources will be provisioned. | `string` | n/a | yes | 37 | | [github\_email](#input\_github\_email) | The email address associated with the GitHub account used for committing changes. This is used to attribute commits to the correct user." | `string` | n/a | yes | 38 | | [github\_organization](#input\_github\_organization) | The GitHub organization under which the repository will be created. This should be the exact name of the GitHub organization. | `string` | n/a | yes | 39 | | [github\_username](#input\_github\_username) | The GitHub username that will be used for committing changes to the repository. Ensure this account has the necessary permissions within the GitHub organization." | `string` | n/a | yes | 40 | | [nonprod\_backend](#input\_nonprod\_backend) | Configuration for the backend storage used in the non-production environment. Includes resource group, storage account, and container names for Terraform state and plans. |
object({
resource_group_name = string
storage_account_name = string
state_container_name = string
plan_container_name = string
})
| n/a | yes | 41 | | [prod\_backend](#input\_prod\_backend) | Configuration for the backend storage used in the production environment. Includes resource group, storage account, and container names for Terraform state and plans. |
object({
resource_group_name = string
storage_account_name = string
state_container_name = string
plan_container_name = string
})
| n/a | yes | 42 | | [repository\_description](#input\_repository\_description) | A brief description of the GitHub repository. This helps in understanding the purpose and scope of the repository.

This should describe the workload represented by the `application_name`. | `string` | n/a | yes | 43 | | [repository\_name](#input\_repository\_name) | The name of the GitHub repository to be created. This name should be unique within the specified GitHub organization.

The GitHub repository name should correlate to the `application_name` as it will contain the source code for the infrastructure
that is provisioned to Azure. | `string` | n/a | yes | 44 | | [repository\_visibility](#input\_repository\_visibility) | The visibility level of the GitHub repository. Accepted values are 'public', 'private', or 'internal'. Determines who can view and access the repository. | `string` | n/a | yes | 45 | | [terraform\_version](#input\_terraform\_version) | Specifies the version of Terraform to use for the deployment. | `string` | n/a | yes | 46 | 47 | ## Outputs 48 | 49 | No outputs. 50 | -------------------------------------------------------------------------------- /examples/azure-fn-core/main.tf: -------------------------------------------------------------------------------- 1 | module "app" { 2 | 3 | source = "../../modules/azure-fn-core" 4 | 5 | application_name = var.application_name 6 | github_organization = var.github_organization 7 | repository_name = var.repository_name 8 | repository_description = var.repository_description 9 | repository_visibility = var.repository_visibility 10 | terraform_version = var.terraform_version 11 | primary_location = "eastus2" 12 | os_type = "Windows" 13 | sku_name = "Y1" 14 | retention_in_days = 30 15 | 16 | commit_user = { 17 | name = var.github_username 18 | email = var.github_email 19 | } 20 | 21 | environments = { 22 | dev = { 23 | subscription_id = var.azure_nonprod_subscription 24 | branch_name = "develop" 25 | backend = var.nonprod_backend 26 | } 27 | test = { 28 | subscription_id = var.azure_nonprod_subscription 29 | branch_name = "release" 30 | backend = var.nonprod_backend 31 | } 32 | prod = { 33 | subscription_id = var.azure_prod_subscription 34 | branch_name = "main" 35 | backend = var.prod_backend 36 | } 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /examples/azure-fn-core/variables.tf: -------------------------------------------------------------------------------- 1 | variable "application_name" { 2 | type = string 3 | description = < 2 | ## Requirements 3 | 4 | | Name | Version | 5 | |------|---------| 6 | | [azuread](#requirement\_azuread) | ~> 3.0.2 | 7 | | [azurerm](#requirement\_azurerm) | ~> 4.10.0 | 8 | | [github](#requirement\_github) | ~> 5.0 | 9 | 10 | ## Providers 11 | 12 | No providers. 13 | 14 | ## Modules 15 | 16 | | Name | Source | Version | 17 | |------|--------|---------| 18 | | [app](#module\_app) | ../../modules/azure-jekyll-site | n/a | 19 | 20 | ## Resources 21 | 22 | No resources. 23 | 24 | ## Inputs 25 | 26 | | Name | Description | Type | Default | Required | 27 | |------|-------------|------|---------|:--------:| 28 | | [application\_name](#input\_application\_name) | The name of the application to be deployed. This name is used for resource identification and naming conventions within the infrastructure.

It's best to keep this short and simple while also ensuring it is easily identifiable and relatively unique within your organization (or at least within the Subscriptions you are targetting). | `string` | n/a | yes | 29 | | [azure\_nonprod\_subscription](#input\_azure\_nonprod\_subscription) | The Azure Subscription ID for the non-production environment where non-production resources will be provisioned. | `string` | n/a | yes | 30 | | [azure\_prod\_subscription](#input\_azure\_prod\_subscription) | The Azure Subscription ID for the production environment where production resources will be provisioned. | `string` | n/a | yes | 31 | | [github\_email](#input\_github\_email) | The email address associated with the GitHub account used for committing changes. This is used to attribute commits to the correct user." | `string` | n/a | yes | 32 | | [github\_organization](#input\_github\_organization) | The GitHub organization under which the repository will be created. This should be the exact name of the GitHub organization. | `string` | n/a | yes | 33 | | [github\_username](#input\_github\_username) | The GitHub username that will be used for committing changes to the repository. Ensure this account has the necessary permissions within the GitHub organization." | `string` | n/a | yes | 34 | | [nonprod\_backend](#input\_nonprod\_backend) | Configuration for the backend storage used in the non-production environment. Includes resource group, storage account, and container names for Terraform state and plans. |
object({
resource_group_name = string
storage_account_name = string
state_container_name = string
plan_container_name = string
})
| n/a | yes | 35 | | [prod\_backend](#input\_prod\_backend) | Configuration for the backend storage used in the production environment. Includes resource group, storage account, and container names for Terraform state and plans. |
object({
resource_group_name = string
storage_account_name = string
state_container_name = string
plan_container_name = string
})
| n/a | yes | 36 | | [repository\_description](#input\_repository\_description) | A brief description of the GitHub repository. This helps in understanding the purpose and scope of the repository.

This should describe the workload represented by the `application_name`. | `string` | n/a | yes | 37 | | [repository\_name](#input\_repository\_name) | The name of the GitHub repository to be created. This name should be unique within the specified GitHub organization.

The GitHub repository name should correlate to the `application_name` as it will contain the source code for the infrastructure
that is provisioned to Azure. | `string` | n/a | yes | 38 | | [repository\_visibility](#input\_repository\_visibility) | The visibility level of the GitHub repository. Accepted values are 'public', 'private', or 'internal'. Determines who can view and access the repository. | `string` | n/a | yes | 39 | | [terraform\_version](#input\_terraform\_version) | Specifies the version of Terraform to use for the deployment. | `string` | n/a | yes | 40 | 41 | ## Outputs 42 | 43 | No outputs. 44 | -------------------------------------------------------------------------------- /examples/azure-jekyll-site/main.tf: -------------------------------------------------------------------------------- 1 | module "app" { 2 | 3 | source = "../../modules/azure-jekyll-site" 4 | 5 | application_name = var.application_name 6 | github_organization = var.github_organization 7 | repository_name = var.repository_name 8 | repository_description = var.repository_description 9 | repository_visibility = var.repository_visibility 10 | terraform_version = var.terraform_version 11 | location = "westus2" 12 | 13 | commit_user = { 14 | name = var.github_username 15 | email = var.github_email 16 | } 17 | 18 | environments = { 19 | dev = { 20 | subscription_id = var.azure_nonprod_subscription 21 | branch_name = "develop" 22 | backend = var.nonprod_backend 23 | } 24 | prod = { 25 | subscription_id = var.azure_prod_subscription 26 | branch_name = "main" 27 | backend = var.prod_backend 28 | } 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /examples/azure-jekyll-site/variables.tf: -------------------------------------------------------------------------------- 1 | variable "application_name" { 2 | type = string 3 | description = < 6 | ## Requirements 7 | 8 | | Name | Version | 9 | |------|---------| 10 | | [azuread](#requirement\_azuread) | ~> 3.0.2 | 11 | | [azurerm](#requirement\_azurerm) | ~> 4.10.0 | 12 | | [github](#requirement\_github) | ~> 5.0 | 13 | 14 | ## Providers 15 | 16 | | Name | Version | 17 | |------|---------| 18 | | [random](#provider\_random) | n/a | 19 | 20 | ## Modules 21 | 22 | | Name | Source | Version | 23 | |------|--------|---------| 24 | | [app](#module\_app) | ../../modules/azure-starter-app | n/a | 25 | | [backend](#module\_backend) | ../../modules/azure-dual-backend | n/a | 26 | 27 | ## Resources 28 | 29 | | Name | Type | 30 | |------|------| 31 | | [random_string.backend_suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource | 32 | 33 | ## Inputs 34 | 35 | | Name | Description | Type | Default | Required | 36 | |------|-------------|------|---------|:--------:| 37 | | [application\_name](#input\_application\_name) | The name of the application to be deployed. This name is used for resource identification and naming conventions within the infrastructure.

It's best to keep this short and simple while also ensuring it is easily identifiable and relatively unique within your organization (or at least within the Subscriptions you are targetting). | `string` | n/a | yes | 38 | | [azure\_nonprod\_subscription](#input\_azure\_nonprod\_subscription) | The Azure Subscription ID for the non-production environment where non-production resources will be provisioned. | `string` | n/a | yes | 39 | | [azure\_prod\_subscription](#input\_azure\_prod\_subscription) | The Azure Subscription ID for the production environment where production resources will be provisioned. | `string` | n/a | yes | 40 | | [github\_email](#input\_github\_email) | The email address associated with the GitHub account used for committing changes. This is used to attribute commits to the correct user." | `string` | n/a | yes | 41 | | [github\_organization](#input\_github\_organization) | The GitHub organization under which the repository will be created. This should be the exact name of the GitHub organization. | `string` | n/a | yes | 42 | | [github\_username](#input\_github\_username) | The GitHub username that will be used for committing changes to the repository. Ensure this account has the necessary permissions within the GitHub organization." | `string` | n/a | yes | 43 | | [location](#input\_location) | The Azure region where the Terraform State Backends will be provisioned. | `string` | n/a | yes | 44 | | [repository\_description](#input\_repository\_description) | A brief description of the GitHub repository. This helps in understanding the purpose and scope of the repository.

This should describe the workload represented by the `application_name`. | `string` | n/a | yes | 45 | | [repository\_name](#input\_repository\_name) | The name of the GitHub repository to be created. This name should be unique within the specified GitHub organization.

The GitHub repository name should correlate to the `application_name` as it will contain the source code for the infrastructure
that is provisioned to Azure. | `string` | n/a | yes | 46 | | [repository\_visibility](#input\_repository\_visibility) | The visibility level of the GitHub repository. Accepted values are 'public', 'private', or 'internal'. Determines who can view and access the repository. | `string` | n/a | yes | 47 | | [terraform\_version](#input\_terraform\_version) | Specifies the version of Terraform to use for the deployment. | `string` | n/a | yes | 48 | 49 | ## Outputs 50 | 51 | No outputs. 52 | -------------------------------------------------------------------------------- /examples/azure-starter-app-stand-alone/main.tf: -------------------------------------------------------------------------------- 1 | resource "random_string" "backend_suffix" { 2 | length = 8 3 | upper = false 4 | special = false 5 | } 6 | 7 | module "backend" { 8 | 9 | source = "../../modules/azure-dual-backend" 10 | 11 | providers = { 12 | azurerm.nonprod = azurerm.nonprod 13 | azurerm.prod = azurerm.prod 14 | } 15 | 16 | name = "tf${random_string.backend_suffix.result}" 17 | location = var.location 18 | 19 | } 20 | 21 | module "app" { 22 | 23 | source = "../../modules/azure-starter-app" 24 | 25 | application_name = var.application_name 26 | github_organization = var.github_organization 27 | repository_name = var.repository_name 28 | repository_description = var.repository_description 29 | repository_visibility = var.repository_visibility 30 | terraform_version = var.terraform_version 31 | 32 | commit_user = { 33 | name = var.github_username 34 | email = var.github_email 35 | } 36 | 37 | environments = { 38 | dev = { 39 | subscription_id = var.azure_nonprod_subscription 40 | branch_name = "develop" 41 | backend = module.backend.nonprod 42 | } 43 | test = { 44 | subscription_id = var.azure_nonprod_subscription 45 | branch_name = "release" 46 | backend = module.backend.nonprod 47 | } 48 | prod = { 49 | subscription_id = var.azure_prod_subscription 50 | branch_name = "main" 51 | backend = module.backend.prod 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /examples/azure-starter-app-stand-alone/variables.tf: -------------------------------------------------------------------------------- 1 | variable "application_name" { 2 | type = string 3 | description = < 8 | ## Requirements 9 | 10 | | Name | Version | 11 | |------|---------| 12 | | [azuread](#requirement\_azuread) | ~> 3.0.2 | 13 | | [azurerm](#requirement\_azurerm) | ~> 4.10.0 | 14 | | [github](#requirement\_github) | ~> 5.0 | 15 | 16 | ## Providers 17 | 18 | No providers. 19 | 20 | ## Modules 21 | 22 | | Name | Source | Version | 23 | |------|--------|---------| 24 | | [app](#module\_app) | ../../modules/azure-starter-app | n/a | 25 | 26 | ## Resources 27 | 28 | No resources. 29 | 30 | ## Inputs 31 | 32 | | Name | Description | Type | Default | Required | 33 | |------|-------------|------|---------|:--------:| 34 | | [application\_name](#input\_application\_name) | The name of the application to be deployed. This name is used for resource identification and naming conventions within the infrastructure.

It's best to keep this short and simple while also ensuring it is easily identifiable and relatively unique within your organization (or at least within the Subscriptions you are targetting). | `string` | n/a | yes | 35 | | [azure\_nonprod\_subscription](#input\_azure\_nonprod\_subscription) | The Azure Subscription ID for the non-production environment where non-production resources will be provisioned. | `string` | n/a | yes | 36 | | [azure\_prod\_subscription](#input\_azure\_prod\_subscription) | The Azure Subscription ID for the production environment where production resources will be provisioned. | `string` | n/a | yes | 37 | | [github\_email](#input\_github\_email) | The email address associated with the GitHub account used for committing changes. This is used to attribute commits to the correct user." | `string` | n/a | yes | 38 | | [github\_organization](#input\_github\_organization) | The GitHub organization under which the repository will be created. This should be the exact name of the GitHub organization. | `string` | n/a | yes | 39 | | [github\_username](#input\_github\_username) | The GitHub username that will be used for committing changes to the repository. Ensure this account has the necessary permissions within the GitHub organization." | `string` | n/a | yes | 40 | | [nonprod\_backend](#input\_nonprod\_backend) | Configuration for the backend storage used in the non-production environment. Includes resource group, storage account, and container names for Terraform state and plans. |
object({
resource_group_name = string
storage_account_name = string
state_container_name = string
plan_container_name = string
})
| n/a | yes | 41 | | [prod\_backend](#input\_prod\_backend) | Configuration for the backend storage used in the production environment. Includes resource group, storage account, and container names for Terraform state and plans. |
object({
resource_group_name = string
storage_account_name = string
state_container_name = string
plan_container_name = string
})
| n/a | yes | 42 | | [repository\_description](#input\_repository\_description) | A brief description of the GitHub repository. This helps in understanding the purpose and scope of the repository.

This should describe the workload represented by the `application_name`. | `string` | n/a | yes | 43 | | [repository\_name](#input\_repository\_name) | The name of the GitHub repository to be created. This name should be unique within the specified GitHub organization.

The GitHub repository name should correlate to the `application_name` as it will contain the source code for the infrastructure
that is provisioned to Azure. | `string` | n/a | yes | 44 | | [repository\_visibility](#input\_repository\_visibility) | The visibility level of the GitHub repository. Accepted values are 'public', 'private', or 'internal'. Determines who can view and access the repository. | `string` | n/a | yes | 45 | | [terraform\_version](#input\_terraform\_version) | Specifies the version of Terraform to use for the deployment. | `string` | n/a | yes | 46 | 47 | ## Outputs 48 | 49 | No outputs. 50 | -------------------------------------------------------------------------------- /examples/azure-starter-app/main.tf: -------------------------------------------------------------------------------- 1 | module "app" { 2 | 3 | source = "../../modules/azure-starter-app" 4 | 5 | application_name = var.application_name 6 | github_organization = var.github_organization 7 | repository_name = var.repository_name 8 | repository_description = var.repository_description 9 | repository_visibility = var.repository_visibility 10 | terraform_version = var.terraform_version 11 | 12 | commit_user = { 13 | name = var.github_username 14 | email = var.github_email 15 | } 16 | 17 | environments = { 18 | dev = { 19 | subscription_id = var.azure_nonprod_subscription 20 | branch_name = "develop" 21 | backend = var.nonprod_backend 22 | } 23 | test = { 24 | subscription_id = var.azure_nonprod_subscription 25 | branch_name = "release" 26 | backend = var.nonprod_backend 27 | } 28 | prod = { 29 | subscription_id = var.azure_prod_subscription 30 | branch_name = "main" 31 | backend = var.prod_backend 32 | } 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /examples/azure-starter-app/variables.tf: -------------------------------------------------------------------------------- 1 | variable "application_name" { 2 | type = string 3 | description = < 2 | ## Requirements 3 | 4 | | Name | Version | 5 | |------|---------| 6 | | [azuread](#requirement\_azuread) | ~> 3.0.2 | 7 | | [azurerm](#requirement\_azurerm) | ~> 4.10.0 | 8 | | [github](#requirement\_github) | ~> 5.0 | 9 | 10 | ## Providers 11 | 12 | No providers. 13 | 14 | ## Modules 15 | 16 | | Name | Source | Version | 17 | |------|--------|---------| 18 | | [app](#module\_app) | ../../modules/azure-vm-app | n/a | 19 | 20 | ## Resources 21 | 22 | No resources. 23 | 24 | ## Inputs 25 | 26 | | Name | Description | Type | Default | Required | 27 | |------|-------------|------|---------|:--------:| 28 | | [application\_name](#input\_application\_name) | The name of the application to be deployed. This name is used for resource identification and naming conventions within the infrastructure.

It's best to keep this short and simple while also ensuring it is easily identifiable and relatively unique within your organization (or at least within the Subscriptions you are targetting). | `string` | n/a | yes | 29 | | [azure\_nonprod\_subscription](#input\_azure\_nonprod\_subscription) | The Azure Subscription ID for the non-production environment where non-production resources will be provisioned. | `string` | n/a | yes | 30 | | [azure\_prod\_subscription](#input\_azure\_prod\_subscription) | The Azure Subscription ID for the production environment where production resources will be provisioned. | `string` | n/a | yes | 31 | | [github\_email](#input\_github\_email) | The email address associated with the GitHub account used for committing changes. This is used to attribute commits to the correct user." | `string` | n/a | yes | 32 | | [github\_organization](#input\_github\_organization) | The GitHub organization under which the repository will be created. This should be the exact name of the GitHub organization. | `string` | n/a | yes | 33 | | [github\_username](#input\_github\_username) | The GitHub username that will be used for committing changes to the repository. Ensure this account has the necessary permissions within the GitHub organization." | `string` | n/a | yes | 34 | | [nonprod\_backend](#input\_nonprod\_backend) | Configuration for the backend storage used in the non-production environment. Includes resource group, storage account, and container names for Terraform state and plans. |
object({
resource_group_name = string
storage_account_name = string
state_container_name = string
plan_container_name = string
})
| n/a | yes | 35 | | [prod\_backend](#input\_prod\_backend) | Configuration for the backend storage used in the production environment. Includes resource group, storage account, and container names for Terraform state and plans. |
object({
resource_group_name = string
storage_account_name = string
state_container_name = string
plan_container_name = string
})
| n/a | yes | 36 | | [repository\_description](#input\_repository\_description) | A brief description of the GitHub repository. This helps in understanding the purpose and scope of the repository.

This should describe the workload represented by the `application_name`. | `string` | n/a | yes | 37 | | [repository\_name](#input\_repository\_name) | The name of the GitHub repository to be created. This name should be unique within the specified GitHub organization.

The GitHub repository name should correlate to the `application_name` as it will contain the source code for the infrastructure
that is provisioned to Azure. | `string` | n/a | yes | 38 | | [repository\_visibility](#input\_repository\_visibility) | The visibility level of the GitHub repository. Accepted values are 'public', 'private', or 'internal'. Determines who can view and access the repository. | `string` | n/a | yes | 39 | | [terraform\_version](#input\_terraform\_version) | Specifies the version of Terraform to use for the deployment. | `string` | n/a | yes | 40 | 41 | ## Outputs 42 | 43 | No outputs. 44 | -------------------------------------------------------------------------------- /examples/azure-vm-app/main.tf: -------------------------------------------------------------------------------- 1 | module "app" { 2 | 3 | source = "../../modules/azure-vm-app" 4 | 5 | application_name = var.application_name 6 | github_organization = var.github_organization 7 | repository_name = var.repository_name 8 | repository_description = var.repository_description 9 | repository_visibility = var.repository_visibility 10 | terraform_version = var.terraform_version 11 | location = "eastus2" 12 | image_names = ["ubuntu-minecraft-bedrock"] 13 | vm_size = "Standard_D2_v2_Promo" 14 | packer_version = "1.9.4" 15 | base_address_space = "10.64.0.0/22" 16 | 17 | commit_user = { 18 | name = var.github_username 19 | email = var.github_email 20 | } 21 | 22 | environments = { 23 | dev = { 24 | subscription_id = var.azure_nonprod_subscription 25 | branch_name = "develop" 26 | backend = var.nonprod_backend 27 | gallery = { 28 | name = "galqonqgallerydev" 29 | resource_group = "rg-qonq-gallery-dev" 30 | } 31 | managed_image_destination = "rg-qonq-gallery-dev" 32 | } 33 | prod = { 34 | subscription_id = var.azure_prod_subscription 35 | branch_name = "main" 36 | backend = var.prod_backend 37 | gallery = { 38 | name = "galqonqgalleryprod" 39 | resource_group = "rg-qonq-gallery-prod" 40 | } 41 | managed_image_destination = "rg-qonq-gallery-prod" 42 | } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /examples/azure-vm-app/variables.tf: -------------------------------------------------------------------------------- 1 | variable "application_name" { 2 | type = string 3 | description = < 2 | ## Requirements 3 | 4 | | Name | Version | 5 | |------|---------| 6 | | [azuread](#requirement\_azuread) | ~> 3.0.2 | 7 | | [azurerm](#requirement\_azurerm) | ~> 4.10.0 | 8 | | [github](#requirement\_github) | ~> 5.0 | 9 | 10 | ## Providers 11 | 12 | No providers. 13 | 14 | ## Modules 15 | 16 | | Name | Source | Version | 17 | |------|--------|---------| 18 | | [app](#module\_app) | ../../modules/azure-vm-core | n/a | 19 | 20 | ## Resources 21 | 22 | No resources. 23 | 24 | ## Inputs 25 | 26 | | Name | Description | Type | Default | Required | 27 | |------|-------------|------|---------|:--------:| 28 | | [application\_name](#input\_application\_name) | The name of the application to be deployed. This name is used for resource identification and naming conventions within the infrastructure.

It's best to keep this short and simple while also ensuring it is easily identifiable and relatively unique within your organization (or at least within the Subscriptions you are targetting). | `string` | n/a | yes | 29 | | [azure\_nonprod\_subscription](#input\_azure\_nonprod\_subscription) | The Azure Subscription ID for the non-production environment where non-production resources will be provisioned. | `string` | n/a | yes | 30 | | [azure\_prod\_subscription](#input\_azure\_prod\_subscription) | The Azure Subscription ID for the production environment where production resources will be provisioned. | `string` | n/a | yes | 31 | | [github\_email](#input\_github\_email) | The email address associated with the GitHub account used for committing changes. This is used to attribute commits to the correct user." | `string` | n/a | yes | 32 | | [github\_organization](#input\_github\_organization) | The GitHub organization under which the repository will be created. This should be the exact name of the GitHub organization. | `string` | n/a | yes | 33 | | [github\_username](#input\_github\_username) | The GitHub username that will be used for committing changes to the repository. Ensure this account has the necessary permissions within the GitHub organization." | `string` | n/a | yes | 34 | | [nonprod\_backend](#input\_nonprod\_backend) | Configuration for the backend storage used in the non-production environment. Includes resource group, storage account, and container names for Terraform state and plans. |
object({
resource_group_name = string
storage_account_name = string
state_container_name = string
plan_container_name = string
})
| n/a | yes | 35 | | [prod\_backend](#input\_prod\_backend) | Configuration for the backend storage used in the production environment. Includes resource group, storage account, and container names for Terraform state and plans. |
object({
resource_group_name = string
storage_account_name = string
state_container_name = string
plan_container_name = string
})
| n/a | yes | 36 | | [repository\_description](#input\_repository\_description) | A brief description of the GitHub repository. This helps in understanding the purpose and scope of the repository.

This should describe the workload represented by the `application_name`. | `string` | n/a | yes | 37 | | [repository\_name](#input\_repository\_name) | The name of the GitHub repository to be created. This name should be unique within the specified GitHub organization.

The GitHub repository name should correlate to the `application_name` as it will contain the source code for the infrastructure
that is provisioned to Azure. | `string` | n/a | yes | 38 | | [repository\_visibility](#input\_repository\_visibility) | The visibility level of the GitHub repository. Accepted values are 'public', 'private', or 'internal'. Determines who can view and access the repository. | `string` | n/a | yes | 39 | | [terraform\_version](#input\_terraform\_version) | Specifies the version of Terraform to use for the deployment. | `string` | n/a | yes | 40 | 41 | ## Outputs 42 | 43 | No outputs. 44 | -------------------------------------------------------------------------------- /examples/azure-vm-core/main.tf: -------------------------------------------------------------------------------- 1 | module "app" { 2 | 3 | source = "../../modules/azure-vm-core" 4 | 5 | application_name = var.application_name 6 | github_organization = var.github_organization 7 | repository_name = var.repository_name 8 | repository_description = var.repository_description 9 | repository_visibility = var.repository_visibility 10 | terraform_version = var.terraform_version 11 | location = "eastus2" 12 | 13 | commit_user = { 14 | name = var.github_username 15 | email = var.github_email 16 | } 17 | 18 | environments = { 19 | dev = { 20 | subscription_id = var.azure_nonprod_subscription 21 | branch_name = "develop" 22 | backend = var.nonprod_backend 23 | } 24 | prod = { 25 | subscription_id = var.azure_prod_subscription 26 | branch_name = "main" 27 | backend = var.prod_backend 28 | } 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /examples/azure-vm-core/variables.tf: -------------------------------------------------------------------------------- 1 | variable "application_name" { 2 | type = string 3 | description = < 14 | ## Requirements 15 | 16 | | Name | Version | 17 | |------|---------| 18 | | [azuread](#requirement\_azuread) | ~> 3.0.2 | 19 | | [azurerm](#requirement\_azurerm) | ~> 4.10.0 | 20 | | [github](#requirement\_github) | ~> 5.0 | 21 | 22 | ## Providers 23 | 24 | No providers. 25 | 26 | ## Modules 27 | 28 | | Name | Source | Version | 29 | |------|--------|---------| 30 | | [backend\_nonprod](#module\_backend\_nonprod) | Azure-Terraformer/terraform-backend/azurerm | 1.0.4 | 31 | | [backend\_prod](#module\_backend\_prod) | Azure-Terraformer/terraform-backend/azurerm | 1.0.4 | 32 | 33 | ## Resources 34 | 35 | No resources. 36 | 37 | ## Inputs 38 | 39 | | Name | Description | Type | Default | Required | 40 | |------|-------------|------|---------|:--------:| 41 | | [location](#input\_location) | The Azure region where the Terraform State Backends will be provisioned. | `string` | n/a | yes | 42 | | [name](#input\_name) | The name of the environment containing dual Terraform State Backends that you'd like to create. | `string` | n/a | yes | 43 | 44 | ## Outputs 45 | 46 | | Name | Description | 47 | |------|-------------| 48 | | [nonprod](#output\_nonprod) | The backend configuration for the Non-Production environment.

This configuration includes:
- **resource\_group\_name** (string): The name of the Azure Resource Group where the storage account resides.
- **storage\_account\_name** (string): The name of the Azure Storage Account used to store Terraform state and plan files.
- **state\_container\_name** (string): The name of the Azure Storage Container specifically for Terraform state files (`tfstate`).
- **plan\_container\_name** (string): The name of the Azure Storage Container specifically for Terraform plan files (`tfplan`).

This output is utilized by Terraform to manage the state and plan files securely within Azure for the Non-Production environment. | 49 | | [prod](#output\_prod) | The backend configuration for the Production environment.

This configuration includes:
- **resource\_group\_name** (string): The name of the Azure Resource Group where the storage account resides.
- **storage\_account\_name** (string): The name of the Azure Storage Account used to store Terraform state and plan files.
- **state\_container\_name** (string): The name of the Azure Storage Container specifically for Terraform state files (`tfstate`).
- **plan\_container\_name** (string): The name of the Azure Storage Container specifically for Terraform plan files (`tfplan`).

This output is utilized by Terraform to manage the state and plan files securely within Azure for the Production environment. | 50 | -------------------------------------------------------------------------------- /modules/azure-dual-backend/main.tf: -------------------------------------------------------------------------------- 1 | module "backend_nonprod" { 2 | 3 | providers = { 4 | azurerm = azurerm.nonprod 5 | } 6 | 7 | source = "Azure-Terraformer/terraform-backend/azurerm" 8 | version = "1.0.4" 9 | 10 | name = var.name 11 | location = var.location 12 | tags = { 13 | application_name = var.name 14 | environment_name = "nonprod" 15 | } 16 | 17 | } 18 | 19 | module "backend_prod" { 20 | 21 | providers = { 22 | azurerm = azurerm.prod 23 | } 24 | 25 | source = "Azure-Terraformer/terraform-backend/azurerm" 26 | version = "1.0.4" 27 | 28 | name = var.name 29 | location = var.location 30 | tags = { 31 | application_name = var.name 32 | environment_name = "prod" 33 | } 34 | 35 | } 36 | 37 | locals { 38 | backends = { 39 | nonprod = module.backend_nonprod.backend_config, 40 | prod = module.backend_prod.backend_config 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /modules/azure-dual-backend/outputs.tf: -------------------------------------------------------------------------------- 1 | output "nonprod" { 2 | value = module.backend_nonprod.backend_config 3 | 4 | description = < 7 | ## Requirements 8 | 9 | | Name | Version | 10 | |------|---------| 11 | | [azuread](#requirement\_azuread) | ~> 3.0.2 | 12 | | [azurerm](#requirement\_azurerm) | ~> 4.10.0 | 13 | | [github](#requirement\_github) | ~> 5.0 | 14 | 15 | ## Providers 16 | 17 | | Name | Version | 18 | |------|---------| 19 | | [azuread](#provider\_azuread) | ~> 3.0.2 | 20 | | [azurerm](#provider\_azurerm) | ~> 4.10.0 | 21 | | [github](#provider\_github) | ~> 5.0 | 22 | | [random](#provider\_random) | n/a | 23 | 24 | ## Modules 25 | 26 | | Name | Source | Version | 27 | |------|--------|---------| 28 | | [action-azure-login-test](#module\_action-azure-login-test) | Azure-Terraformer/action-azure-login-test/github | 1.0.1 | 29 | | [dotnet\_codebase](#module\_dotnet\_codebase) | Azure-Terraformer/codebase-terraform-azure-fn-app-dotnet/github | 1.0.39 | 30 | | [github\_environments-terraform-azure](#module\_github\_environments-terraform-azure) | Azure-Terraformer/environment-terraform-azure/github | 1.0.3 | 31 | | [github\_identity](#module\_github\_identity) | Azure-Terraformer/github-credential/azuread | 1.0.10 | 32 | | [terraform\_codebase](#module\_terraform\_codebase) | Azure-Terraformer/codebase-terraform-azure-fn-app/github | 1.0.26 | 33 | | [terraform\_gitflow](#module\_terraform\_gitflow) | Azure-Terraformer/action-azure-application/github | 1.0.32 | 34 | 35 | ## Resources 36 | 37 | | Name | Type | 38 | |------|------| 39 | | [azurerm_role_assignment.main](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | 40 | | [github_actions_variable.application_name](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_variable) | resource | 41 | | [github_branch.main](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch) | resource | 42 | | [github_branch_default.default](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch_default) | resource | 43 | | [github_repository.main](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository) | resource | 44 | | [random_string.main](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource | 45 | | [azuread_client_config.current](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/client_config) | data source | 46 | | [azurerm_subscription.main](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subscription) | data source | 47 | | [github_user.current](https://registry.terraform.io/providers/integrations/github/latest/docs/data-sources/user) | data source | 48 | 49 | ## Inputs 50 | 51 | | Name | Description | Type | Default | Required | 52 | |------|-------------|------|---------|:--------:| 53 | | [application\_name](#input\_application\_name) | The name of the application to be deployed. This name is used for resource identification and naming conventions within the infrastructure.

It's best to keep this short and simple while also ensuring it is easily identifiable and relatively unique within your organization (or at least within the Subscriptions you are targetting). | `string` | n/a | yes | 54 | | [commit\_user](#input\_commit\_user) | The user information for committing changes to the repository, including name and email. |
object({
name = string
email = string
})
| n/a | yes | 55 | | [core\_name](#input\_core\_name) | The name of the Azure Functions Core Environment. | `string` | n/a | yes | 56 | | [delay\_after\_environment\_creation](#input\_delay\_after\_environment\_creation) | GitHub Environments have a glitch that causes them to not be available immediately after creation is reported. Environment variables
will fail unless there is some time granted to allow for the Environment creation to complete. This setting adds a fixed amount of time
after the creation of the environment before provisioning additional resources. | `number` | `10` | no | 57 | | [delete\_branch\_on\_merge](#input\_delete\_branch\_on\_merge) | The setting that controls whether the GitHub repository deletes the feature branch automatically after the merge. | `bool` | `true` | no | 58 | | [environments](#input\_environments) | Configuration for each of the environments for this application.

Each Environment has a name which is supplied by the key of the map.
Each Environment has a long-lived environment on the specified `branch_name`.
Each Environment can be provisioned within the context of an Azure Subscription specified by `subscription_id`.
Each Environment can have its own Terraform State Backend configuration which consists of an Azure Storage Account and containers for both state files and plan files. |
map(object({
subscription_id = string
branch_name = string
reviewing_users = list(string)
reviewing_teams = list(string)
backend = object({
resource_group_name = string
storage_account_name = string
state_container_name = string
plan_container_name = string
})
}))
| n/a | yes | 59 | | [github\_organization](#input\_github\_organization) | The GitHub organization under which the repository will be created. This should be the exact name of the GitHub organization. | `string` | n/a | yes | 60 | | [os\_type](#input\_os\_type) | The operating system type for Azure Function Service Plan that will be provisioned." | `string` | n/a | yes | 61 | | [primary\_location](#input\_primary\_location) | The primary Azure region where the Azure Functions Core Environment will be provisioned." | `string` | n/a | yes | 62 | | [repository\_description](#input\_repository\_description) | A brief description of the GitHub repository. This helps in understanding the purpose and scope of the repository.

This should describe the workload represented by the `application_name`. | `string` | n/a | yes | 63 | | [repository\_name](#input\_repository\_name) | The name of the GitHub repository to be created. This name should be unique within the specified GitHub organization.

The GitHub repository name should correlate to the `application_name` as it will contain the source code for the infrastructure
that is provisioned to Azure. | `string` | n/a | yes | 64 | | [repository\_visibility](#input\_repository\_visibility) | The visibility level of the GitHub repository. Accepted values are 'public', 'private', or 'internal'. Determines who can view and access the repository. | `string` | n/a | yes | 65 | | [root\_namespace](#input\_root\_namespace) | The .NET Namespace that will be used to the names of the Visual Studio Solution and Project files as well as the default .NET namespace within the
C# codebase. | `string` | n/a | yes | 66 | | [terraform\_version](#input\_terraform\_version) | Specifies the version of Terraform to use. Defaults to '1.9.8'. | `string` | `"1.9.8"` | no | 67 | 68 | ## Outputs 69 | 70 | No outputs. 71 | -------------------------------------------------------------------------------- /modules/azure-fn-app/codebase.tf: -------------------------------------------------------------------------------- 1 | module "terraform_codebase" { 2 | 3 | source = "Azure-Terraformer/codebase-terraform-azure-fn-app/github" 4 | version = "1.0.26" 5 | 6 | repository = var.repository_name 7 | branch = github_branch.main.branch 8 | path = "src/terraform" 9 | commit_user = var.commit_user 10 | primary_location = var.primary_location 11 | os_type = var.os_type 12 | core_name = var.core_name 13 | 14 | } 15 | 16 | module "dotnet_codebase" { 17 | 18 | source = "Azure-Terraformer/codebase-terraform-azure-fn-app-dotnet/github" 19 | version = "1.0.39" 20 | 21 | repository = var.repository_name 22 | branch = github_branch.main.branch 23 | path = "src/dotnet" 24 | commit_user = var.commit_user 25 | root_namespace = var.root_namespace 26 | environments = local.branch_name_map 27 | 28 | } 29 | -------------------------------------------------------------------------------- /modules/azure-fn-app/environments.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | extended_environments = { 3 | for key, value in var.environments : key => { 4 | subscription_id = value.subscription_id 5 | tenant_id = data.azuread_client_config.current.tenant_id 6 | client_id = module.github_identity[key].application.client_id 7 | branch_name = value.branch_name 8 | reviewers = value.reviewing_users 9 | backend = value.backend 10 | } 11 | } 12 | } 13 | 14 | module "github_environments-terraform-azure" { 15 | source = "Azure-Terraformer/environment-terraform-azure/github" 16 | version = "1.0.3" 17 | 18 | repository_name = var.repository_name 19 | terraform_version = var.terraform_version 20 | terraform_working_directory = module.terraform_codebase.path 21 | delay_after_environment_creation = 10 22 | environments = local.extended_environments 23 | 24 | depends_on = [github_branch_default.default] 25 | 26 | } 27 | -------------------------------------------------------------------------------- /modules/azure-fn-app/identity.tf: -------------------------------------------------------------------------------- 1 | data "azuread_client_config" "current" {} 2 | 3 | resource "random_string" "main" { 4 | length = 8 5 | upper = false 6 | special = false 7 | } 8 | 9 | module "github_identity" { 10 | 11 | source = "Azure-Terraformer/github-credential/azuread" 12 | version = "1.0.10" 13 | 14 | for_each = var.environments 15 | 16 | name = "${var.github_organization}-${var.repository_name}-${each.key}" 17 | github_organization = var.github_organization 18 | repository_name = var.repository_name 19 | entity_type = "environment" 20 | environment_name = each.key 21 | owners = [data.azuread_client_config.current.object_id] 22 | 23 | } 24 | 25 | data "azurerm_subscription" "main" { 26 | 27 | for_each = var.environments 28 | 29 | subscription_id = each.value.subscription_id 30 | 31 | } 32 | 33 | resource "azurerm_role_assignment" "main" { 34 | 35 | for_each = var.environments 36 | 37 | scope = data.azurerm_subscription.main[each.key].id 38 | role_definition_name = "Owner" 39 | principal_id = module.github_identity[each.key].service_principal.object_id 40 | 41 | } 42 | -------------------------------------------------------------------------------- /modules/azure-fn-app/main.tf: -------------------------------------------------------------------------------- 1 | 2 | data "github_user" "current" { 3 | username = "" 4 | } 5 | 6 | resource "github_repository" "main" { 7 | 8 | name = var.repository_name 9 | description = var.repository_description 10 | 11 | visibility = var.repository_visibility 12 | delete_branch_on_merge = var.delete_branch_on_merge 13 | auto_init = true 14 | 15 | } 16 | 17 | resource "github_branch" "main" { 18 | repository = var.repository_name 19 | branch = "main" 20 | } 21 | 22 | resource "github_branch_default" "default" { 23 | repository = var.repository_name 24 | branch = github_branch.main.branch 25 | } 26 | 27 | resource "github_actions_variable" "application_name" { 28 | 29 | repository = var.repository_name 30 | variable_name = "APPLICATION_NAME" 31 | value = var.application_name 32 | 33 | depends_on = [github_branch_default.default] 34 | 35 | } 36 | -------------------------------------------------------------------------------- /modules/azure-fn-app/pipelines.tf: -------------------------------------------------------------------------------- 1 | # Local to convert to map(string) 2 | locals { 3 | branch_name_map = tomap({ 4 | for key, value in var.environments : key => value.branch_name 5 | }) 6 | } 7 | 8 | module "terraform_gitflow" { 9 | 10 | source = "Azure-Terraformer/action-azure-application/github" 11 | version = "1.0.32" 12 | 13 | repository = var.repository_name 14 | branch = github_branch.main.branch 15 | commit_user = var.commit_user 16 | environments = local.branch_name_map 17 | 18 | # we don't want the actions firing when we start pushing commits 19 | depends_on = [ 20 | module.terraform_codebase, 21 | module.dotnet_codebase 22 | ] 23 | 24 | } 25 | 26 | module "action-azure-login-test" { 27 | source = "Azure-Terraformer/action-azure-login-test/github" 28 | version = "1.0.1" 29 | 30 | repository = var.repository_name 31 | branch = github_branch.main.branch 32 | commit_user = var.commit_user 33 | 34 | } 35 | -------------------------------------------------------------------------------- /modules/azure-fn-app/variables.tf: -------------------------------------------------------------------------------- 1 | variable "application_name" { 2 | type = string 3 | description = < 6 | ## Requirements 7 | 8 | | Name | Version | 9 | |------|---------| 10 | | [azuread](#requirement\_azuread) | ~> 3.0.2 | 11 | | [azurerm](#requirement\_azurerm) | ~> 4.10.0 | 12 | | [github](#requirement\_github) | ~> 5.0 | 13 | 14 | ## Providers 15 | 16 | | Name | Version | 17 | |------|---------| 18 | | [azuread](#provider\_azuread) | ~> 3.0.2 | 19 | | [azurerm](#provider\_azurerm) | ~> 4.10.0 | 20 | | [github](#provider\_github) | ~> 5.0 | 21 | | [random](#provider\_random) | n/a | 22 | 23 | ## Modules 24 | 25 | | Name | Source | Version | 26 | |------|--------|---------| 27 | | [action\_azure\_login](#module\_action\_azure\_login) | Azure-Terraformer/action-azure-login-test/github | 1.0.1 | 28 | | [codebase](#module\_codebase) | Azure-Terraformer/codebase-terraform-azure-fn-core/github | 1.0.14 | 29 | | [gitflow](#module\_gitflow) | Azure-Terraformer/action-azure-application/github | 1.0.32 | 30 | | [github\_environments](#module\_github\_environments) | Azure-Terraformer/environment-terraform-azure/github | 1.0.3 | 31 | | [github\_identity](#module\_github\_identity) | Azure-Terraformer/github-credential/azuread | 1.0.10 | 32 | 33 | ## Resources 34 | 35 | | Name | Type | 36 | |------|------| 37 | | [azurerm_role_assignment.main](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | 38 | | [github_actions_variable.application_name](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_variable) | resource | 39 | | [github_branch.main](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch) | resource | 40 | | [github_branch_default.default](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch_default) | resource | 41 | | [github_repository.main](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository) | resource | 42 | | [random_string.main](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource | 43 | | [azuread_client_config.current](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/client_config) | data source | 44 | | [azurerm_subscription.main](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subscription) | data source | 45 | | [github_user.current](https://registry.terraform.io/providers/integrations/github/latest/docs/data-sources/user) | data source | 46 | 47 | ## Inputs 48 | 49 | | Name | Description | Type | Default | Required | 50 | |------|-------------|------|---------|:--------:| 51 | | [application\_name](#input\_application\_name) | The name of the application to be deployed. This name is used for resource identification and naming conventions within the infrastructure.

It's best to keep this short and simple while also ensuring it is easily identifiable and relatively unique within your organization (or at least within the Subscriptions you are targetting). | `string` | n/a | yes | 52 | | [commit\_user](#input\_commit\_user) | The user information for committing changes to the repository, including name and email. |
object({
name = string
email = string
})
| n/a | yes | 53 | | [delay\_after\_environment\_creation](#input\_delay\_after\_environment\_creation) | GitHub Environments have a glitch that causes them to not be available immediately after creation is reported. Environment variables
will fail unless there is some time granted to allow for the Environment creation to complete. This setting adds a fixed amount of time
after the creation of the environment before provisioning additional resources. | `number` | `10` | no | 54 | | [delete\_branch\_on\_merge](#input\_delete\_branch\_on\_merge) | The setting that controls whether the GitHub repository deletes the feature branch automatically after the merge. | `bool` | `true` | no | 55 | | [environments](#input\_environments) | Configuration for each of the environments for this application.

Each Environment has a name which is supplied by the key of the map.
Each Environment has a long-lived environment on the specified `branch_name`.
Each Environment can be provisioned within the context of an Azure Subscription specified by `subscription_id`.
Each Environment can have its own Terraform State Backend configuration which consists of an Azure Storage Account and containers for both state files and plan files. |
map(object({
subscription_id = string
branch_name = string
backend = object({
resource_group_name = string
storage_account_name = string
state_container_name = string
plan_container_name = string
})
}))
| n/a | yes | 56 | | [github\_organization](#input\_github\_organization) | The GitHub organization under which the repository will be created. This should be the exact name of the GitHub organization. | `string` | n/a | yes | 57 | | [os\_type](#input\_os\_type) | The operating system type for Azure Function Service Plan that will be provisioned." | `string` | n/a | yes | 58 | | [primary\_location](#input\_primary\_location) | The primary Azure region where the Azure Functions Core Environment will be provisioned." | `string` | n/a | yes | 59 | | [repository\_description](#input\_repository\_description) | A brief description of the GitHub repository. This helps in understanding the purpose and scope of the repository.

This should describe the workload represented by the `application_name`. | `string` | n/a | yes | 60 | | [repository\_name](#input\_repository\_name) | The name of the GitHub repository to be created. This name should be unique within the specified GitHub organization.

The GitHub repository name should correlate to the `application_name` as it will contain the source code for the infrastructure
that is provisioned to Azure. | `string` | n/a | yes | 61 | | [repository\_visibility](#input\_repository\_visibility) | The visibility level of the GitHub repository. Accepted values are 'public', 'private', or 'internal'. Determines who can view and access the repository. | `string` | n/a | yes | 62 | | [retention\_in\_days](#input\_retention\_in\_days) | The number of days to retain logs before automatic deletion from the Azure Log Analytics Workspace in the Azure Functions Core Environments. | `number` | n/a | yes | 63 | | [sku\_name](#input\_sku\_name) | The SKU for the Azure Function Service Plan. | `string` | n/a | yes | 64 | | [terraform\_version](#input\_terraform\_version) | Specifies the version of Terraform to use. Defaults to '1.9.8'. | `string` | `"1.9.8"` | no | 65 | 66 | ## Outputs 67 | 68 | No outputs. 69 | -------------------------------------------------------------------------------- /modules/azure-fn-core/codebase.tf: -------------------------------------------------------------------------------- 1 | module "codebase" { 2 | 3 | source = "Azure-Terraformer/codebase-terraform-azure-fn-core/github" 4 | version = "1.0.14" 5 | 6 | repository = var.repository_name 7 | branch = github_branch.main.branch 8 | commit_user = var.commit_user 9 | primary_location = var.primary_location 10 | os_type = var.os_type 11 | sku_name = var.sku_name 12 | retention_in_days = var.retention_in_days 13 | 14 | } 15 | -------------------------------------------------------------------------------- /modules/azure-fn-core/environments.tf: -------------------------------------------------------------------------------- 1 | 2 | locals { 3 | extended_environments = { 4 | for key, value in var.environments : key => { 5 | subscription_id = value.subscription_id 6 | tenant_id = data.azuread_client_config.current.tenant_id 7 | client_id = module.github_identity[key].application.client_id 8 | branch_name = value.branch_name 9 | reviewers = [] 10 | backend = value.backend 11 | } 12 | } 13 | } 14 | 15 | module "github_environments" { 16 | source = "Azure-Terraformer/environment-terraform-azure/github" 17 | version = "1.0.3" 18 | 19 | repository_name = var.repository_name 20 | terraform_version = var.terraform_version 21 | terraform_working_directory = module.codebase.path 22 | delay_after_environment_creation = 10 23 | environments = local.extended_environments 24 | 25 | depends_on = [github_branch_default.default] 26 | 27 | } 28 | -------------------------------------------------------------------------------- /modules/azure-fn-core/identity.tf: -------------------------------------------------------------------------------- 1 | data "azuread_client_config" "current" {} 2 | 3 | resource "random_string" "main" { 4 | length = 8 5 | upper = false 6 | special = false 7 | } 8 | 9 | module "github_identity" { 10 | 11 | source = "Azure-Terraformer/github-credential/azuread" 12 | version = "1.0.10" 13 | 14 | for_each = var.environments 15 | 16 | name = "${var.github_organization}-${var.repository_name}-${each.key}" 17 | github_organization = var.github_organization 18 | repository_name = var.repository_name 19 | entity_type = "environment" 20 | environment_name = each.key 21 | owners = [data.azuread_client_config.current.object_id] 22 | 23 | } 24 | 25 | data "azurerm_subscription" "main" { 26 | 27 | for_each = var.environments 28 | 29 | subscription_id = each.value.subscription_id 30 | 31 | } 32 | 33 | resource "azurerm_role_assignment" "main" { 34 | 35 | for_each = var.environments 36 | 37 | scope = data.azurerm_subscription.main[each.key].id 38 | role_definition_name = "Owner" 39 | principal_id = module.github_identity[each.key].service_principal.object_id 40 | 41 | } 42 | -------------------------------------------------------------------------------- /modules/azure-fn-core/main.tf: -------------------------------------------------------------------------------- 1 | 2 | data "github_user" "current" { 3 | username = "" 4 | } 5 | 6 | resource "github_repository" "main" { 7 | 8 | name = var.repository_name 9 | description = var.repository_description 10 | 11 | visibility = var.repository_visibility 12 | delete_branch_on_merge = var.delete_branch_on_merge 13 | auto_init = true 14 | 15 | } 16 | 17 | resource "github_branch" "main" { 18 | repository = var.repository_name 19 | branch = "main" 20 | } 21 | 22 | resource "github_branch_default" "default" { 23 | repository = var.repository_name 24 | branch = github_branch.main.branch 25 | } 26 | 27 | resource "github_actions_variable" "application_name" { 28 | 29 | repository = var.repository_name 30 | variable_name = "APPLICATION_NAME" 31 | value = var.application_name 32 | 33 | depends_on = [github_branch_default.default] 34 | 35 | } 36 | -------------------------------------------------------------------------------- /modules/azure-fn-core/pipelines.tf: -------------------------------------------------------------------------------- 1 | # Local to convert to map(string) 2 | locals { 3 | branch_name_map = tomap({ 4 | for key, value in var.environments : key => value.branch_name 5 | }) 6 | } 7 | 8 | module "gitflow" { 9 | 10 | source = "Azure-Terraformer/action-azure-application/github" 11 | version = "1.0.32" 12 | 13 | repository = var.repository_name 14 | branch = github_branch.main.branch 15 | commit_user = var.commit_user 16 | environments = local.branch_name_map 17 | 18 | # we don't want the actions firing when we start pushing commits 19 | depends_on = [module.codebase] 20 | 21 | } 22 | 23 | module "action_azure_login" { 24 | source = "Azure-Terraformer/action-azure-login-test/github" 25 | version = "1.0.1" 26 | 27 | repository = var.repository_name 28 | branch = github_branch.main.branch 29 | commit_user = var.commit_user 30 | 31 | } 32 | -------------------------------------------------------------------------------- /modules/azure-fn-core/variables.tf: -------------------------------------------------------------------------------- 1 | variable "application_name" { 2 | type = string 3 | description = < 6 | ## Requirements 7 | 8 | | Name | Version | 9 | |------|---------| 10 | | [azuread](#requirement\_azuread) | ~> 3.0.2 | 11 | | [azurerm](#requirement\_azurerm) | ~> 4.10.0 | 12 | | [github](#requirement\_github) | ~> 5.0 | 13 | 14 | ## Providers 15 | 16 | | Name | Version | 17 | |------|---------| 18 | | [azuread](#provider\_azuread) | ~> 3.0.2 | 19 | | [azurerm](#provider\_azurerm) | ~> 4.10.0 | 20 | | [github](#provider\_github) | ~> 5.0 | 21 | | [random](#provider\_random) | n/a | 22 | 23 | ## Modules 24 | 25 | | Name | Source | Version | 26 | |------|--------|---------| 27 | | [action\_azure\_login](#module\_action\_azure\_login) | Azure-Terraformer/action-azure-login-test/github | 1.0.1 | 28 | | [codebase](#module\_codebase) | Azure-Terraformer/codebase-terraform-azure-jekyll-site/github | 1.0.10 | 29 | | [gitflow](#module\_gitflow) | Azure-Terraformer/action-azure-application/github | 1.0.32 | 30 | | [github\_environments](#module\_github\_environments) | Azure-Terraformer/environment-terraform-azure/github | 1.0.3 | 31 | | [github\_identity](#module\_github\_identity) | Azure-Terraformer/github-credential/azuread | 1.0.10 | 32 | 33 | ## Resources 34 | 35 | | Name | Type | 36 | |------|------| 37 | | [azurerm_role_assignment.main](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | 38 | | [github_actions_variable.application_name](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_variable) | resource | 39 | | [github_branch.main](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch) | resource | 40 | | [github_branch_default.default](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch_default) | resource | 41 | | [github_repository.main](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository) | resource | 42 | | [random_string.main](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource | 43 | | [azuread_client_config.current](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/client_config) | data source | 44 | | [azurerm_subscription.main](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subscription) | data source | 45 | | [github_user.current](https://registry.terraform.io/providers/integrations/github/latest/docs/data-sources/user) | data source | 46 | 47 | ## Inputs 48 | 49 | | Name | Description | Type | Default | Required | 50 | |------|-------------|------|---------|:--------:| 51 | | [application\_name](#input\_application\_name) | The name of the application to be deployed. This name is used for resource identification and naming conventions within the infrastructure.

It's best to keep this short and simple while also ensuring it is easily identifiable and relatively unique within your organization (or at least within the Subscriptions you are targetting). | `string` | n/a | yes | 52 | | [commit\_user](#input\_commit\_user) | The user information for committing changes to the repository, including name and email. |
object({
name = string
email = string
})
| n/a | yes | 53 | | [delete\_branch\_on\_merge](#input\_delete\_branch\_on\_merge) | The setting that controls whether the GitHub repository deletes the feature branch automatically after the merge. | `bool` | `true` | no | 54 | | [environments](#input\_environments) | Configuration for each of the environments for this application.

Each Environment has a name which is supplied by the key of the map.
Each Environment has a long-lived environment on the specified `branch_name`.
Each Environment can be provisioned within the context of an Azure Subscription specified by `subscription_id`.
Each Environment can have its own Terraform State Backend configuration which consists of an Azure Storage Account and containers for both state files and plan files. |
map(object({
subscription_id = string
branch_name = string
backend = object({
resource_group_name = string
storage_account_name = string
state_container_name = string
plan_container_name = string
})
}))
| n/a | yes | 55 | | [github\_organization](#input\_github\_organization) | The GitHub organization under which the repository will be created. This should be the exact name of the GitHub organization. | `string` | n/a | yes | 56 | | [location](#input\_location) | Azure Region to provision the Jekyll Web Site into. | `string` | n/a | yes | 57 | | [repository\_description](#input\_repository\_description) | A brief description of the GitHub repository. This helps in understanding the purpose and scope of the repository.

This should describe the workload represented by the `application_name`. | `string` | n/a | yes | 58 | | [repository\_name](#input\_repository\_name) | The name of the GitHub repository to be created. This name should be unique within the specified GitHub organization.

The GitHub repository name should correlate to the `application_name` as it will contain the source code for the infrastructure
that is provisioned to Azure. | `string` | n/a | yes | 59 | | [repository\_visibility](#input\_repository\_visibility) | The visibility level of the GitHub repository. Accepted values are 'public', 'private', or 'internal'. Determines who can view and access the repository. | `string` | n/a | yes | 60 | | [terraform\_version](#input\_terraform\_version) | Specifies the version of Terraform to use for the deployment. | `string` | `"1.9.8"` | no | 61 | 62 | ## Outputs 63 | 64 | | Name | Description | 65 | |------|-------------| 66 | | [repository\_name](#output\_repository\_name) | n/a | 67 | -------------------------------------------------------------------------------- /modules/azure-jekyll-site/codebase.tf: -------------------------------------------------------------------------------- 1 | module "codebase" { 2 | 3 | source = "Azure-Terraformer/codebase-terraform-azure-jekyll-site/github" 4 | version = "1.0.10" 5 | 6 | repository = var.repository_name 7 | branch = github_branch.main.branch 8 | path = "src/terraform" 9 | commit_user = var.commit_user 10 | location = var.location 11 | environments = local.branch_name_map 12 | 13 | } 14 | -------------------------------------------------------------------------------- /modules/azure-jekyll-site/environments.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | extended_environments = { 3 | for key, value in var.environments : key => { 4 | subscription_id = value.subscription_id 5 | tenant_id = data.azuread_client_config.current.tenant_id 6 | client_id = module.github_identity[key].application.client_id 7 | branch_name = value.branch_name 8 | reviewers = [] 9 | backend = value.backend 10 | } 11 | } 12 | } 13 | 14 | module "github_environments" { 15 | source = "Azure-Terraformer/environment-terraform-azure/github" 16 | version = "1.0.3" 17 | 18 | repository_name = var.repository_name 19 | terraform_version = var.terraform_version 20 | terraform_working_directory = module.codebase.path 21 | delay_after_environment_creation = 10 22 | environments = local.extended_environments 23 | 24 | } 25 | -------------------------------------------------------------------------------- /modules/azure-jekyll-site/identity.tf: -------------------------------------------------------------------------------- 1 | data "azuread_client_config" "current" {} 2 | 3 | resource "random_string" "main" { 4 | length = 8 5 | upper = false 6 | special = false 7 | } 8 | 9 | module "github_identity" { 10 | 11 | source = "Azure-Terraformer/github-credential/azuread" 12 | version = "1.0.10" 13 | 14 | for_each = var.environments 15 | 16 | name = "${var.github_organization}-${var.repository_name}-${each.key}" 17 | github_organization = var.github_organization 18 | repository_name = var.repository_name 19 | entity_type = "environment" 20 | environment_name = each.key 21 | owners = [data.azuread_client_config.current.object_id] 22 | 23 | } 24 | 25 | data "azurerm_subscription" "main" { 26 | 27 | for_each = var.environments 28 | 29 | subscription_id = each.value.subscription_id 30 | 31 | } 32 | 33 | resource "azurerm_role_assignment" "main" { 34 | 35 | for_each = var.environments 36 | 37 | scope = data.azurerm_subscription.main[each.key].id 38 | role_definition_name = "Contributor" 39 | principal_id = module.github_identity[each.key].service_principal.object_id 40 | 41 | } 42 | -------------------------------------------------------------------------------- /modules/azure-jekyll-site/main.tf: -------------------------------------------------------------------------------- 1 | 2 | data "github_user" "current" { 3 | username = "" 4 | } 5 | 6 | resource "github_repository" "main" { 7 | 8 | name = var.repository_name 9 | description = var.repository_description 10 | 11 | visibility = var.repository_visibility 12 | delete_branch_on_merge = var.delete_branch_on_merge 13 | auto_init = true 14 | 15 | } 16 | 17 | resource "github_branch" "main" { 18 | repository = var.repository_name 19 | branch = "main" 20 | } 21 | 22 | resource "github_branch_default" "default" { 23 | repository = var.repository_name 24 | branch = github_branch.main.branch 25 | } 26 | 27 | resource "github_actions_variable" "application_name" { 28 | 29 | repository = var.repository_name 30 | variable_name = "APPLICATION_NAME" 31 | value = var.application_name 32 | 33 | } 34 | -------------------------------------------------------------------------------- /modules/azure-jekyll-site/outputs.tf: -------------------------------------------------------------------------------- 1 | output "repository_name" { 2 | value = github_repository.main.name 3 | } 4 | -------------------------------------------------------------------------------- /modules/azure-jekyll-site/pipelines.tf: -------------------------------------------------------------------------------- 1 | # Local to convert to map(string) 2 | locals { 3 | branch_name_map = tomap({ 4 | for key, value in var.environments : key => value.branch_name 5 | }) 6 | } 7 | 8 | module "gitflow" { 9 | 10 | source = "Azure-Terraformer/action-azure-application/github" 11 | version = "1.0.32" 12 | 13 | repository = var.repository_name 14 | branch = github_branch.main.branch 15 | commit_user = var.commit_user 16 | environments = local.branch_name_map 17 | 18 | # we don't want the actions firing when we start pushing commits 19 | depends_on = [module.codebase] 20 | 21 | } 22 | 23 | module "action_azure_login" { 24 | source = "Azure-Terraformer/action-azure-login-test/github" 25 | version = "1.0.1" 26 | 27 | repository = var.repository_name 28 | branch = github_branch.main.branch 29 | commit_user = var.commit_user 30 | 31 | } 32 | -------------------------------------------------------------------------------- /modules/azure-jekyll-site/variables.tf: -------------------------------------------------------------------------------- 1 | variable "application_name" { 2 | type = string 3 | description = < 6 | ## Requirements 7 | 8 | | Name | Version | 9 | |------|---------| 10 | | [azuread](#requirement\_azuread) | ~> 3.0.2 | 11 | | [azurerm](#requirement\_azurerm) | ~> 4.10.0 | 12 | | [github](#requirement\_github) | ~> 5.0 | 13 | 14 | ## Providers 15 | 16 | | Name | Version | 17 | |------|---------| 18 | | [azuread](#provider\_azuread) | ~> 3.0.2 | 19 | | [azurerm](#provider\_azurerm) | ~> 4.10.0 | 20 | | [github](#provider\_github) | ~> 5.0 | 21 | | [random](#provider\_random) | n/a | 22 | 23 | ## Modules 24 | 25 | | Name | Source | Version | 26 | |------|--------|---------| 27 | | [action\_azure\_login](#module\_action\_azure\_login) | Azure-Terraformer/action-azure-login-test/github | 1.0.1 | 28 | | [codebase](#module\_codebase) | Azure-Terraformer/codebase-terraform-azure-application/github | 1.0.4 | 29 | | [gitflow](#module\_gitflow) | Azure-Terraformer/action-azure-application/github | 1.0.32 | 30 | | [github\_environments](#module\_github\_environments) | Azure-Terraformer/environment-terraform-azure/github | 1.0.3 | 31 | | [github\_identity](#module\_github\_identity) | Azure-Terraformer/github-credential/azuread | 1.0.10 | 32 | 33 | ## Resources 34 | 35 | | Name | Type | 36 | |------|------| 37 | | [azurerm_role_assignment.main](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | 38 | | [github_actions_variable.application_name](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_variable) | resource | 39 | | [github_branch.main](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch) | resource | 40 | | [github_branch_default.default](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch_default) | resource | 41 | | [github_repository.main](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository) | resource | 42 | | [random_string.main](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource | 43 | | [azuread_client_config.current](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/client_config) | data source | 44 | | [azurerm_subscription.main](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subscription) | data source | 45 | | [github_user.current](https://registry.terraform.io/providers/integrations/github/latest/docs/data-sources/user) | data source | 46 | 47 | ## Inputs 48 | 49 | | Name | Description | Type | Default | Required | 50 | |------|-------------|------|---------|:--------:| 51 | | [application\_name](#input\_application\_name) | The name of the application to be deployed. This name is used for resource identification and naming conventions within the infrastructure.

It's best to keep this short and simple while also ensuring it is easily identifiable and relatively unique within your organization (or at least within the Subscriptions you are targetting). | `string` | n/a | yes | 52 | | [commit\_user](#input\_commit\_user) | The user information for committing changes to the repository, including name and email. |
object({
name = string
email = string
})
| n/a | yes | 53 | | [delete\_branch\_on\_merge](#input\_delete\_branch\_on\_merge) | The setting that controls whether the GitHub repository deletes the feature branch automatically after the merge. | `bool` | `true` | no | 54 | | [environments](#input\_environments) | Configuration for each of the environments for this application.

Each Environment has a name which is supplied by the key of the map.
Each Environment has a long-lived environment on the specified `branch_name`.
Each Environment can be provisioned within the context of an Azure Subscription specified by `subscription_id`.
Each Environment can have its own Terraform State Backend configuration which consists of an Azure Storage Account and containers for both state files and plan files. |
map(object({
subscription_id = string
branch_name = string
backend = object({
resource_group_name = string
storage_account_name = string
state_container_name = string
plan_container_name = string
})
}))
| n/a | yes | 55 | | [github\_organization](#input\_github\_organization) | The GitHub organization under which the repository will be created. This should be the exact name of the GitHub organization. | `string` | n/a | yes | 56 | | [repository\_description](#input\_repository\_description) | A brief description of the GitHub repository. This helps in understanding the purpose and scope of the repository.

This should describe the workload represented by the `application_name`. | `string` | n/a | yes | 57 | | [repository\_name](#input\_repository\_name) | The name of the GitHub repository to be created. This name should be unique within the specified GitHub organization.

The GitHub repository name should correlate to the `application_name` as it will contain the source code for the infrastructure
that is provisioned to Azure. | `string` | n/a | yes | 58 | | [repository\_visibility](#input\_repository\_visibility) | The visibility level of the GitHub repository. Accepted values are 'public', 'private', or 'internal'. Determines who can view and access the repository. | `string` | n/a | yes | 59 | | [terraform\_version](#input\_terraform\_version) | Specifies the version of Terraform to use for the deployment. | `string` | `"1.9.8"` | no | 60 | 61 | ## Outputs 62 | 63 | | Name | Description | 64 | |------|-------------| 65 | | [repository\_name](#output\_repository\_name) | n/a | 66 | -------------------------------------------------------------------------------- /modules/azure-starter-app/codebase.tf: -------------------------------------------------------------------------------- 1 | module "codebase" { 2 | 3 | source = "Azure-Terraformer/codebase-terraform-azure-application/github" 4 | version = "1.0.4" 5 | 6 | repository = var.repository_name 7 | branch = github_branch.main.branch 8 | commit_user = var.commit_user 9 | 10 | } 11 | //.terraform/modules/test.tests/azure-fn-app-stand-alone.environment.core.terraform_gitflow/files/.github/workflows/atat-push-terraform-apply.yaml 12 | -------------------------------------------------------------------------------- /modules/azure-starter-app/environments.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | extended_environments = { 3 | for key, value in var.environments : key => { 4 | subscription_id = value.subscription_id 5 | tenant_id = data.azuread_client_config.current.tenant_id 6 | client_id = module.github_identity[key].application.client_id 7 | branch_name = value.branch_name 8 | reviewers = [] 9 | backend = value.backend 10 | } 11 | } 12 | } 13 | 14 | module "github_environments" { 15 | source = "Azure-Terraformer/environment-terraform-azure/github" 16 | version = "1.0.3" 17 | 18 | repository_name = var.repository_name 19 | terraform_version = var.terraform_version 20 | terraform_working_directory = module.codebase.path 21 | delay_after_environment_creation = 10 22 | environments = local.extended_environments 23 | 24 | } 25 | -------------------------------------------------------------------------------- /modules/azure-starter-app/identity.tf: -------------------------------------------------------------------------------- 1 | data "azuread_client_config" "current" {} 2 | 3 | resource "random_string" "main" { 4 | length = 8 5 | upper = false 6 | special = false 7 | } 8 | 9 | module "github_identity" { 10 | 11 | source = "Azure-Terraformer/github-credential/azuread" 12 | version = "1.0.10" 13 | 14 | for_each = var.environments 15 | 16 | name = "${var.github_organization}-${var.repository_name}-${each.key}" 17 | github_organization = var.github_organization 18 | repository_name = var.repository_name 19 | entity_type = "environment" 20 | environment_name = each.key 21 | owners = [data.azuread_client_config.current.object_id] 22 | 23 | } 24 | 25 | data "azurerm_subscription" "main" { 26 | 27 | for_each = var.environments 28 | 29 | subscription_id = each.value.subscription_id 30 | 31 | } 32 | 33 | resource "azurerm_role_assignment" "main" { 34 | 35 | for_each = var.environments 36 | 37 | scope = data.azurerm_subscription.main[each.key].id 38 | role_definition_name = "Contributor" 39 | principal_id = module.github_identity[each.key].service_principal.object_id 40 | 41 | } 42 | -------------------------------------------------------------------------------- /modules/azure-starter-app/main.tf: -------------------------------------------------------------------------------- 1 | 2 | data "github_user" "current" { 3 | username = "" 4 | } 5 | 6 | resource "github_repository" "main" { 7 | 8 | name = var.repository_name 9 | description = var.repository_description 10 | 11 | visibility = var.repository_visibility 12 | delete_branch_on_merge = var.delete_branch_on_merge 13 | auto_init = true 14 | 15 | } 16 | 17 | resource "github_branch" "main" { 18 | repository = var.repository_name 19 | branch = "main" 20 | } 21 | 22 | resource "github_branch_default" "default" { 23 | repository = var.repository_name 24 | branch = github_branch.main.branch 25 | } 26 | 27 | resource "github_actions_variable" "application_name" { 28 | 29 | repository = var.repository_name 30 | variable_name = "APPLICATION_NAME" 31 | value = var.application_name 32 | 33 | } 34 | -------------------------------------------------------------------------------- /modules/azure-starter-app/outputs.tf: -------------------------------------------------------------------------------- 1 | output "repository_name" { 2 | value = github_repository.main.name 3 | } 4 | -------------------------------------------------------------------------------- /modules/azure-starter-app/pipelines.tf: -------------------------------------------------------------------------------- 1 | # Local to convert to map(string) 2 | locals { 3 | branch_name_map = tomap({ 4 | for key, value in var.environments : key => value.branch_name 5 | }) 6 | } 7 | 8 | module "gitflow" { 9 | 10 | source = "Azure-Terraformer/action-azure-application/github" 11 | version = "1.0.32" 12 | 13 | repository = var.repository_name 14 | branch = github_branch.main.branch 15 | commit_user = var.commit_user 16 | environments = local.branch_name_map 17 | 18 | # we don't want the actions firing when we start pushing commits 19 | depends_on = [module.codebase] 20 | 21 | } 22 | 23 | module "action_azure_login" { 24 | source = "Azure-Terraformer/action-azure-login-test/github" 25 | version = "1.0.1" 26 | 27 | repository = var.repository_name 28 | branch = github_branch.main.branch 29 | commit_user = var.commit_user 30 | 31 | } 32 | -------------------------------------------------------------------------------- /modules/azure-starter-app/variables.tf: -------------------------------------------------------------------------------- 1 | variable "application_name" { 2 | type = string 3 | description = < 6 | ## Requirements 7 | 8 | | Name | Version | 9 | |------|---------| 10 | | [azuread](#requirement\_azuread) | ~> 3.0.2 | 11 | | [azurerm](#requirement\_azurerm) | ~> 4.10.0 | 12 | | [github](#requirement\_github) | ~> 5.0 | 13 | 14 | ## Providers 15 | 16 | | Name | Version | 17 | |------|---------| 18 | | [azuread](#provider\_azuread) | ~> 3.0.2 | 19 | | [azurerm](#provider\_azurerm) | ~> 4.10.0 | 20 | | [github](#provider\_github) | ~> 5.0 | 21 | | [random](#provider\_random) | n/a | 22 | 23 | ## Modules 24 | 25 | | Name | Source | Version | 26 | |------|--------|---------| 27 | | [action\_azure\_login](#module\_action\_azure\_login) | Azure-Terraformer/action-azure-login-test/github | 1.0.1 | 28 | | [codebase](#module\_codebase) | Azure-Terraformer/codebase-terraform-azure-vm-app/github | 1.0.16 | 29 | | [gitflow](#module\_gitflow) | Azure-Terraformer/action-azure-application/github | 1.0.32 | 30 | | [github\_environments](#module\_github\_environments) | Azure-Terraformer/environment-terraform-azure/github | 1.0.3 | 31 | | [github\_identity](#module\_github\_identity) | Azure-Terraformer/github-credential/azuread | 1.0.10 | 32 | 33 | ## Resources 34 | 35 | | Name | Type | 36 | |------|------| 37 | | [azurerm_role_assignment.main](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | 38 | | [github_actions_environment_variable.gallery_name](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_environment_variable) | resource | 39 | | [github_actions_environment_variable.gallery_resource_group](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_environment_variable) | resource | 40 | | [github_actions_environment_variable.managed_image_destination](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_environment_variable) | resource | 41 | | [github_actions_variable.application_name](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_variable) | resource | 42 | | [github_branch.main](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch) | resource | 43 | | [github_branch_default.default](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch_default) | resource | 44 | | [github_repository.main](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository) | resource | 45 | | [random_string.main](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource | 46 | | [azuread_client_config.current](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/client_config) | data source | 47 | | [azurerm_subscription.main](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subscription) | data source | 48 | | [github_user.current](https://registry.terraform.io/providers/integrations/github/latest/docs/data-sources/user) | data source | 49 | 50 | ## Inputs 51 | 52 | | Name | Description | Type | Default | Required | 53 | |------|-------------|------|---------|:--------:| 54 | | [application\_name](#input\_application\_name) | The name of the application to be deployed. This name is used for resource identification and naming conventions within the infrastructure.

It's best to keep this short and simple while also ensuring it is easily identifiable and relatively unique within your organization (or at least within the Subscriptions you are targetting). | `string` | n/a | yes | 55 | | [base\_address\_space](#input\_base\_address\_space) | n/a | `string` | n/a | yes | 56 | | [commit\_user](#input\_commit\_user) | The user information for committing changes to the repository, including name and email. |
object({
name = string
email = string
})
| n/a | yes | 57 | | [delay\_after\_environment\_creation](#input\_delay\_after\_environment\_creation) | GitHub Environments have a glitch that causes them to not be available immediately after creation is reported. Environment variables
will fail unless there is some time granted to allow for the Environment creation to complete. This setting adds a fixed amount of time
after the creation of the environment before provisioning additional resources. | `number` | `10` | no | 58 | | [delete\_branch\_on\_merge](#input\_delete\_branch\_on\_merge) | The setting that controls whether the GitHub repository deletes the feature branch automatically after the merge. | `bool` | `true` | no | 59 | | [environments](#input\_environments) | Configuration for each of the environments for this application.

Each Environment has a name which is supplied by the key of the map.
Each Environment has a long-lived environment on the specified `branch_name`.
Each Environment can be provisioned within the context of an Azure Subscription specified by `subscription_id`.
Each Environment can have its own Terraform State Backend configuration which consists of an Azure Storage Account and containers for both state files and plan files. |
map(object({
subscription_id = string
branch_name = string
backend = object({
resource_group_name = string
storage_account_name = string
state_container_name = string
plan_container_name = string
})
gallery = object({
name = string
resource_group = string
})
managed_image_destination = string
}))
| n/a | yes | 60 | | [github\_organization](#input\_github\_organization) | The GitHub organization under which the repository will be created. This should be the exact name of the GitHub organization. | `string` | n/a | yes | 61 | | [image\_names](#input\_image\_names) | n/a | `list(string)` | n/a | yes | 62 | | [location](#input\_location) | The primary Azure region where the Azure Functions Core Environment will be provisioned." | `string` | n/a | yes | 63 | | [packer\_version](#input\_packer\_version) | n/a | `string` | n/a | yes | 64 | | [repository\_description](#input\_repository\_description) | A brief description of the GitHub repository. This helps in understanding the purpose and scope of the repository.

This should describe the workload represented by the `application_name`. | `string` | n/a | yes | 65 | | [repository\_name](#input\_repository\_name) | The name of the GitHub repository to be created. This name should be unique within the specified GitHub organization.

The GitHub repository name should correlate to the `application_name` as it will contain the source code for the infrastructure
that is provisioned to Azure. | `string` | n/a | yes | 66 | | [repository\_visibility](#input\_repository\_visibility) | The visibility level of the GitHub repository. Accepted values are 'public', 'private', or 'internal'. Determines who can view and access the repository. | `string` | n/a | yes | 67 | | [terraform\_version](#input\_terraform\_version) | Specifies the version of Terraform to use. Defaults to '1.9.8'. | `string` | `"1.9.8"` | no | 68 | | [vm\_size](#input\_vm\_size) | n/a | `string` | n/a | yes | 69 | 70 | ## Outputs 71 | 72 | No outputs. 73 | -------------------------------------------------------------------------------- /modules/azure-vm-app/codebase.tf: -------------------------------------------------------------------------------- 1 | module "codebase" { 2 | 3 | source = "Azure-Terraformer/codebase-terraform-azure-vm-app/github" 4 | version = "1.0.16" 5 | 6 | repository = var.repository_name 7 | branch = github_branch.main.branch 8 | commit_user = var.commit_user 9 | primary_location = var.location 10 | image_names = var.image_names 11 | vm_size = var.vm_size 12 | packer_version = var.packer_version 13 | base_address_space = var.base_address_space 14 | 15 | } 16 | -------------------------------------------------------------------------------- /modules/azure-vm-app/environments.tf: -------------------------------------------------------------------------------- 1 | 2 | locals { 3 | extended_environments = { 4 | for key, value in var.environments : key => { 5 | subscription_id = value.subscription_id 6 | tenant_id = data.azuread_client_config.current.tenant_id 7 | client_id = module.github_identity[key].application.client_id 8 | branch_name = value.branch_name 9 | reviewers = [] 10 | backend = value.backend 11 | } 12 | } 13 | } 14 | 15 | module "github_environments" { 16 | source = "Azure-Terraformer/environment-terraform-azure/github" 17 | version = "1.0.3" 18 | 19 | repository_name = var.repository_name 20 | terraform_version = var.terraform_version 21 | terraform_working_directory = module.codebase.terraform_path 22 | delay_after_environment_creation = 10 23 | environments = local.extended_environments 24 | 25 | depends_on = [github_branch_default.default] 26 | 27 | } 28 | 29 | resource "github_actions_environment_variable" "gallery_name" { 30 | 31 | for_each = local.extended_environments 32 | 33 | repository = var.repository_name 34 | environment = each.key 35 | variable_name = "PACKER_COMPUTE_GALLERY_NAME" 36 | value = var.environments[each.key].gallery.name 37 | 38 | depends_on = [module.github_environments] 39 | 40 | } 41 | 42 | resource "github_actions_environment_variable" "gallery_resource_group" { 43 | 44 | for_each = var.environments 45 | 46 | repository = var.repository_name 47 | environment = each.key 48 | variable_name = "PACKER_COMPUTE_GALLERY_RESOURCE_GROUP" 49 | value = var.environments[each.key].gallery.resource_group 50 | 51 | depends_on = [module.github_environments] 52 | 53 | } 54 | 55 | 56 | resource "github_actions_environment_variable" "managed_image_destination" { 57 | 58 | for_each = var.environments 59 | 60 | repository = var.repository_name 61 | environment = each.key 62 | variable_name = "PACKER_MANAGED_IMAGE_DESTINATION" 63 | value = var.environments[each.key].managed_image_destination 64 | 65 | depends_on = [module.github_environments] 66 | 67 | } 68 | -------------------------------------------------------------------------------- /modules/azure-vm-app/identity.tf: -------------------------------------------------------------------------------- 1 | data "azuread_client_config" "current" {} 2 | 3 | resource "random_string" "main" { 4 | length = 8 5 | upper = false 6 | special = false 7 | } 8 | 9 | module "github_identity" { 10 | 11 | source = "Azure-Terraformer/github-credential/azuread" 12 | version = "1.0.10" 13 | 14 | for_each = var.environments 15 | 16 | name = "${var.github_organization}-${var.repository_name}-${each.key}" 17 | github_organization = var.github_organization 18 | repository_name = var.repository_name 19 | entity_type = "environment" 20 | environment_name = each.key 21 | owners = [data.azuread_client_config.current.object_id] 22 | 23 | } 24 | 25 | data "azurerm_subscription" "main" { 26 | 27 | for_each = var.environments 28 | 29 | subscription_id = each.value.subscription_id 30 | 31 | } 32 | 33 | resource "azurerm_role_assignment" "main" { 34 | 35 | for_each = var.environments 36 | 37 | scope = data.azurerm_subscription.main[each.key].id 38 | role_definition_name = "Owner" 39 | principal_id = module.github_identity[each.key].service_principal.object_id 40 | 41 | } 42 | -------------------------------------------------------------------------------- /modules/azure-vm-app/main.tf: -------------------------------------------------------------------------------- 1 | 2 | data "github_user" "current" { 3 | username = "" 4 | } 5 | 6 | resource "github_repository" "main" { 7 | 8 | name = var.repository_name 9 | description = var.repository_description 10 | 11 | visibility = var.repository_visibility 12 | delete_branch_on_merge = var.delete_branch_on_merge 13 | auto_init = true 14 | 15 | } 16 | 17 | resource "github_branch" "main" { 18 | repository = var.repository_name 19 | branch = "main" 20 | } 21 | 22 | resource "github_branch_default" "default" { 23 | repository = var.repository_name 24 | branch = github_branch.main.branch 25 | } 26 | 27 | resource "github_actions_variable" "application_name" { 28 | 29 | repository = var.repository_name 30 | variable_name = "APPLICATION_NAME" 31 | value = var.application_name 32 | 33 | depends_on = [github_branch_default.default] 34 | 35 | } 36 | -------------------------------------------------------------------------------- /modules/azure-vm-app/pipelines.tf: -------------------------------------------------------------------------------- 1 | # Local to convert to map(string) 2 | locals { 3 | branch_name_map = tomap({ 4 | for key, value in var.environments : key => value.branch_name 5 | }) 6 | } 7 | 8 | module "gitflow" { 9 | 10 | source = "Azure-Terraformer/action-azure-application/github" 11 | version = "1.0.32" 12 | 13 | repository = var.repository_name 14 | branch = github_branch.main.branch 15 | commit_user = var.commit_user 16 | environments = local.branch_name_map 17 | 18 | # we don't want the actions firing when we start pushing commits 19 | depends_on = [module.codebase] 20 | 21 | } 22 | 23 | module "action_azure_login" { 24 | source = "Azure-Terraformer/action-azure-login-test/github" 25 | version = "1.0.1" 26 | 27 | repository = var.repository_name 28 | branch = github_branch.main.branch 29 | commit_user = var.commit_user 30 | 31 | } 32 | -------------------------------------------------------------------------------- /modules/azure-vm-app/variables.tf: -------------------------------------------------------------------------------- 1 | variable "application_name" { 2 | type = string 3 | description = < 6 | ## Requirements 7 | 8 | | Name | Version | 9 | |------|---------| 10 | | [azuread](#requirement\_azuread) | ~> 3.0.2 | 11 | | [azurerm](#requirement\_azurerm) | ~> 4.10.0 | 12 | | [github](#requirement\_github) | ~> 5.0 | 13 | 14 | ## Providers 15 | 16 | | Name | Version | 17 | |------|---------| 18 | | [azuread](#provider\_azuread) | ~> 3.0.2 | 19 | | [azurerm](#provider\_azurerm) | ~> 4.10.0 | 20 | | [github](#provider\_github) | ~> 5.0 | 21 | | [random](#provider\_random) | n/a | 22 | 23 | ## Modules 24 | 25 | | Name | Source | Version | 26 | |------|--------|---------| 27 | | [action\_azure\_login](#module\_action\_azure\_login) | Azure-Terraformer/action-azure-login-test/github | 1.0.1 | 28 | | [codebase](#module\_codebase) | Azure-Terraformer/codebase-terraform-azure-vm-core/github | 1.0.3 | 29 | | [gitflow](#module\_gitflow) | Azure-Terraformer/action-azure-application/github | 1.0.32 | 30 | | [github\_environments](#module\_github\_environments) | Azure-Terraformer/environment-terraform-azure/github | 1.0.3 | 31 | | [github\_identity](#module\_github\_identity) | Azure-Terraformer/github-credential/azuread | 1.0.10 | 32 | 33 | ## Resources 34 | 35 | | Name | Type | 36 | |------|------| 37 | | [azurerm_role_assignment.main](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | 38 | | [github_actions_variable.application_name](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_variable) | resource | 39 | | [github_branch.main](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch) | resource | 40 | | [github_branch_default.default](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch_default) | resource | 41 | | [github_repository.main](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository) | resource | 42 | | [random_string.main](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource | 43 | | [azuread_client_config.current](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/client_config) | data source | 44 | | [azurerm_subscription.main](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subscription) | data source | 45 | | [github_user.current](https://registry.terraform.io/providers/integrations/github/latest/docs/data-sources/user) | data source | 46 | 47 | ## Inputs 48 | 49 | | Name | Description | Type | Default | Required | 50 | |------|-------------|------|---------|:--------:| 51 | | [application\_name](#input\_application\_name) | The name of the application to be deployed. This name is used for resource identification and naming conventions within the infrastructure.

It's best to keep this short and simple while also ensuring it is easily identifiable and relatively unique within your organization (or at least within the Subscriptions you are targetting). | `string` | n/a | yes | 52 | | [commit\_user](#input\_commit\_user) | The user information for committing changes to the repository, including name and email. |
object({
name = string
email = string
})
| n/a | yes | 53 | | [delay\_after\_environment\_creation](#input\_delay\_after\_environment\_creation) | GitHub Environments have a glitch that causes them to not be available immediately after creation is reported. Environment variables
will fail unless there is some time granted to allow for the Environment creation to complete. This setting adds a fixed amount of time
after the creation of the environment before provisioning additional resources. | `number` | `10` | no | 54 | | [delete\_branch\_on\_merge](#input\_delete\_branch\_on\_merge) | The setting that controls whether the GitHub repository deletes the feature branch automatically after the merge. | `bool` | `true` | no | 55 | | [environments](#input\_environments) | Configuration for each of the environments for this application.

Each Environment has a name which is supplied by the key of the map.
Each Environment has a long-lived environment on the specified `branch_name`.
Each Environment can be provisioned within the context of an Azure Subscription specified by `subscription_id`.
Each Environment can have its own Terraform State Backend configuration which consists of an Azure Storage Account and containers for both state files and plan files. |
map(object({
subscription_id = string
branch_name = string
backend = object({
resource_group_name = string
storage_account_name = string
state_container_name = string
plan_container_name = string
})
}))
| n/a | yes | 56 | | [github\_organization](#input\_github\_organization) | The GitHub organization under which the repository will be created. This should be the exact name of the GitHub organization. | `string` | n/a | yes | 57 | | [location](#input\_location) | The primary Azure region where the Azure Functions Core Environment will be provisioned." | `string` | n/a | yes | 58 | | [repository\_description](#input\_repository\_description) | A brief description of the GitHub repository. This helps in understanding the purpose and scope of the repository.

This should describe the workload represented by the `application_name`. | `string` | n/a | yes | 59 | | [repository\_name](#input\_repository\_name) | The name of the GitHub repository to be created. This name should be unique within the specified GitHub organization.

The GitHub repository name should correlate to the `application_name` as it will contain the source code for the infrastructure
that is provisioned to Azure. | `string` | n/a | yes | 60 | | [repository\_visibility](#input\_repository\_visibility) | The visibility level of the GitHub repository. Accepted values are 'public', 'private', or 'internal'. Determines who can view and access the repository. | `string` | n/a | yes | 61 | | [terraform\_version](#input\_terraform\_version) | Specifies the version of Terraform to use. Defaults to '1.9.8'. | `string` | `"1.9.8"` | no | 62 | 63 | ## Outputs 64 | 65 | No outputs. 66 | -------------------------------------------------------------------------------- /modules/azure-vm-core/codebase.tf: -------------------------------------------------------------------------------- 1 | module "codebase" { 2 | 3 | source = "Azure-Terraformer/codebase-terraform-azure-vm-core/github" 4 | version = "1.0.3" 5 | 6 | repository = var.repository_name 7 | branch = github_branch.main.branch 8 | commit_user = var.commit_user 9 | location = var.location 10 | 11 | } 12 | -------------------------------------------------------------------------------- /modules/azure-vm-core/environments.tf: -------------------------------------------------------------------------------- 1 | 2 | locals { 3 | extended_environments = { 4 | for key, value in var.environments : key => { 5 | subscription_id = value.subscription_id 6 | tenant_id = data.azuread_client_config.current.tenant_id 7 | client_id = module.github_identity[key].application.client_id 8 | branch_name = value.branch_name 9 | reviewers = [] 10 | backend = value.backend 11 | } 12 | } 13 | } 14 | 15 | module "github_environments" { 16 | source = "Azure-Terraformer/environment-terraform-azure/github" 17 | version = "1.0.3" 18 | 19 | repository_name = var.repository_name 20 | terraform_version = var.terraform_version 21 | terraform_working_directory = module.codebase.path 22 | delay_after_environment_creation = 10 23 | environments = local.extended_environments 24 | 25 | depends_on = [github_branch_default.default] 26 | 27 | } 28 | -------------------------------------------------------------------------------- /modules/azure-vm-core/identity.tf: -------------------------------------------------------------------------------- 1 | data "azuread_client_config" "current" {} 2 | 3 | resource "random_string" "main" { 4 | length = 8 5 | upper = false 6 | special = false 7 | } 8 | 9 | module "github_identity" { 10 | 11 | source = "Azure-Terraformer/github-credential/azuread" 12 | version = "1.0.10" 13 | 14 | for_each = var.environments 15 | 16 | name = "${var.github_organization}-${var.repository_name}-${each.key}" 17 | github_organization = var.github_organization 18 | repository_name = var.repository_name 19 | entity_type = "environment" 20 | environment_name = each.key 21 | owners = [data.azuread_client_config.current.object_id] 22 | 23 | } 24 | 25 | data "azurerm_subscription" "main" { 26 | 27 | for_each = var.environments 28 | 29 | subscription_id = each.value.subscription_id 30 | 31 | } 32 | 33 | resource "azurerm_role_assignment" "main" { 34 | 35 | for_each = var.environments 36 | 37 | scope = data.azurerm_subscription.main[each.key].id 38 | role_definition_name = "Owner" 39 | principal_id = module.github_identity[each.key].service_principal.object_id 40 | 41 | } 42 | -------------------------------------------------------------------------------- /modules/azure-vm-core/main.tf: -------------------------------------------------------------------------------- 1 | 2 | data "github_user" "current" { 3 | username = "" 4 | } 5 | 6 | resource "github_repository" "main" { 7 | 8 | name = var.repository_name 9 | description = var.repository_description 10 | 11 | visibility = var.repository_visibility 12 | delete_branch_on_merge = var.delete_branch_on_merge 13 | auto_init = true 14 | 15 | } 16 | 17 | resource "github_branch" "main" { 18 | repository = var.repository_name 19 | branch = "main" 20 | } 21 | 22 | resource "github_branch_default" "default" { 23 | repository = var.repository_name 24 | branch = github_branch.main.branch 25 | } 26 | 27 | resource "github_actions_variable" "application_name" { 28 | 29 | repository = var.repository_name 30 | variable_name = "APPLICATION_NAME" 31 | value = var.application_name 32 | 33 | depends_on = [github_branch_default.default] 34 | 35 | } 36 | -------------------------------------------------------------------------------- /modules/azure-vm-core/pipelines.tf: -------------------------------------------------------------------------------- 1 | # Local to convert to map(string) 2 | locals { 3 | branch_name_map = tomap({ 4 | for key, value in var.environments : key => value.branch_name 5 | }) 6 | } 7 | 8 | module "gitflow" { 9 | 10 | source = "Azure-Terraformer/action-azure-application/github" 11 | version = "1.0.32" 12 | 13 | repository = var.repository_name 14 | branch = github_branch.main.branch 15 | commit_user = var.commit_user 16 | environments = local.branch_name_map 17 | 18 | # we don't want the actions firing when we start pushing commits 19 | depends_on = [module.codebase] 20 | 21 | } 22 | 23 | module "action_azure_login" { 24 | source = "Azure-Terraformer/action-azure-login-test/github" 25 | version = "1.0.1" 26 | 27 | repository = var.repository_name 28 | branch = github_branch.main.branch 29 | commit_user = var.commit_user 30 | 31 | } 32 | -------------------------------------------------------------------------------- /modules/azure-vm-core/variables.tf: -------------------------------------------------------------------------------- 1 | variable "application_name" { 2 | type = string 3 | description = < 2 | ## Requirements 3 | 4 | | Name | Version | 5 | |------|---------| 6 | | [azuread](#requirement\_azuread) | ~> 3.0.2 | 7 | | [azurerm](#requirement\_azurerm) | ~> 4.10.0 | 8 | | [github](#requirement\_github) | ~> 5.0 | 9 | 10 | ## Providers 11 | 12 | | Name | Version | 13 | |------|---------| 14 | | [random](#provider\_random) | n/a | 15 | 16 | ## Modules 17 | 18 | No modules. 19 | 20 | ## Resources 21 | 22 | | Name | Type | 23 | |------|------| 24 | | [random_string.repository_name](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource | 25 | 26 | ## Inputs 27 | 28 | No inputs. 29 | 30 | ## Outputs 31 | 32 | | Name | Description | 33 | |------|-------------| 34 | | [repository\_name\_suffix](#output\_repository\_name\_suffix) | n/a | 35 | -------------------------------------------------------------------------------- /tests/setup/main.tf: -------------------------------------------------------------------------------- 1 | resource "random_string" "repository_name" { 2 | length = 6 3 | special = false 4 | upper = false 5 | } 6 | 7 | output "repository_name_suffix" { 8 | value = random_string.repository_name.result 9 | } 10 | -------------------------------------------------------------------------------- /tests/setup/terraform.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | github = { 4 | source = "integrations/github" 5 | version = "~> 5.0" 6 | } 7 | azurerm = { 8 | source = "hashicorp/azurerm" 9 | version = "~> 4.10.0" 10 | } 11 | azuread = { 12 | source = "hashicorp/azuread" 13 | version = "~> 3.0.2" 14 | } 15 | } 16 | } 17 | --------------------------------------------------------------------------------