Terraform の AzAPI を使って Azure Communication Services Email を作成してみた

Azure でメール送信といえば SendGrid か、365 のメールボックスを使っていました。久しぶりにライトにメール送信をする必要があり、Azure Communication Services Email を作成してみました。Terraform の azurerm には、一部の Azure Communication Services しか用意されておらず、今回は AzAPI を使用しています。

## Azure Communication Services Email を作成する Terraform コード

```terraform:main.tf
terraform {
  required_providers {
    azurerm = {
      source = "hashicorp/azurerm"
    }
    azapi = {
      source = "azure/azapi"
    }
  }
}

provider "azurerm" {
  features {}
}

provider "azapi" {}

variable "prefix" {
  type    = string
  default = "mnrlabo"
}

data "azurerm_client_config" "current" {}

data "azapi_resource" "rg" {
  type      = "Microsoft.Resources/resourceGroups@2022-09-01"
  name      = "${var.prefix}-rg"
  parent_id = "/subscriptions/${data.azurerm_client_config.current.subscription_id}"
}

resource "azapi_resource" "ecs" {
  type      = "Microsoft.Communication/EmailServices@2023-03-31"
  name      = var.prefix
  location  = "global"
  parent_id = data.azapi_resource.rg.id

  body = jsonencode(
    {
      properties = {
        dataLocation = "Japan"
      }
    }
  )
}

resource "azapi_resource" "domains" {
  type      = "Microsoft.Communication/emailServices/domains@2023-03-31"
  name      = "AzureManagedDomain"
  parent_id = azapi_resource.ecs.id
  location  = "global"

  body = jsonencode(
    {
      properties = {
        domainManagement       = "AzureManaged"
        userEngagementTracking = "Disabled"
      }
    }
  )

  response_export_values = ["properties.fromSenderDomain"]
}

resource "azapi_resource" "cs" {
  type      = "Microsoft.Communication/CommunicationServices@2023-03-31"
  name      = var.prefix
  location  = "global"
  parent_id = data.azapi_resource.rg.id

  body = jsonencode(
    {
      properties = {
        dataLocation  = "Japan"
        linkedDomains = [azapi_resource.domains.id]
      }
    }
  )
}

output "fromSenderDomain" {
  value = jsondecode(azapi_resource.domains.output).properties.fromSenderDomain
}
```

`fromSenderDomain` のアウトプットを追加して、あとでコマンドライン利用する想定です。

## メールを送信するスクリプト

```python:send-email.py
import os
from azure.communication.email import EmailClient

AZURE_COMMUNICATION_STRING = os.environ.get("AZURE_COMMUNICATION_STRING")
AZURE_COMMUNICATION_SENDER = os.environ.get("AZURE_COMMUNICATION_SENDER")
AZURE_COMMUNICATION_TO = os.environ.get("AZURE_COMMUNICATION_TO")
AZURE_COMMUNICATION_SUBJECT = os.environ.get("AZURE_COMMUNICATION_SUBJECT")
AZURE_COMMUNICATION_BODY = os.environ.get("AZURE_COMMUNICATION_BODY")

try:
    email_client = EmailClient.from_connection_string(AZURE_COMMUNICATION_STRING)

    message = {
        "content": {
            "subject": AZURE_COMMUNICATION_SUBJECT,
            "plainText": AZURE_COMMUNICATION_BODY
        },
        "recipients": {
            "to": [
                {
                    "address": AZURE_COMMUNICATION_TO
                }
            ]
        },
        "senderAddress": AZURE_COMMUNICATION_SENDER
    }

    email_client.begin_send(message)
except Exception as ex:
    print('Exception:')
    print(ex)
```

## メールを送信して動作確認

```bash:bash
export AZURE_COMMUNICATION_STRING=$(az communication list-key -n mnrlabo -g mnrlabo-rg --query primaryConnectionString -o tsv)
export AZURE_COMMUNICATION_SENDER='donotreply@'$(terraform output fromSenderDomain | jq -r .)
export AZURE_COMMUNICATION_TO=$(az account show --query user.name --output tsv)
export AZURE_COMMUNICATION_SUBJECT="test subject"
export AZURE_COMMUNICATION_BODY="test body"

pip install azure-communication-email

python send-email.py
```

## 参考

https://registry.terraform.io/providers/Azure/azapi/latest/docs/resources/azapi_resource

https://learn.microsoft.com/ja-jp/rest/api/communication/resourcemanager/communication-services