From 565ca93959dbd62e7071f0505d189fb7b9ad6a45 Mon Sep 17 00:00:00 2001
From: Ash Davies <3853061+DrizzlyOwl@users.noreply.github.com>
Date: Tue, 10 Jan 2023 15:33:24 +0000
Subject: [PATCH] Added Terraform Hosting Module
---
.gitignore | 11 ++
terraform/.terraform-docs.yml | 26 ++++
terraform/.terraform-version | 1 +
terraform/.terraform.lock.hcl | 80 ++++++++++++
terraform/Brewfile | 6 +
terraform/README.md | 173 ++++++++++++++++++++++++++
terraform/backend.tf | 3 +
terraform/backend.vars.example | 5 +
terraform/container-apps-hosting.tf | 18 +++
terraform/data.tf | 7 ++
terraform/key-vault-tfvars-secrets.tf | 54 ++++++++
terraform/locals.tf | 14 +++
terraform/providers.tf | 6 +
terraform/terraform.tfvars.example | 16 +++
terraform/variables.tf | 60 +++++++++
terraform/versions.tf | 13 ++
16 files changed, 493 insertions(+)
create mode 100644 terraform/.terraform-docs.yml
create mode 100644 terraform/.terraform-version
create mode 100644 terraform/.terraform.lock.hcl
create mode 100644 terraform/Brewfile
create mode 100644 terraform/README.md
create mode 100644 terraform/backend.tf
create mode 100644 terraform/backend.vars.example
create mode 100644 terraform/container-apps-hosting.tf
create mode 100644 terraform/data.tf
create mode 100644 terraform/key-vault-tfvars-secrets.tf
create mode 100644 terraform/locals.tf
create mode 100644 terraform/providers.tf
create mode 100644 terraform/terraform.tfvars.example
create mode 100644 terraform/variables.tf
create mode 100644 terraform/versions.tf
diff --git a/.gitignore b/.gitignore
index 6bcd493d9..d5ced6436 100644
--- a/.gitignore
+++ b/.gitignore
@@ -148,6 +148,8 @@ _NCrunch*
# node_modules
CypressTests/node_modules
+# Homebrew
+Brewfile.lock.json
# Environment variables
.env
@@ -156,3 +158,12 @@ CypressTests/node_modules
.env.*.local
!.env.development.local.example
!.env.database.example
+
+### Terraform
+.terraformrc*
+terraform.rc*
+*.tfstate*
+*.tfvars*
+!terraform.tfvars.example
+.terraform/
+backend.vars
diff --git a/terraform/.terraform-docs.yml b/terraform/.terraform-docs.yml
new file mode 100644
index 000000000..a6917808f
--- /dev/null
+++ b/terraform/.terraform-docs.yml
@@ -0,0 +1,26 @@
+---
+formatter: "markdown table"
+version: "~> 0.16"
+settings:
+ anchor: true
+ default: true
+ description: false
+ escape: true
+ hide-empty: false
+ html: true
+ indent: 2
+ lockfile: true
+ read-comments: true
+ required: true
+ sensitive: true
+ type: true
+sort:
+ enabled: true
+ by: name
+output:
+ file: README.md
+ mode: inject
+ template: |-
+
+ {{ .Content }}
+
diff --git a/terraform/.terraform-version b/terraform/.terraform-version
new file mode 100644
index 000000000..3336003dc
--- /dev/null
+++ b/terraform/.terraform-version
@@ -0,0 +1 @@
+1.3.7
diff --git a/terraform/.terraform.lock.hcl b/terraform/.terraform.lock.hcl
new file mode 100644
index 000000000..5e0a872e5
--- /dev/null
+++ b/terraform/.terraform.lock.hcl
@@ -0,0 +1,80 @@
+# This file is maintained automatically by "terraform init".
+# Manual edits may be lost in future updates.
+
+provider "registry.terraform.io/azure/azapi" {
+ version = "1.2.0"
+ constraints = ">= 1.1.0"
+ hashes = [
+ "h1:RTlIi2Ja1PeMmQ2OVlXQrJulcSXiX+OJYq5K65G8Eeo=",
+ "zh:0dcca6970347a67c2192be251ea1e98b5df50a8f7cb352adbf2fbdb6cbe02b03",
+ "zh:306545eedf8a6dbc64d34fdc9fe104b874d45f9ab5ca1232e9670e36376f7d04",
+ "zh:31484f398b08b10b86af2d89c89ae13e513bf738dfe90e2ff3dc564332b8c180",
+ "zh:36fda73c39c56495bfda7fa746863357ab8284d27724d809130c03fada62301f",
+ "zh:40075df5e753032bd9a7d2698e762d355524f56a4a7e8df65489d44273aa0e32",
+ "zh:6b7667b74eaa0e0884423704e48bb3468e465fd99de108e64b93c9e26c8c4b0d",
+ "zh:8248289b744cdeb9d3e20dedd13a66ba3225f8efd6694a556f69acf16825f45f",
+ "zh:86d864576520952d74b0ac5d92ed9efe09894c5405cbadddf1d95c2b39c4a514",
+ "zh:9b5d3c6a753cc57be31ba6a6e14b571ebbaa5c0c14791ef20a975b9c15c65252",
+ "zh:a522991b3d8dfb3b7073c3cd44fb6b8d9957c006ad304e299342e29d11bde854",
+ "zh:b1f931cd16e5a8235131b11c4a0d93f122d22dec597534da1bac03324e564fb1",
+ "zh:fa1f470859b8c5dc778561cbf0749b0c002cfa13bbd3574a2574ea682368d73f",
+ ]
+}
+
+provider "registry.terraform.io/hashicorp/azuread" {
+ version = "2.31.0"
+ hashes = [
+ "h1:0D8+cQBlCyA50NiiTJwNDK9QjKfZsjuHgXTFRlhIZyg=",
+ "zh:02a64db03707cc6970ab28a1da00d7fa011cc54e8a7806209f31bd8aad1794e1",
+ "zh:077ffce8135a57544ec3c227bbe0ee5f6ca649223bd1dc0bbbd31d3fdf616830",
+ "zh:0a369de6132edb0f4a69f2aa472b23f9bb5c430a3d539146d1c18d4cc7b12c7f",
+ "zh:14bfc5f2354c1389eb7ed8bf5a5eaadc9940e18c2dd15058eb9b48ea5c37ae66",
+ "zh:1c3e89cf19118fc07d7b04257251fc9897e722c16e0a0df7b07fcd261f8c12e7",
+ "zh:5629f020ac3409ad34a39e221fb2e63f82948c3eb936508331d5a7f870556e9d",
+ "zh:5b419eb59fa4e0b9c520c5cd5028f236bce6d9ab701c5ccca23cc040d3d690c4",
+ "zh:5e7e6207fd58a3e9ba54b7333169a3e3ea693c25c8f477622536600a8a09a3f1",
+ "zh:a9a552ad36d7a3db4554c6fbc716cf8631328331ea6188eddb4038b4c213ff46",
+ "zh:aee812d33916e5fdfb4d58ce74af0f3b2a7a58dbfb5ec8e0b42b5780ceff5414",
+ "zh:ce46738cd1909675b980bb90b9c3d919a4d1d655b4296082b86b6622ce818f7a",
+ "zh:db02dbe5ce139610688b354b15eb934f9f67ab32d6c5d63690dce6f9b8d90904",
+ ]
+}
+
+provider "registry.terraform.io/hashicorp/azurerm" {
+ version = "3.38.0"
+ constraints = ">= 3.35.0"
+ hashes = [
+ "h1:Isa/rY8+4+DCatuYgmDT4TYkcp/he7RrfR6jyhrm7hQ=",
+ "zh:08df48bdaf162bf3da7ac2b09147d44f94fae6f3cfd97d6cf9c45cb7c1c36a44",
+ "zh:220b68a3f819777872281974e6621527698575096c3a2ef78cb0aabf28665161",
+ "zh:25db1128a96599ffbcc7e865579bec7c009cb4e7f7731e0e30d261ab02cc38d5",
+ "zh:279444db11f570b837143559e5df7453bd8aeda4e22a9879a5a1a795bf6612a3",
+ "zh:2d506b6b865f6d5143e54e139d9a61b18bdcc8b9485d2bc7237e95a53a9c7ed9",
+ "zh:6ddb2cbcdf15b432508fe00ee7863f6d51a136db1746e7af03bec8ce2a09bad3",
+ "zh:96b664a716678923ce0f9828eaad22b5353669fa5013ea39b7b8081a77988b85",
+ "zh:a9ca583b219a3daba171ca11908547abb1b09453934950aacff17ae8b51d0ff0",
+ "zh:aa497620c82afab7819736180f0a56b76da6f3e23bd0580383fda98104b4e5c2",
+ "zh:ab9e9f3c35288d0bd615024f213e46d16d639c281f7d850b21971b530d08e231",
+ "zh:b164a0ddb30b64c35f13dad0aa9701a4e3eb24dc8165a3e794c499f1e9070b99",
+ "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
+ ]
+}
+
+provider "registry.terraform.io/hashicorp/null" {
+ version = "3.2.1"
+ hashes = [
+ "h1:ydA0/SNRVB1o95btfshvYsmxA+jZFRZcvKzZSB+4S1M=",
+ "zh:58ed64389620cc7b82f01332e27723856422820cfd302e304b5f6c3436fb9840",
+ "zh:62a5cc82c3b2ddef7ef3a6f2fedb7b9b3deff4ab7b414938b08e51d6e8be87cb",
+ "zh:63cff4de03af983175a7e37e52d4bd89d990be256b16b5c7f919aff5ad485aa5",
+ "zh:74cb22c6700e48486b7cabefa10b33b801dfcab56f1a6ac9b6624531f3d36ea3",
+ "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
+ "zh:79e553aff77f1cfa9012a2218b8238dd672ea5e1b2924775ac9ac24d2a75c238",
+ "zh:a1e06ddda0b5ac48f7e7c7d59e1ab5a4073bbcf876c73c0299e4610ed53859dc",
+ "zh:c37a97090f1a82222925d45d84483b2aa702ef7ab66532af6cbcfb567818b970",
+ "zh:e4453fbebf90c53ca3323a92e7ca0f9961427d2f0ce0d2b65523cc04d5d999c2",
+ "zh:e80a746921946d8b6761e77305b752ad188da60688cfd2059322875d363be5f5",
+ "zh:fbdb892d9822ed0e4cb60f2fedbdbb556e4da0d88d3b942ae963ed6ff091e48f",
+ "zh:fca01a623d90d0cad0843102f9b8b9fe0d3ff8244593bd817f126582b52dd694",
+ ]
+}
diff --git a/terraform/Brewfile b/terraform/Brewfile
new file mode 100644
index 000000000..000ace386
--- /dev/null
+++ b/terraform/Brewfile
@@ -0,0 +1,6 @@
+brew "tfenv"
+brew "terraform-docs"
+brew "tfsec"
+brew "az"
+brew "coreutils"
+brew "jq"
diff --git a/terraform/README.md b/terraform/README.md
new file mode 100644
index 000000000..ac9477b80
--- /dev/null
+++ b/terraform/README.md
@@ -0,0 +1,173 @@
+This documentation covers the deployment of the infrastructure to host the app.
+
+## Azure infrastructure
+
+The infrastructure is managed using [Terraform](https://www.terraform.io/).
+The state is stored remotely in encrypted Azure storage.
+[Terraform workspaces](https://www.terraform.io/docs/state/workspaces.html) are used to separate environments.
+
+#### Configuring the storage backend
+
+The Terraform state is stored remotely in Azure, this allows multiple team members to
+make changes and means the state file is backed up. The state file contains
+sensitive information so access to it should be restricted, and it should be stored
+encrypted at rest.
+
+##### Create a new storage backend
+
+This step only needs to be done once per project (eg. not per environment).
+If it has already been created, obtain the storage backend attributes and skip to the next step.
+
+The [Azure tutorial](https://docs.microsoft.com/en-us/azure/developer/terraform/store-state-in-azure-storage) outlines the steps to create a storage account and container for the state file. You will need:
+
+- resource_group_name: The name of the resource group used for the Azure Storage account.
+- storage_account_name: The name of the Azure Storage account.
+- container_name: The name of the blob container.
+- key: The name of the state store file to be created.
+
+##### Create a backend configuration file
+
+Create a new file named `backend.vars` with the following content:
+
+```
+resource_group_name = [the name of the Azure resource group]
+storage_account_name = [the name of the Azure Storage account]
+container_name = [the name of the blob container]
+key = "terraform.tstate"
+```
+
+##### Install dependencies
+
+We can use [Homebrew](https://brew.sh) to install the dependecies we need to deploy the infrastructure (eg. tfenv, Azure cli).
+These are listed in the `Brewfile`
+
+to install, run:
+
+```
+$ brew bundle
+```
+
+##### Log into azure with the Azure CLI
+
+Log in to your account:
+
+```
+$ az login
+```
+
+Confirm which account you are currently using:
+
+```
+$ az account show
+```
+
+To list the available subscriptions, run:
+
+```
+$ az account list
+```
+
+Then if needed, switch to it using the 'id':
+
+```
+$ az account set --subscription
+```
+
+##### Initialise Terraform
+
+Install the required terraform version with the Terraform version manager `tfenv`:
+
+```
+$ tfenv install
+```
+
+Initialize Terraform to download the required Terraform modules and configure the remote state backend
+to use the settings you specified in the previous step.
+
+`$ terraform init -backend-config=backend.vars`
+
+##### Create a Terraform variables file
+
+Each environment will need it's own `tfvars` file.
+
+Copy the `terraform.tfvars.example` to `environment-name.tfvars` and modify the contents as required
+
+##### Create the infrastructure
+
+Now Terraform has been initialised you can create a workspace if needed:
+
+`$ terraform workspace new staging`
+
+Or to check what workspaces already exist:
+
+`$ terraform workspace list`
+
+Switch to the new or existing workspace:
+
+`$ terraform workspace select staging`
+
+Plan the changes:
+
+`$ terraform plan -var-file=staging.tfvars`
+
+Terraform will ask you to provide any variables not specified in an `*.auto.tfvars` file.
+Now you can run:
+
+`$ terraform apply -var-file=staging.tfvars`
+
+If everything looks good, answer `yes` and wait for the new infrastructure to be created.
+
+##### Azure resources
+
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.3.6 |
+| [azapi](#requirement\_azapi) | >= 1.1.0 |
+| [azurerm](#requirement\_azurerm) | >= 3.35.0 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [azuread](#provider\_azuread) | 2.31.0 |
+| [azurerm](#provider\_azurerm) | 3.38.0 |
+
+## Modules
+
+| Name | Source | Version |
+|------|--------|---------|
+| [azure\_container\_apps\_hosting](#module\_azure\_container\_apps\_hosting) | github.com/DFE-Digital/terraform-azurerm-container-apps-hosting | v0.12.0 |
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [azurerm_key_vault.tfvars](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault) | resource |
+| [azurerm_key_vault_secret.tfvars](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret) | resource |
+| [azuread_user.key_vault_access](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/user) | data source |
+| [azurerm_client_config.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config) | data source |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [azure\_location](#input\_azure\_location) | Azure location in which to launch resources. | `string` | n/a | yes |
+| [container\_command](#input\_container\_command) | Container command | `list(any)` | n/a | yes |
+| [container\_secret\_environment\_variables](#input\_container\_secret\_environment\_variables) | Container secret environment variables | `map(string)` | n/a | yes |
+| [enable\_cdn\_frontdoor](#input\_enable\_cdn\_frontdoor) | Enable Azure CDN FrontDoor. This will use the Container Apps endpoint as the origin. | `bool` | n/a | yes |
+| [enable\_container\_registry](#input\_enable\_container\_registry) | Set to true to create a container registry | `bool` | n/a | yes |
+| [environment](#input\_environment) | Environment name. Will be used along with `project_name` as a prefix for all resources. | `string` | n/a | yes |
+| [image\_name](#input\_image\_name) | Image name | `string` | n/a | yes |
+| [key\_vault\_access\_users](#input\_key\_vault\_access\_users) | List of users that require access to the Key Vault where tfvars are stored. This should be a list of User Principle Names (Found in Active Directory) that need to run terraform | `list(string)` | n/a | yes |
+| [project\_name](#input\_project\_name) | Project name. Will be used along with `environment` as a prefix for all resources. | `string` | n/a | yes |
+| [tags](#input\_tags) | Tags to be applied to all resources | `map(string)` | n/a | yes |
+| [tfvars\_filename](#input\_tfvars\_filename) | tfvars filename. This file is uploaded and stored encrupted within Key Vault, to ensure that the latest tfvars are stored in a shared place. | `string` | n/a | yes |
+| [virtual\_network\_address\_space](#input\_virtual\_network\_address\_space) | Virtual network address space CIDR | `string` | n/a | yes |
+
+## Outputs
+
+No outputs.
+
diff --git a/terraform/backend.tf b/terraform/backend.tf
new file mode 100644
index 000000000..6602f2060
--- /dev/null
+++ b/terraform/backend.tf
@@ -0,0 +1,3 @@
+terraform {
+ backend "azurerm" {}
+}
diff --git a/terraform/backend.vars.example b/terraform/backend.vars.example
new file mode 100644
index 000000000..bc2382128
--- /dev/null
+++ b/terraform/backend.vars.example
@@ -0,0 +1,5 @@
+resource_group_name = ""
+storage_account_name = ""
+container_name = ""
+key = "terraform.tstate"
+subscription_id = ""
diff --git a/terraform/container-apps-hosting.tf b/terraform/container-apps-hosting.tf
new file mode 100644
index 000000000..d90a4b8e4
--- /dev/null
+++ b/terraform/container-apps-hosting.tf
@@ -0,0 +1,18 @@
+module "azure_container_apps_hosting" {
+ source = "github.com/DFE-Digital/terraform-azurerm-container-apps-hosting?ref=v0.12.0"
+
+ environment = local.environment
+ project_name = local.project_name
+ azure_location = local.azure_location
+ tags = local.tags
+
+ virtual_network_address_space = local.virtual_network_address_space
+
+ enable_container_registry = local.enable_container_registry
+
+ image_name = local.image_name
+ container_command = local.container_command
+ container_secret_environment_variables = local.container_secret_environment_variables
+
+ enable_cdn_frontdoor = local.enable_cdn_frontdoor
+}
diff --git a/terraform/data.tf b/terraform/data.tf
new file mode 100644
index 000000000..8fc2edce3
--- /dev/null
+++ b/terraform/data.tf
@@ -0,0 +1,7 @@
+data "azurerm_client_config" "current" {}
+
+data "azuread_user" "key_vault_access" {
+ for_each = local.key_vault_access_users
+
+ user_principal_name = each.value
+}
diff --git a/terraform/key-vault-tfvars-secrets.tf b/terraform/key-vault-tfvars-secrets.tf
new file mode 100644
index 000000000..cf6ae3538
--- /dev/null
+++ b/terraform/key-vault-tfvars-secrets.tf
@@ -0,0 +1,54 @@
+resource "azurerm_key_vault" "tfvars" {
+ name = "${local.environment}${local.project_name}-tfvars"
+ location = module.azure_container_apps_hosting.azurerm_resource_group_default.location
+ resource_group_name = module.azure_container_apps_hosting.azurerm_resource_group_default.name
+ tenant_id = data.azurerm_client_config.current.tenant_id
+ sku_name = "standard"
+ soft_delete_retention_days = 7
+ enable_rbac_authorization = false
+
+ dynamic "access_policy" {
+ for_each = data.azuread_user.key_vault_access
+
+ content {
+ tenant_id = data.azurerm_client_config.current.tenant_id
+ object_id = access_policy.value["object_id"]
+
+ key_permissions = [
+ "Create",
+ "Get",
+ ]
+
+ secret_permissions = [
+ "Set",
+ "Get",
+ "Delete",
+ "Purge",
+ "Recover",
+ "List",
+ ]
+ }
+ }
+
+ # It won't be possible to add/manage a network acl for this
+ # vault, as it will need to be accessable for multiple people.
+ # tfsec:ignore:azure-keyvault-specify-network-acl
+ network_acls {
+ bypass = "None"
+ default_action = "Allow"
+ }
+
+ purge_protection_enabled = true
+
+ tags = local.tags
+}
+
+# Expiry doesn't need to be set, as this is just used as a way to
+# store and share the tfvars
+# tfsec:ignore:azure-keyvault-ensure-secret-expiry
+resource "azurerm_key_vault_secret" "tfvars" {
+ name = "${local.environment}${local.project_name}-tfvars"
+ value = base64encode(file(local.tfvars_filename))
+ key_vault_id = azurerm_key_vault.tfvars.id
+ content_type = "text/plain+base64"
+}
diff --git a/terraform/locals.tf b/terraform/locals.tf
new file mode 100644
index 000000000..83f2a04c5
--- /dev/null
+++ b/terraform/locals.tf
@@ -0,0 +1,14 @@
+locals {
+ environment = var.environment
+ project_name = var.project_name
+ azure_location = var.azure_location
+ tags = var.tags
+ virtual_network_address_space = var.virtual_network_address_space
+ enable_container_registry = var.enable_container_registry
+ image_name = var.image_name
+ container_command = var.container_command
+ container_secret_environment_variables = var.container_secret_environment_variables
+ enable_cdn_frontdoor = var.enable_cdn_frontdoor
+ key_vault_access_users = toset(var.key_vault_access_users)
+ tfvars_filename = var.tfvars_filename
+}
diff --git a/terraform/providers.tf b/terraform/providers.tf
new file mode 100644
index 000000000..12bf2de93
--- /dev/null
+++ b/terraform/providers.tf
@@ -0,0 +1,6 @@
+provider "azurerm" {
+ features {}
+ skip_provider_registration = true
+}
+
+provider "azapi" {}
diff --git a/terraform/terraform.tfvars.example b/terraform/terraform.tfvars.example
new file mode 100644
index 000000000..a0c7e6600
--- /dev/null
+++ b/terraform/terraform.tfvars.example
@@ -0,0 +1,16 @@
+environment = "development"
+project_name = "myproject"
+azure_location = "uksouth"
+enable_container_registry = true
+image_name = "myimage"
+enable_mssql_database = true
+enable_redis_cache = true
+mssql_server_admin_password = "S3crEt"
+mssql_database_name = "mydatabase"
+container_command = ["/bin/bash", "-c", "echo hello && sleep 86400"]
+container_environment_variables = {
+ "ASPNETCORE_ENVIRONMENT" = "production"
+}
+key_vault_access_users = [
+ "someone_example.com#EXT#@tenantname.onmicrosoft.com",
+]
diff --git a/terraform/variables.tf b/terraform/variables.tf
new file mode 100644
index 000000000..9c9d2a912
--- /dev/null
+++ b/terraform/variables.tf
@@ -0,0 +1,60 @@
+variable "environment" {
+ description = "Environment name. Will be used along with `project_name` as a prefix for all resources."
+ type = string
+}
+
+variable "key_vault_access_users" {
+ description = "List of users that require access to the Key Vault where tfvars are stored. This should be a list of User Principle Names (Found in Active Directory) that need to run terraform"
+ type = list(string)
+}
+
+variable "tfvars_filename" {
+ description = "tfvars filename. This file is uploaded and stored encrupted within Key Vault, to ensure that the latest tfvars are stored in a shared place."
+ type = string
+}
+
+variable "project_name" {
+ description = "Project name. Will be used along with `environment` as a prefix for all resources."
+ type = string
+}
+
+variable "azure_location" {
+ description = "Azure location in which to launch resources."
+ type = string
+}
+
+variable "tags" {
+ description = "Tags to be applied to all resources"
+ type = map(string)
+}
+
+variable "virtual_network_address_space" {
+ description = "Virtual network address space CIDR"
+ type = string
+}
+
+variable "enable_container_registry" {
+ description = "Set to true to create a container registry"
+ type = bool
+}
+
+variable "image_name" {
+ description = "Image name"
+ type = string
+}
+
+variable "container_command" {
+ description = "Container command"
+ type = list(any)
+}
+
+variable "container_secret_environment_variables" {
+ description = "Container secret environment variables"
+ type = map(string)
+ sensitive = true
+}
+
+variable "enable_cdn_frontdoor" {
+ description = "Enable Azure CDN FrontDoor. This will use the Container Apps endpoint as the origin."
+ type = bool
+}
diff --git a/terraform/versions.tf b/terraform/versions.tf
new file mode 100644
index 000000000..94c960a56
--- /dev/null
+++ b/terraform/versions.tf
@@ -0,0 +1,13 @@
+terraform {
+ required_version = ">= 1.3.6"
+ required_providers {
+ azurerm = {
+ source = "hashicorp/azurerm"
+ version = ">= 3.35.0"
+ }
+ azapi = {
+ source = "Azure/azapi"
+ version = ">= 1.1.0"
+ }
+ }
+}