【AWSチュートリアル】WEBサーバ用のALBを作成してみよう!①

WEB-ALB-01ALB

今回はWEBサーバ用のALBを作成していきます。長くなりそうなので、2回に分けて解説していきますので、是非最後まで読んで頂けると!

GitHub - katsuya-yamaguchi/study-infra-aws-tutorial at blog/006
Contribute to katsuya-yamaguchi/study-infra-aws-tutorial development by creating an account on GitHub.

前提

  1. 前回までの記事を読んでいること!

今回の目標

以下のリソースを作成します。

  • 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」となってます。

タスク定義パラメータ - Amazon Elastic Container Service
タスク定義は、タスクファミリ、IAM タスクロール、ネットワークモード、コンテナ定義、ボリューム、タスク配置の制約事項、起動タイプの各部分に分かれています。ファミリーとコンテナ定義はタスク定義に必須ですが、タスクロール、ネットワークモード、ボリューム、タスク配置の制約事項、起動タイプはオプションです。

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が記載されています。

Application Load Balancer のアクセスログ - Elastic Load Balancing
Elastic Load Balancing が提供するアクセスログを使用して Application Load Balancer を監視する方法について説明します。
リージョンリージョン名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の作成に入っていきます。

これにて本記事は終了です。

コメント

タイトルとURLをコピーしました