はじめに
この記事ではterraformを用いてロードバランサーを作成してみましょう。
連載記事一覧
【連載】terraform によるAWS環境構築入門 最終回 ~ RDSとElastiCache ~
【連載】terraform によるAWS環境構築入門 おまけ1 ~ piplineを用いた継続的インテグレーション ~
本連載での使用技術
1. アプリケーションロードバランサ定義
ALB定義
最初にアプリケーションロードバランサーを以下のように定義してみましょう。
# ALBの定義 resource "aws_lb" "example" { name = "example" load_balancer_type = "application" internal = false idle_timeout = 60 enable_deletion_protection = true subnets = [ aws_subnet.public_0.id, aws_subnet.public_1.id, ] access_logs { bucket = aws_s3_bucket.alb_log.id enabled = true } security_groups = [ module.http_sg.security_group_id, ] }
・「internal」でALBがVPC内部向けなのか、インターネット向けなのか指定します。今回は外部向けなのでfalseにします。
・「enable_deletion_protection」を trueにすると削除保護が有効になります。本番環境では誤って削除しないよう有効にしておきましょう。
・ALB が所属するサブネットを「subnetsて」゙指定します。2つのサブネットを指定しクロスゾーン負荷分散を実現します。
セキュリティグループ
セキュリティグループを以下のように定義します
# ALB用のセキュリティグループ定義 module "http_sg" { source = "./security_group" name = "http-sg" vpc_id = aws_vpc.example.id port = 80 cidr_blocks = ["0.0.0.0/0"] }
リスナー
リスナーでどのポートのリクエストを受け付けるか設定します。リスナーはALBに 複数アタッチできます
# ALBリスナーの定義 resource "aws_lb_listener" "http" { load_balancer_arn = aws_lb.example.arn port = "80" protocol = "HTTP" default_action { type = "fixed-response" fixed_response { content_type = "text/plain" message_body = "これは『HTTP』です" status_code = "200" } } }
リスナーは複数のルールを設定して異なるアクションを実行できます。
いずれのルールにも合致しない場合はdefault_actionの定義内容が実行されます
- forward - リクエストを別のターゲットグループに転送
- fixed-response - 固定のHTTPレスポンスを応答
- redirect - 別のURLにリダイレクト
上記では固定のHTTPレスポンスを設定しています。
2. リクエストフォワーディング
ターゲットグループ
ALBがリクエストをフォワードする対象を「ターゲットグループ」と呼び以下のように定義します。
# ターゲットグループ resource "aws_lb_target_group" "example" { name = "example" vpc_id = aws_vpc.example.id target_type = "ip" port = 80 protocol = "HTTP" deregistration_delay = 300 health_check { path = "/" healthy_threshold = 5 unhealthy_threshold = 2 timeout = 5 interval = 30 matcher = 200 port = "traffic-port" protocol = "HTTP" } depends_on = [aws_lb.example] }
- 今回は、次章のECSで使用するインスタンスがfargateなので、「target_type」をipにします。
- ターゲットグループに ipを指定した場合はさらに、vpc_id、port、protocolを設定します。
- アプリケーションロードバランサとターゲットグループを、次章で登場するECSサービスと同時に作成するとエラーになります。そこで「depends_on」で依存関係を制御し、エラーを回避します。
リスナールール
ターゲットグループにリクエストをフォワードするリスナールールを作成します。
# リスナールール resource "aws_lb_listener_rule" "example" { listener_arn = aws_lb_listener.http.arn priority = 100 action { type = "forward" target_group_arn = aws_lb_target_group.example.arn } condition { field = "path-pattern" values = ["/*"] } }
- リスナールールは複数定義でき、優先順位を「priority」で設定します。数字が小さいほど優先順位が高いです。フォルトルールはもっとも優先順位が低いです。
- 「action」で、フォワード先のターゲットグループを設定します。
- 条件を「condition」で設定します。
3. まとめ(最終成果物の作成)
以上の解説をまとめて、最終成果物を作成しましょう。 フォルダ構成は以下の通り。 今回新しくlb.tfが追加になります。
exaple | |--- iam_role | |___ main.tf | |--- security_group | |___ main.tf | |--- lb.tf (新) | |--- main.tf (変更) | |--- network.tf | |___ S3.tf
まず、「main.tf」にセキュリティーグループを追記しましょう。
# ALB用のセキュリティグループ定義 module "http_sg" { source = "./security_group" name = "http-sg" vpc_id = aws_vpc.example.id port = 80 cidr_blocks = ["0.0.0.0/0"] }
次に、「lb.tf」に以下の内容を記述し、ロードバランサーとその周辺設定を定義しましょう。
# ALBの定義 resource "aws_lb" "example" { name = "example" load_balancer_type = "application" internal = false idle_timeout = 60 enable_deletion_protection = true subnets = [ aws_subnet.public_0.id, aws_subnet.public_1.id, ] access_logs { bucket = aws_s3_bucket.alb_log.id enabled = true } security_groups = [ module.http_sg.security_group_id, ] } # ALBリスナーの定義 resource "aws_lb_listener" "http" { load_balancer_arn = aws_lb.example.arn port = "80" protocol = "HTTP" default_action { type = "fixed-response" fixed_response { content_type = "text/plain" message_body = "これは『HTTP』です" status_code = "200" } } } # ターゲットグループ resource "aws_lb_target_group" "example" { name = "example" vpc_id = aws_vpc.example.id target_type = "ip" port = 80 protocol = "HTTP" deregistration_delay = 300 health_check { path = "/" healthy_threshold = 5 unhealthy_threshold = 2 timeout = 5 interval = 30 matcher = 200 port = "traffic-port" protocol = "HTTP" } depends_on = [aws_lb.example] } # リスナールール resource "aws_lb_listener_rule" "example" { listener_arn = aws_lb_listener.http.arn priority = 100 action { type = "forward" target_group_arn = aws_lb_target_group.example.arn } condition { field = "path-pattern" values = ["/*"] } } output "alb_dns_name" { value = aws_lb.example.dns_name }
4. 実行
まずはinitしましょう。これをやらないと、モジュールの呼び出しができません。
$ terraform init
実行計画の確認。前回にも書きましたが、破壊的な変更が入っていないか入念に確認しましょう。
$ terraform plan
実行。実行されたら、AWSの管理画面から確認しましょう。
うまくいっていればIAMページ左上の「Search IAM」のフォームに「describe-regions-for-ec2」と入力て検索ができるはずです。
$ terraform apply