Route53ホストゾーンにDNSレコードをTerraformで作成するのに必要な最小権限

2021.08.30

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Route53ホストゾーンにDNSレコードを一つ作るのをTerraformでやる機会がありました。今回訳あってTerraformが使うIAM Roleに必要以上に権限を持たせたくなかったので、最低限の権限だけ持たせました。そのIAM Policyを共有します。

TerraformでRoute53ホストゾーンにDNSレコードを作るコード

以下のroute53_recordリソースを使います。

resource "aws_route53_record" "hostname" {
  zone_id = local.hosted_zone_id
  name    = local.fqdn
  type    = "A"
  ttl     = "300"
  records = [local.ip]
}

最小権限のIAM Policyはこれだ

本題のPolicyです。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "route53:GetHostedZone",
                "route53:ChangeResourceRecordSets",
                "route53:ListResourceRecordSets"
            ],
            "Resource": [
                "arn:aws:route53:::hostedzone/(hostzoneid)"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "route53:GetChange"
            ],
            "Resource": [
                "arn:aws:route53:::change/*"
            ],
            "Effect": "Allow"
        }
    ]
}

解説

route53:GetHostedZone

特定のRoute53ホストゾーンの情報を取得するのに必要な権限。

route53:ChangeResourceRecordSets

これが今回の核となる権限ですね。特定のRoute53ホストゾーン内のレコードセットを作成、変更、削除するための権限です。

route53:ListResourceRecordSets

特定のRoute53ホストゾーン下のレコード一覧を返す権限です。

route53:GetChange

一番「なんやこれ?」と思った権限です。
route53:ChangeResourceRecordSets権限でレコードセット作成(変更、削除)を実行した後に、その進行状況を確認するための権限です。最初、ステータスは「PENDING」になり、その後「INSYNC」に変わります。

レコードセット作成の度に一意のIDが振られるため、Resoucrce句は "arn:aws:route53:::change/*"と広く指定しています。

以下のCLIでやる例をみると、この権限のイメージがつかみやすいかと思います。

ホストゾーンの中の1レコードだけ触れるようにしたい

上記権限だと、あるホストゾーンの中の全てのレコードを作成、変更、削除できてしまいます。特定の1レコードだけ触れれば十分な場合、そこまで権限を絞ることはできるのでしょうか?

これはできないようです。PolicyのCondition句で使えるRoute53固有のコンテキストキーはありません。

※ S3 Backendを使うなら

TerraformのStateファイルをS3で管理するのなら、別途そのための権限が必要になります。

例えば、以下のようなBackendの設定なら、

backend "s3" {
    bucket = "kazue-hogehoge-backend"
    key    = "route53.tfstate"
    region = "ap-northeast-1"
}

以下権限が追加で最低限必要です。

{
    "Effect": "Allow",
    "Action": "s3:ListBucket",
    "Resource": "arn:aws:s3:::kazue-hogehoge-backend"
},
{
    "Effect": "Allow",
    "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject"
    ],
    "Resource": [
        "arn:aws:s3:::kazue-hogehoge-backend/route53.tfstate"
    ]
}