今回はWEBサーバ用のALBを作成していきます。長くなりそうなので、2回に分けて解説していきますので、是非最後まで読んで頂けると!
前提
- 前回までの記事を読んでいること!
今回の目標
以下のリソースを作成します。
- ALB用のセキュリティグループ。
- ALBのアクセスログ格納のために、ログ格納用S3バケットにアクセス許可設定を入れる。
- ALBに必要なACMのouputを追加。
ALB用のセキュリティグループを作成する。
ALB用のセキュリティグループを作成します。作成したセキュリティグループには以下のルールをも追加します。
- ALBからの送信は全て許可。
- ALBへのHTTP通信(ポート80)は全て許可。
- ALBへのHTTPS通信(ポート443)は全て許可。
terraform/system/modules/web/ec2_sg.tf
+ resource "aws_security_group" "alb_web" {
+ name = "alb-web"
+ vpc_id = var.vpc_id
+ tags = {
+ Name = "alb-web"
+ }
+ }
# ALBからの送信許可設定。
+ resource "aws_security_group_rule" "alb_web_to_outbound" {
+ type = "egress"
+ security_group_id = aws_security_group.alb_web.id
+ from_port = 0
+ to_port = 0
+ protocol = -1
+ cidr_blocks = ["0.0.0.0/0"]
+ }
# ALBへのHTTPS通信の許可設定。
+ resource "aws_security_group_rule" "alb_web_in_https" {
+ type = "ingress"
+ security_group_id = aws_security_group.alb_web.id
+ from_port = 443
+ to_port = 443
+ protocol = "tcp"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
# ALBへのHTTP通信の許可設定。
+ resource "aws_security_group_rule" "alb_web_in_htttp" {
+ type = "ingress"
+ security_group_id = aws_security_group.alb_web.id
+ from_port = 80
+ to_port = 80
+ protocol = "tcp"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
また、ALBからコンテナインスタンスへの通信許可も設定していきます。コンテナインスタンス用のセキュリティグループに対して以下の内容でルールを追加します。
通信タイプ | 受信 |
---|---|
ソース | ALBのセキュリティグループ |
ポート | 49153~65535(※) |
※ECSのネットワークモードは「default(bridge)」を使用する予定です。その際、ホスト側のポート設定として動的ホストポートマッピングを利用します。この動的ホストポートマッピングのポートの範囲が「49153~65535」となってます。
terraform/system/modules/web/ec2_sg.tf
+ resource "aws_security_group_rule" "ecs_container_instance_from_alb_web" {
+ type = "ingress"
+ security_group_id = aws_security_group.ecs_container_instance_web.id
+ from_port = 49153
+ to_port = 65535
+ protocol = "tcp"
+ source_security_group_id = aws_security_group.alb_web.id
+ }
ログ格納用S3バケットに対して、バケットポリシーを作成する。
ALBのアクセスログは、自動でS3バケットに保存することができます。ALBからS3バケットにログを格納するには、対象のS3バケットのバケットポリシーで許可をする必要があります。
ALBは少し特殊で、「ELBアカウントがS3バケットにPutObjectすることを許可」というバケットポリシーを作成する必要があります。特殊な部分は、このELBアカウントと呼ばれるものです。これは、リージョン毎に決まっています。
公式ドキュメントにリージョン毎のIDが記載されています。
リージョン | リージョン名 | Elastic Load Balancing アカウント ID |
---|---|---|
ap-northeast-1 | アジアパシフィック (東京) | 582318560864 |
今回は東京リージョンにALBを作成しているため、↑のIDを使用します。
terraform/system/modules/common/s3_logging.tf
# 自分のAWSアカウントIDを参照することができます。
# (これを使うと、コード内にハードコーディングしなくてよいのでとても便利です。)
+ data "aws_caller_identity" "self" {}
# ALBがPutObjectするのを許可しています。
# https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-access-logs.html#access-logging-bucket-permissions
+ data "aws_iam_policy_document" "alb" {
+ statement {
+ principals {
+ type = "AWS"
+ identifiers = ["arn:aws:iam::582318560864:root"]
+ }
+ actions = [
+ "s3:PutObject"
+ ]
+ resources = ["arn:aws:s3:::${aws_s3_bucket.logging.id}/AWSLogs/${data.aws_caller_identity.self.account_id}/*"]
+ }
+ }
# バケットポリシーとS3バケットの紐付けを行います。
+ resource "aws_s3_bucket_policy" "logging" {
+ bucket = aws_s3_bucket.logging.id
+ policy = data.aws_iam_policy_document.alb.json
+ }
ALBで使用するACMのSSL証明書をoutputに追加する。
ALBでのHTTPS通信に必要なSSL証明書をouputに追加します。
terraform/system/modules/common/output.tf
+ output "ssl_certificate_study_infra_tk_arn" {
+ value = aws_acm_certificate.study_infra_tk.arn
+ }
main.tfにて必要な変数をモジュールに渡す。
az、public_subnets_id、s3_logging_bucket、ssl_certificate_study_infra_tk_arnはALBを作成するときに使用します。
terraform/system/staging/main.tf
module "web" {
...
+ az = var.az
+ public_subnets_id = data.terraform_remote_state.network.outputs.public_subnets_id
+ s3_logging_bucket = module.common.s3_logging_bucket
+ ssl_certificate_study_infra_tk_arn = module.common.ssl_certificate_study_infra_tk_arn
}
Terraformを実行する。
1. /study-infra-aws-tutorial/terraform/system/staging/example.tfbackend
を修正する。
- bucket:Stateを管理するS3バケット名に変更する。
- role_arn:Terraform実行用RoleのARNに変更する。
bucket = "sample-bucket"
region = "ap-northeast-1"
key = "study-infra-tutorial/system/staging.tfstate"
encrypt = true
role_arn = "arn:aws:iam::111111111:role/study-infra-terraform-role"
2. /study-infra-aws-tutorial/terraform/system/staging/staging.tfvars
を作成する。
- iam_role_for_terraform:Terraform実行用RoleのARNに変更する。
- bucket:Stateを管理するS3バケット名に変更する。
- role_arn:Terraform実行用RoleのARNに変更する。
iam_role_for_terraform = "arn:aws:iam::111111111:role/study-infra-terraform-role"
network_remote_state_config = {
bucket = "sample-bucket"
key = "study-infra-tutorial/staging.tfstate"
region = "ap-northeast-1"
role_arn = "arn:aws:iam::111111111:role/study-infra-terraform-role"
}
3.Dockerイメージをビルドする。
$ docker build \
-t study-infra-tf:${IMAGE_VERSION} \
--build-arg AWS_ACCESS_KEY=${AWS_ACCESS_KEY} \
--build-arg AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} \
--build-arg ENV=${ENV} \
.
4.コンテナを起動して接続する。
$ pwd
-> 「***/study-infra-aws-tutorial」に居ること。
$ docker run --rm -v $PWD/terraform:/tf -it [ImageID] ash
5.Terraformを初期化する。
$ cd /tf/system/stating
$ terraform init -backend-config=example.tfbackend
Initializing modules...
- network in ../modules
Initializing the backend...
Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.
Initializing provider plugins...
- Finding latest version of hashicorp/aws...
- Installing hashicorp/aws v3.68.0...
- Installed hashicorp/aws v3.68.0 (signed by HashiCorp)
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
$
6. terraform plan
を実行する。
planの結果、エラーが無いようであればOKです。
$ terraform plan -var-file=staging.tfvars
7. terraform apply
を実行してリソースを構築する。
$ terraform apply -var-file=staging.tfvars
以上で、ALBで必要なリソースが準備できました。次回はALBの作成に入っていきます。
これにて本記事は終了です。
コメント