This documentation covers the deployment of the infrastructure to host the app.
The infrastructure is managed using Terraform.
The state is stored remotely in encrypted Azure storage.
Terraform workspaces are used to separate environments.
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.
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 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 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"
We can use Homebrew 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 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 <id>
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
Each environment will need it's own tfvars
file.
Copy the terraform.tfvars.example
to environment-name.tfvars
and modify the contents as required
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.
Name | Version |
---|---|
terraform | ~> 1.9 |
azapi | ~> 1.13 |
azurerm | ~> 4.0 |
statuscake | ~> 2.1 |
No providers.
Name | Source | Version |
---|---|---|
azure_container_apps_hosting | github.com/DFE-Digital/terraform-azurerm-container-apps-hosting | v1.16.2 |
azurerm_key_vault | github.com/DFE-Digital/terraform-azurerm-key-vault-tfvars | v0.5.1 |
statuscake-tls-monitor | github.com/dfe-digital/terraform-statuscake-tls-monitor | v0.1.5 |
No resources.
Name | Description | Type | Default | Required |
---|---|---|---|---|
azure_client_id | Service Principal Client ID | string |
n/a | yes |
azure_client_secret | Service Principal Client Secret | string |
n/a | yes |
azure_location | Azure location in which to launch resources. | string |
n/a | yes |
azure_subscription_id | Service Principal Subscription ID | string |
n/a | yes |
azure_tenant_id | Service Principal Tenant ID | string |
n/a | yes |
cdn_frontdoor_custom_domains | Azure CDN Front Door custom domains. If they are within the DNS zone (optionally created), the Validation TXT records and ALIAS/CNAME records will be created | list(string) |
[] |
no |
cdn_frontdoor_enable_rate_limiting | Enable CDN Front Door Rate Limiting. This will create a WAF policy, and CDN security policy. For pricing reasons, there will only be one WAF policy created. | bool |
n/a | yes |
cdn_frontdoor_forwarding_protocol | Azure CDN Front Door forwarding protocol | string |
"HttpsOnly" |
no |
cdn_frontdoor_host_redirects | CDN Front Door host redirects [{ "from" = "example.com", "to" = "www.example.com" }] |
list(map(string)) |
[] |
no |
cdn_frontdoor_origin_fqdn_override | Manually specify the hostname that the CDN Front Door should target. Defaults to the Container App FQDN | string |
"" |
no |
cdn_frontdoor_origin_host_header_override | Manually specify the host header that the CDN sends to the target. Defaults to the recieved host header. Set to null to set it to the host_name (cdn_frontdoor_origin_fqdn_override ) |
string |
"" |
no |
cdn_frontdoor_rate_limiting_duration_in_minutes | CDN Front Door rate limiting duration in minutes | number |
5 |
no |
cdn_frontdoor_rate_limiting_threshold | Maximum number of concurrent requests before Rate Limiting policy is applied | number |
n/a | yes |
cdn_frontdoor_vdp_destination_hostname | Requires 'enable_cdn_frontdoor_vdp_redirects' to be set to 'true'. Hostname to redirect security.txt and thanks.txt to | string |
"vdp.security.education.gov.uk" |
no |
container_apps_allow_ips_inbound | Restricts access to the Container Apps by creating a network security group rule that only allow inbound traffic from the provided list of IPs | list(string) |
[] |
no |
container_command | Container command | list(any) |
n/a | yes |
container_health_probe_protocol | Use HTTPS or a TCP connection for the Container liveness probe | string |
n/a | yes |
container_min_replicas | Container min replicas | number |
1 |
no |
container_port | Container port | number |
3000 |
no |
container_scale_http_concurrency | When the number of concurrent HTTP requests exceeds this value, then another replica is added. Replicas continue to add to the pool up to the max-replicas amount. | number |
10 |
no |
container_secret_environment_variables | Container secret environment variables | map(string) |
n/a | yes |
custom_container_apps | Custom container apps, by default deployed within the container app environment managed by this module. | map(object({ |
{} |
no |
dns_mx_records | DNS MX records to add to the DNS Zone | map( |
{} |
no |
dns_ns_records | DNS NS records to add to the DNS zone | map( |
{} |
no |
dns_txt_records | DNS TXT records to add to the DNS zone | map( |
{} |
no |
dns_zone_domain_name | DNS zone domain name. If specified, records will automatically be created to point to the CDN. | string |
n/a | yes |
enable_cdn_frontdoor | Enable Azure CDN FrontDoor. This will use the Container Apps endpoint as the origin. | bool |
n/a | yes |
enable_cdn_frontdoor_health_probe | Enable CDN Front Door health probe | bool |
false |
no |
enable_cdn_frontdoor_vdp_redirects | Deploy redirects for security.txt and thanks.txt to an external Vulnerability Disclosure Program service | bool |
true |
no |
enable_container_app_file_share | Create an Azure Storage Account and File Share to be mounted to the Container Apps | bool |
false |
no |
enable_container_health_probe | Enable liveness probes for the Container | bool |
n/a | yes |
enable_container_registry | Set to true to create a container registry | bool |
false |
no |
enable_dns_zone | Conditionally create a DNS zone | bool |
n/a | yes |
enable_event_hub | Send Azure Container App logs to an Event Hub sink | bool |
false |
no |
enable_health_insights_api | Deploys a Function App that exposes the last 3 HTTP Web Tests via an API endpoint. 'enable_app_insights_integration' and 'enable_monitoring' must be set to 'true'. | bool |
false |
no |
enable_logstash_consumer | Create an Event Hub consumer group for Logstash | bool |
false |
no |
enable_monitoring | Create an App Insights instance and notification group for the Container App | bool |
n/a | yes |
enable_mssql_database | Set to true to create an Azure SQL server/database, with aprivate endpoint within the virtual network | bool |
n/a | yes |
enable_redis_cache | Set to true to create a Redis Cache | bool |
n/a | yes |
enable_worker_container | Conditionally launch a worker container. This container uses the same image and environment variables as a the default container app, but allows a different container commanmd to be ran. The worker container does not expose any ports. | bool |
n/a | yes |
environment | Environment name. Will be used along with project_name as a prefix for all resources. |
string |
n/a | yes |
eventhub_export_log_analytics_table_names | List of Log Analytics table names that you want to export to Event Hub. See https://learn.microsoft.com/en-gb/azure/azure-monitor/logs/logs-data-export?tabs=portal#supported-tables for a list of supported tables | list(string) |
[] |
no |
existing_logic_app_workflow | Name, and Resource Group of an existing Logic App Workflow. Leave empty to create a new Resource | object({ |
{ |
no |
existing_network_watcher_name | Use an existing network watcher to add flow logs. | string |
n/a | yes |
existing_network_watcher_resource_group_name | Existing network watcher resource group. | string |
n/a | yes |
health_insights_api_cors_origins | List of hostnames that are permitted to contact the Health insights API | list(string) |
[ |
no |
health_insights_api_ipv4_allow_list | List of IPv4 addresses that are permitted to contact the Health insights API | list(string) |
[] |
no |
image_name | Image name | string |
n/a | yes |
key_vault_access_ipv4 | List of IPv4 Addresses that are permitted to access the Key Vault | list(string) |
n/a | yes |
monitor_email_receivers | A list of email addresses that should be notified by monitoring alerts | list(string) |
n/a | yes |
monitor_endpoint_healthcheck | Specify a route that should be monitored for a 200 OK status | string |
n/a | yes |
mssql_azuread_admin_object_id | Object ID of a User within Azure AD that you want to assign as the SQL Server Administrator | string |
n/a | yes |
mssql_azuread_admin_username | Username of a User within Azure AD that you want to assign as the SQL Server Administrator | string |
n/a | yes |
mssql_database_name | The name of the MSSQL database to create. Must be set if enable_mssql_database is true |
string |
n/a | yes |
mssql_firewall_ipv4_allow_list | A list of IPv4 Addresses that require remote access to the MSSQL Server | map(object({ |
{} |
no |
mssql_managed_identity_assign_role | Assign the 'Storage Blob Data Contributor' Role to the SQL Server User-Assigned Managed Identity. Note: If you do not have 'Microsoft.Authorization/roleAssignments/write' permission, you will need to manually assign the 'Storage Blob Data Contributor' Role to the identity | bool |
false |
no |
mssql_server_admin_password | The local administrator password for the MSSQL server | string |
n/a | yes |
mssql_server_public_access_enabled | Enable public internet access to your MSSQL instance. Be sure to specify 'mssql_firewall_ipv4_allow_list' to restrict inbound connections | bool |
false |
no |
mssql_sku_name | Specifies the name of the SKU used by the database | string |
"Basic" |
no |
project_name | Project name. Will be used along with environment as a prefix for all resources. |
string |
n/a | yes |
redis_cache_sku | Redis Cache SKU | string |
"Basic" |
no |
redis_config | Overrides for Redis Cache Configuration options | object({ |
{} |
no |
registry_admin_enabled | Do you want to enable access key based authentication for your Container Registry? | bool |
false |
no |
registry_managed_identity_assign_role | Assign the 'AcrPull' Role to the Container App User-Assigned Managed Identity. Note: If you do not have 'Microsoft.Authorization/roleAssignments/write' permission, you will need to manually assign the 'AcrPull' Role to the identity | bool |
false |
no |
registry_server | Container registry server | string |
"" |
no |
registry_use_managed_identity | Create a User-Assigned Managed Identity for the Container App. Note: If you do not have 'Microsoft.Authorization/roleAssignments/write' permission, you will need to manually assign the 'AcrPull' Role to the identity | bool |
true |
no |
statuscake_api_token | API token for StatusCake | string |
"00000000000000000000000000000" |
no |
statuscake_contact_group_email_addresses | List of email address that should receive notifications from StatusCake | list(string) |
[] |
no |
statuscake_contact_group_integrations | List of Integration IDs to connect to your Contact Group | list(string) |
[] |
no |
statuscake_contact_group_name | Name of the contact group in StatusCake | string |
"" |
no |
statuscake_monitored_resource_addresses | The URLs to perform TLS checks on | list(string) |
[] |
no |
storage_account_ipv4_allow_list | A list of public IPv4 address to grant access to the Storage Account | list(string) |
[] |
no |
storage_account_public_access_enabled | Should the Azure Storage Account have Public visibility? | bool |
false |
no |
tags | Tags to be applied to all resources | map(string) |
n/a | yes |
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 | Virtual network address space CIDR | string |
n/a | yes |
worker_container_command | Container command for the Worker container. enable_worker_container must be set to true for this to have any effect. |
list(string) |
n/a | yes |
worker_container_max_replicas | Worker container max replicas | number |
1 |
no |
No outputs.