[Terraform]親ドメインからサブドメインへの権限委任 〜 サブドメインのパブリック証明書を取得するまで
はじめに
皆様こんにちは、クラウド事業本部コンサルティング部のあかいけです。
最近、Route53で既存のドメインにサブドメインを追加(権限委任)する機会があり、
作業する際に私はふと思いました。
「Route53に限った話ではないけど、GUIで久しぶりに触るリソースだと画面構成が変わっていて困惑することがあるよなぁ…。」 と。
そこで今後を見据えて、今回はTerraformを使って作業してみることにしました。
なおGUIでの手順は以下をご参照ください。
やりたいこと
構成
- 親ドメイン(委任元):example.org
- サブドメイン(委任先):tes.example.org
前提として、親ドメイン(example.org)は作成済みとします。
今回新たに作成するリソースは以下の通りです。
- 親ドメイン側
- NSレコード (委任先のサブドメインのNSを指定)
- サブドメイン側
- ホストゾーン
- CNAMEレコード (証明書検証用)
- パブリック証明書(ACM)
手順
Terraformの全量は以下の通りです。
これをローカル環境にコピーして、
terraform 全量
terraform {
required_version = ">= 1.10.0"
}
terraform {
required_providers {
aws = ">= 5.87.0"
}
}
provider "aws" {
region = "ap-northeast-1"
}
# ACM用 プロバイダー
provider "aws" {
alias = "us-east-1"
region = "us-east-1"
}
variable "base_domain" {
type = string
}
variable "sub_domain" {
type = string
}
locals {
sub_domain = var.sub_domain
base_domain = var.base_domain
}
# 1.サブドメイン ホストゾーン作成
resource "aws_route53_zone" "main" {
name = "${local.sub_domain}.${local.base_domain}"
}
# 2.親ドメイン 権限委任用NSレコード作成
data "aws_route53_zone" "root" {
name = local.base_domain
private_zone = false
}
resource "aws_route53_record" "root_ns" {
zone_id = data.aws_route53_zone.root.id
name = "${local.sub_domain}.${local.base_domain}"
type = "NS"
ttl = 300
records = aws_route53_zone.main.name_servers
}
# 3.サブドメイン用 証明書発行
## パブリック証明書
resource "aws_acm_certificate" "main" {
domain_name = "${local.sub_domain}.${local.base_domain}"
subject_alternative_names = ["*.${local.sub_domain}.${local.base_domain}"]
validation_method = "DNS"
provider = "aws.us-east-1"
lifecycle {
create_before_destroy = true
}
}
## ドメイン検証
resource "aws_acm_certificate_validation" "main" {
provider = "aws.us-east-1"
certificate_arn = aws_acm_certificate.main.arn
validation_record_fqdns = [for record in aws_route53_record.cert_validation : record.fqdn]
}
## ドメイン検証用 CNAMEレコード
resource "aws_route53_record" "cert_validation" {
for_each = {
for dvo in aws_acm_certificate.main.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
zone_id = aws_route53_zone.main.id
}
}
allow_overwrite = true
name = each.value.name
records = [each.value.record]
ttl = 60
type = each.value.type
zone_id = each.value.zone_id
}
output "domain" {
value = aws_route53_zone.main.name
}
output "name_servers" {
value = aws_route53_zone.main.name_servers
}
variables.tfに対象となるドメイン名を入力して、
(ファイル直書きに抵抗があれば、terraform apply時に指定してください)
variable "base_domain" {
type = string
default = example.org
}
variable "sub_domain" {
type = string
default = tes
}
あとはapplyしてください。
% terraform init
% terraform apply
リソース作成後、
以下のようにNSレコードが参照できれば正常に権限委任できています。
% dig +noall +answer tes.example.org. ns
tes.example.org. 172800 IN NS ns-AAAA.awsdns-XX.org.
tes.example.org. 172800 IN NS ns-BBBB.awsdns-XX.co.uk.
tes.example.org. 172800 IN NS ns-CCCC.awsdns-XX.com.
tes.example.org. 172800 IN NS ns-DDDD.awsdns-XX.net.
設定内容
これ以降は具体的にどのような設定をしているか解説します。
1.サブドメイン ホストゾーン作成
まずサブドメインのホストゾーンを作成します。
resource "aws_route53_zone" "main" {
name = "${local.sub_domain}.${local.base_domain}"
}
2.親ドメイン 権限委任用NSレコード作成
親ドメインのホストゾーンは管理対象外の想定で、dataリソースとして参照しています。
委任先のNSはサブドメインのホストゾーンの属性を参照して、
権限委任用のNSレコードを作成します。
data "aws_route53_zone" "root" {
name = local.base_domain
private_zone = false
}
resource "aws_route53_record" "root_ns" {
zone_id = data.aws_route53_zone.root.id
name = "${local.sub_domain}.${local.base_domain}"
type = "NS"
ttl = 300
records = aws_route53_zone.main.name_servers
}
3.サブドメイン 証明書発行
最後にサブドメイン用にACMでパブリック証明書を発行します。
GUIで作成する場合、検証用のCNAMEレコードは自動作成されますが、
Terraformの場合は明示的に作成する必要があります。
## パブリック証明書
resource "aws_acm_certificate" "main" {
domain_name = "${local.sub_domain}.${local.base_domain}"
subject_alternative_names = ["*.${local.sub_domain}.${local.base_domain}"]
validation_method = "DNS"
provider = "aws.us-east-1"
lifecycle {
create_before_destroy = true
}
}
## ドメイン検証
resource "aws_acm_certificate_validation" "main" {
provider = "aws.us-east-1"
certificate_arn = aws_acm_certificate.main.arn
validation_record_fqdns = [for record in aws_route53_record.cert_validation : record.fqdn]
}
## ドメイン検証用 CNAMEレコード
resource "aws_route53_record" "cert_validation" {
for_each = {
for dvo in aws_acm_certificate.main.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
zone_id = aws_route53_zone.main.id
}
}
allow_overwrite = true
name = each.value.name
records = [each.value.record]
ttl = 60
type = each.value.type
zone_id = each.value.zone_id
}
さいごに
以上、「親ドメインからサブドメインへの権限委任 〜 パブリック証明書を取得するまで」でした。
個人的にRoute53関連の設定は頻繁にやる作業ではないためか、毎回調べて思い出しながら作業している状況です…。
なのでこれからも、隙あらばIaC化していこうと思います。