variable "env" {
description = "Environment"
default = "dev"
}
variable "app_name" {
description = "Application name"
}
variable "subdomain" {
description = "Subdomain for the DNS record"
}
variable "dns_zone" {
description = "DNS Zone name"
}
variable "dns_resource_group" {
description = "DNS resource group"
}
variable "location" {
description = "Location"
default = "Brazil South"
}
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>3.80.0"
}
azapi = {
source = "azure/azapi"
}
}
backend "remote" {}
}
provider "azurerm" {
features {}
}
provider "azapi" {}
resource "azurerm_resource_group" "rg" {
name = "${upper(var.env)}-${upper(var.app_name)}-RG"
location = var.location
}
resource "azurerm_log_analytics_workspace" "logs" {
name = "${upper(var.env)}-${upper(var.app_name)}-logs"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}
resource "azurerm_container_app_environment" "app_env" {
name = "${upper(var.env)}-${upper(var.app_name)}-CAE"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
log_analytics_workspace_id = azurerm_log_analytics_workspace.logs.id
}
resource "azurerm_container_app" "app" {
name = "${lower(var.env)}-${lower(var.app_name)}-ca"
container_app_environment_id = azurerm_container_app_environment.app_env.id
resource_group_name = azurerm_resource_group.rg.name
revision_mode = "Single"
template {
container {
name = "${var.env}-${var.app_name}-container"
image = "mcr.microsoft.com/azuredocs/containerapps-helloworld:latest"
cpu = 0.25
memory = "0.5Gi"
}
}
ingress {
transport = "http"
target_port = 80
external_enabled = true
allow_insecure_connections = false
traffic_weight {
percentage = 100
latest_revision = true
}
}
lifecycle {
ignore_changes = [ingress.0.custom_domain] // Required to not delete the custom domain created in dns.tf
}
}
output "default_app_url" {
value = azurerm_container_app.app.ingress[0].fqdn
}
output "app_url" {
value = time_sleep.dns_propagation.triggers["url"]
}
data "azurerm_dns_zone" "dns" {
name = var.dns_zone
resource_group_name = var.dns_resource_group
}
resource "azurerm_dns_cname_record" "cname_record" {
name = var.subdomain
zone_name = data.azurerm_dns_zone.dns.name
resource_group_name = data.azurerm_dns_zone.dns.resource_group_name
ttl = 3600
record = azurerm_container_app.app.ingress[0].fqdn
}
data "azapi_resource" "app_verification_id" {
resource_id = azurerm_container_app_environment.app_env.id
type = "Microsoft.App/managedEnvironments@2023-05-01"
response_export_values = ["properties.customDomainConfiguration.customDomainVerificationId"]
}
locals {
verificationId = jsondecode(data.azapi_resource.app_verification_id.output).properties.customDomainConfiguration.customDomainVerificationId
}
resource "azurerm_dns_txt_record" "txt_record" {
name = "asuid.${var.subdomain}"
zone_name = data.azurerm_dns_zone.dns.name
resource_group_name = data.azurerm_dns_zone.dns.resource_group_name
ttl = 3600
record {
value = local.verificationId
}
}
resource "time_sleep" "dns_propagation" {
create_duration = "60s"
depends_on = [azurerm_dns_txt_record.txt_record, azurerm_dns_cname_record.cname_record]
triggers = {
url = "${azurerm_dns_cname_record.cname_record.name}.${data.azurerm_dns_zone.dns.name}",
verificationId = local.verificationId,
record = azurerm_dns_cname_record.cname_record.record,
}
}
// azurerm can't create a managed TLS certificate - see https://github.com/hashicorp/terraform-provider-azurerm/issues/21866
// The following resources are the workaround
resource "azapi_update_resource" "custom_domain" {
type = "Microsoft.App/containerApps@2023-05-01"
resource_id = azurerm_container_app.app.id
body = jsonencode({
properties = {
configuration = {
ingress = {
customDomains = [
{
bindingType = "Disabled",
name = time_sleep.dns_propagation.triggers["url"],
}
]
}
}
}
})
}
resource "azapi_resource" "managed_certificate" {
depends_on = [time_sleep.dns_propagation, azapi_update_resource.custom_domain]
type = "Microsoft.App/ManagedEnvironments/managedCertificates@2023-05-01"
name = "${lower(var.env)}-${lower(var.app_name)}-cert"
parent_id = azurerm_container_app_environment.app_env.id
location = azurerm_resource_group.rg.location
body = jsonencode({
properties = {
subjectName = time_sleep.dns_propagation.triggers["url"]
domainControlValidation = "CNAME"
}
})
response_export_values = ["*"]
}
resource "azapi_update_resource" "custom_domain_binding" {
type = "Microsoft.App/containerApps@2023-05-01"
resource_id = azurerm_container_app.app.id
body = jsonencode({
properties = {
configuration = {
ingress = {
customDomains = [
{
bindingType = "SniEnabled",
name = time_sleep.dns_propagation.triggers["url"],
certificateId = jsondecode(azapi_resource.managed_certificate.output).id
}
]
}
}
}
})
}