前回の記事から、Terraform で ECS 環境の構築に取り組んでいました。 今回は、ドメインの設定とロードバランサの設定を行い、HTTPS で外部からのリクエストを受けられるようにします。
- はじめに:最終的なゴールと今回の目標の確認
- 無料で独自ドメインを取得し、Route 53 で利用する
- ALB の設定
- Route 53 の設定
- ACM で SSL 証明書の作成
- 適用と検証
- まとめ
- 参考資料
はじめに:最終的なゴールと今回の目標の確認
- 最終的な目標は、外部からのリクエストを受けられる ECS サービスの構築です。
- 下図の青く囲ったところが前回構築した部分、赤く囲ったところが今回の目標です。
無料で独自ドメインを取得し、Route 53 で利用する
- 今回は、独自ドメインの設定をして HTTPS 通信ができるところまでを目標にします。
- 今回のように、お試しで作業したりする際、わざわざ有料のドメインを取得するほどのことでもなかったり、所有ドメインのサブドメインを作成したくない場合に、freenom を利用して無料のドメインを取得できます。
- 無料対象 TLD は下記の5つです:
無料ドメインの取得まで
- freenom にアクセスしたら、取得したいドメイン名を入れて検索します。
- 取得可能な一覧が表示されますので、取得したい TLD の「今すぐ入手」を押します。
- 右上に「チェックアウト」のボタンが出るので押して次に進みます。
- 次の画面の「Period」で期間を選択します。12 ヶ月(12 Months)までは無料のようです。
- 1 年(1 year)は有料です(なぜ・・・?)
- 期間が終了して継続して利用する場合は、更新を忘れないようにします。
- 選択したら、「Continue」で次に進みます。
- 次の画面でメールアドレスか Google アカウントによる認証を行います。
- 認証が終わったら、詳細情報を聞かれます。
- この情報は公開されません。
- whois には freenom の情報が記載されます。
取得したドメインを Route 53 で利用できるようにする
- 独自ドメインを Route 53 で利用できるようにします*1。
- AWS の各種サービスで利用しやすくなります。
- Terraform は使わずにマネジメントコンソールで設定していきます。
- Route 53の画面で左メニューから「ホストゾーン」を選択します。
- 「ホストゾーンの作成」を押して次に進みます。
- 「ドメイン名」に先程取得したドメイン名を記入して、「ホストゾーンの作成」を押して進みます。
- ホストゾーンを登録後、登録したホストゾーンの設定画面から、 NS レコードの4つの値を確認します。
- 再び、 freenom の画面に戻り、サインアップ後、上のメニューより「Services」->「My Domains」から取得したドメインの「Manage Domain」を押します。
- 「Management Tools」から「Nameservers」を選択します。
- 「Use custom nameservers (enter below)」を選択し、Nameserver の入力欄に、先程 Route 53 で確認した NS レコードの入力して「Change Nameservers」を押します。
- レコードの入力欄には、各設定値の最後のドット(.)は入れないことに注意します。
- ネームサーバの設定変更の反映には時間がかかります。
ALB の設定
- 前段が長くなってしまいましたが、ここから Terraform を使って ALB を構築していきます。
ALB ログバケット
resource "aws_s3_bucket" "alb_log" { bucket = "linkode-terraform-alb-log" force_destroy = true lifecycle_rule { enabled = true expiration { days = "180" } } }
- AWS の他のサービスから S3 バケットへの書き込みアクセス権を設定します。以下のようにバケットポリシーを設定します。
- ALB の場合、AWS が管理しているアカウントから書き込むため、書き込みを行うアカウント ID を
principals.identifiers
に記載します。 - アカウントの ID はリージョン毎に異なります。以下のページから確認できます。
- ALB の場合、AWS が管理しているアカウントから書き込むため、書き込みを行うアカウント ID を
resource "aws_s3_bucket_policy" "alb_log" { bucket = aws_s3_bucket.alb_log.id policy = data.aws_iam_policy_document.alb_log.json } data "aws_iam_policy_document" "alb_log" { statement { effect = "Allow" actions = ["s3:PutObject"] resources = ["arn:aws:s3:::${aws_s3_bucket.alb_log.id}/*"] principals { type = "AWS" identifiers = ["582318560864"] } } }
- ここまでの内容を
s3.tf
にまとめて記載しておきます。
// ここまでのファイル構成 . |-- main.tf |-- network.tf |-- s3.tf // 新規作成したファイル `-- security_group |-- main.tf |-- output.tf `-- variable.tf
ALB の作成
- ALB の構成要素は以下の図のようになっています。
- まず、ALB を以下のように定義します。
load_balancer_type
: ロードバランサーの種別を設定します。application
を指定すると ALB,network
を指定すると NLB になります。internal
: インターネット向けなのか VPC 内部向けなのかを指定します。false
にするとインターネット向けになります。idle_timeout
: タイムアウトの時間(秒単位)を指定します。デフォルトは 60 秒です。enable_deletion_protection
: 削除保護を有効にするか否かを指定します。本番環境では誤って削除しないようtrue
を指定します。subnets
: ALB が所属するサブネットを指定します。access_logs
: バケット名を指定して、アクセスログの保存を有効にします。- 先ほど作成した、S3 バケットを指定します。
resource "aws_lb" "example" { name = "example" load_balancer_type = "application" internal = false idle_timeout = 60 enable_deletion_protection = false subnets = [ aws_subnet.public_a.id, aws_subnet.public_b.id, ] access_logs { bucket = aws_s3_bucket.alb_log.id prefix = "example-alb" enabled = true } security_groups = [ module.http_sg.security_group_id, module.https_sg.security_group_id, ] } output "alb_dns_name" { value = aws_lb.example.dns_name }
セキュリティグループの作成
- 前回の記事で作成したモジュールを用いて、セキュリティグループを作成します。
- HTTP のポート 80 番と HTTPS の 443 番を許可します。
module "http_sg" { source = "./security_group" name = "http-sg" vpc_id = aws_vpc.example.id port = 80 cidr_blocks = ["0.0.0.0/0"] } module "https_sg" { source = "./security_group" name = "https-sg" vpc_id = aws_vpc.example.id port = 443 cidr_blocks = ["0.0.0.0/0"] }
リスナーの作成
- リスナーを作成し、どのポートでリクエストを受けるかを設定します。
- 以下では、次のように設定しています:
certificate_arn
で SSL 証明書の ARN を指定していますが、これは後ほど設定します。
resource "aws_lb_listener" "http" { load_balancer_arn = aws_lb.example.arn port = "80" protocol = "HTTP" default_action { type = "redirect" redirect { port = "443" protocol = "HTTPS" status_code = "HTTP_301" } } } resource "aws_lb_listener" "https" { load_balancer_arn = aws_lb.example.arn port = "443" protocol = "HTTPS" certificate_arn = [後ほど設定] ssl_policy = "ELBSecurityPolicy-2016-08" default_action { type = "fixed-response" fixed_response { content_type = "text/plain" message_body = "これは「HTTPS」です" status_code = "200" } } }
- ここまでの内容を
alb.tf
に記述して保存しておきます。
// ここまでのファイル構成 . |-- alb.tf // 新規作成したファイル |-- main.tf |-- network.tf |-- s3.tf `-- security_group |-- main.tf |-- output.tf `-- variable.tf
Route 53 の設定
- 最初に作成したホストゾーンに DNS レコードを定義します。
- 予め作成したホストゾーンは以下のように参照します。
data "aws_route53_zone" "main" { name = "linkode-example.ml" }
- このホストゾーンに対して、DNS レコードを作成します。
resource "aws_route53_record" "example" { zone_id = data.aws_route53_zone.main.zone_id name = data.aws_route53_zone.main.name type = "A" alias { name = aws_lb.example.dns_name zone_id = aws_lb.example.zone_id evaluate_target_health = true } }
- ここまでの内容を
route53.tf
に記載しておきます。
// ここまでのファイル構成 . |-- alb.tf |-- main.tf |-- network.tf |-- route53.tf // 新規作成したファイル |-- s3.tf `-- security_group |-- main.tf |-- output.tf `-- variable.tf
ACM で SSL 証明書の作成
- ACM を利用すると、 SSL 証明書の自動更新を行なってくれます。
- SSL 証明書はホストゾーンと同様に手動で設定します。
- マネジメントコンソールより Certificate Manager を選択し、「証明書のリクエスト」を押します。
- 「パブリック証明書のリクエスト」を選択し、「証明書のリクエスト」を押します。
- 次の画面で、取得したドメイン名を入力して次へ進みます。
- 検証方法は、DNS 検証を選択して次へ進む。
- タグについては特に入力せず、確認の画面に進み、次の画面で「確定とリクエスト」を押します。
- Route 53 でホストゾーンを管理していると、検証の画面で「Route 53 でのレコード作成」ボタンが現れるので押すと、検証用レコードが作成されます。
- 検証には少々時間がかかりますが、完了したら「発行済み」の状況になります。
適用と検証
- ここまでの作業が完了したら、プロジェクトのルートディレクトリで、
terraform apply
を実行します。- モジュールの適用のために一度
terraform get
を実行します。
- モジュールの適用のために一度
$ terraform fmt $ terraform get $ terraform validate $ terraform plan $ terraform apply
- 完了した際にコンソールに表示される「
alb_dns_name
」のcurl
でアクセスしてみます。- 下のように、リダイレクトされた旨のレスポンスが返ってきたら成功です。
$ curl http://example-XXXXXX.ap-northeast-1.elb.amazonaws.com <html> <head><title>301 Moved Permanently</title></head> <body> <center><h1>301 Moved Permanently</h1></center> </body> </html>
- 次に、独自ドメインの URL にアクセスしてみます。
- http でアクセスすると、先ほどと同じくリダイレクトされた旨のレスポンスが返ってきます。
- https でアクセスすると、 Terraform で設定した固定レスポンスが返ってきます。
$ curl http://linkode-example.ml <html> <head><title>301 Moved Permanently</title></head> <body> <center><h1>301 Moved Permanently</h1></center> </body> </html> $ curl https://linkode-example.ml これは「HTTPS」です
まとめ
- Terraform を用いて、Route 53 や ACM, ALB を設定・構築し、独自ドメインで HTTPS のリクエストを受けられるようにしました。
- 無料で独自ドメインを取得する方法と AWS で利用するための方法も紹介しました。
- freenom 以外のドメインサービスでも同様の設定で利用することが出来ます。
- ここまでで、外部からのリクエストを受けられる状態になりました。次回はリクエストを ECS に振り分けるように設定します。
参考資料
- 野村 友規「実践Terraform AWSにおけるシステム設計とベストプラクティス」インプレスR&D(2019)
- 内容全般について参考にしました。
- freenomで無料ドメインを取得する
- 無料での独自ドメインの取得方法について参考にしました。
- Terraform の公式ドキュメント:各リソースの設定方法や利用法、注意点を参照しています。