【Terraform】ALB+EC2を作成してNginxをインストールする

Terraform

 

タイトルにあるとおり、TerraformでALB+EC2を構築していきます。

 

基本的な構成だと思いますので、使う機会も多いのでは?

Terraformの勉強としても使えるので試してみてください!

 

 

想定読者

 

  • Terraformの基本的な文法を理解している
  • AWSに触れたことがある
  • Terraformを使用してAWSにデプロイできる環境がある

 

ゴール

インフラ構成図

 

 

要件

 

  • ALBはHTTP(80番ポート)でリクエストを受け、EC2(80番ポート)に流す
  • ALBは2つのAZが必要なので、AZおよびサブネットは2つ用意する
  • ALB、EC2ともにパブリックサブネットに構築する
  • ALBからのみEC2にアクセスできる
  • 構築するEC2は1台のみ
  • NAT Gateway を使用してEC2→インターネットに疎通可能
    ⇒なかなかコストがかかるのでNAT Gatewayは使わない
  • Amazon Linux 2023 を使用してEC2を構築し、Nginxをインストールする

 

動作確認方法

 

WEBブラウザからALBにアクセスし、

EC2にインストールされたNginxの画面が表示されることを確認します

 

ディレクトリ構成

 

 

ルートディレクトリ

provider.tf

 

TerraformやAWSプロバイダーのバージョン、リージョンを定義します

 

backend.tf

 

tfstateを保存するS3バケットを定義します

保存先のバケット名(<bucket_name>)は各自変更してください

 

variables.tf

 

VPCのCidrと作成するリソースに付与するNameタグで使用するPrefixを設定しておきます

Prefixは自分がわかるように好きな文字列を設定してください

 

main.tf

 

VPCとinternet gateway、モジュールの呼び出しをします

VPCとinternet gatewayは一つだけあればいいのでモジュール化せずここで定義しておきます

 

ポイントは、

  • Subnetを2つのAZで作成
  • EC2のAMIはAmazon Linux 2023、インスタンスタイプはt2.micro(無料枠なので、、)

となるようにモジュールの引数を指定しています。

 

outputs.tf

 

今回outputする値はないので、空ファイルになります

 

モジュール

subnet

 

パブリックサブネットを作成するモジュールです。

このモジュールをルートディレクトリで2回呼び出し、2つのAZに同様のSubnetを作成します

 

variables.tf

 

Subnetの構築に必要なパラメータを設定します

  • AZ
  • SubnetのCidr

を変数化し、ほかのAZでの構築でも使用できるようにしました

 

main.tf

 

Subnetを作成し、インターネットへのRouteを定義しているRoute Tableと紐づけることで、

インターネットへアクセスできるPublic Subnet化しています

 

outputs.tf

 

EC2やALBの構築時に必要なSubnetのIDをoutputしておきます

 

ec2

 

EC2にキーペアを指定していないため、SSHはできません。

もしSSHしたい方はキーペアを指定するか、

↓を参考にSession Managerを使ってみてください!

 

variables.tf

 

EC2の構築に必要なパラメータを設定します

  • AMI
  • AZ
  • Instance Type
  • SubnetのID

を変数化し、複数インスタンスを構築できるようにしました

 

main.tf

 

EC2インスタンス、Security Group、EIPを定義しています

 

・EC2インスタンス

AMIやインスタンスタイプ、Subnet等を指定しています

ユーザーデータにshファイルを指定し、ファイルを読み込んでいます

 

・Security Group

ALB⇒EC2の80ポートへの通信(インバウンド)と
EC2⇒インターネットの通信(アウトバウンド)を許可しています

 

 

user_data.sh

 

EC2のユーザーデータに設定するスクリプトです。

今回はNginxをインストールし起動するものとなっています

 

outputs.tf

 

ALBの構築時に必要なインスタンスのIDとSecurity GroupのIDをoutputします

 

alb

variables.tf

 

ALBの構築に必要なパラメータを設定します

ターゲットグループに設定するEC2のIDはリスト型にし、複数指定できるようにします

 

main.tf

 

ALBの動きとしては

  1. 80ポートでリクエストを受け取る
  2. ターゲットグループ内のEC2(80ポート)にリクエストを流す

を想定しており、パラメータを表にまとめました

 

・aws_lb

プロパティ 説明
name “alb” LBの名前
internal false VPC外からアクセスしたいのでfalse
load_balancer_type “application” ELBのタイプ。今回はALB
security_groups [aws_security_group.alb_sg.id] ELBで使用するSecurity Group
リストで指定する
subnets var.subnets ELBが属するSubnet。
リストで指定する。
ALBの場合は2つ以上指定する必要あり。
enable_deletion_protection true ELBが削除可能かどうか
trueなので、Terraformによる削除は不可
tags
{
  Name = “${var.prefix}-alb”
}
Nameタグを付与しておく

 

・aws_security_group

名前とVPC、Nameタグの付与のみ

 

・aws_security_group_rule(インバウンド)

プロパティ 説明
security_group_id aws_security_group.alb_sg.id ルールを紐づけるSecurity GroupのID
type “ingress” インバウンドなので、ingress
from_port “80” 80ポートへのアクセスを許可する
to_port “80”
protocol “tcp” 通信プロトコルはTCP
cidr_blocks [“0.0.0.0/0”] どのIPからでもアクセスを許可

 

・aws_security_group_rule(アウトバウンド)

プロパティ 説明
security_group_id aws_security_group.alb_sg.id ルールを紐づけるSecurity GroupのID
type “egress” アウトバウンドなので、egress
from_port “80” 80ポートへのアクセスを許可する
to_port “80”
protocol “tcp” 通信プロトコルはTCP
cidr_blocks [var.vpc_cidr_block] VPC内のIPアドレスへの通信を許可

 

・aws_lb_listener

プロパティ 説明
load_balancer_arn aws_lb.alb.arn 紐づけるELBのARN
port “80” 80ポートでリクエストを受け付ける
protocol “HTTP” 受け取るプロトコルはHTTP
default_action
{
  type             = “forward”
  target_group_arn = aws_lb_target_group.tg.arn
}
リクエストが来た時にどうするか。
今回はターゲットグループに振り分けるため、typeはforward、ターゲットグループを指定

 

・aws_lb_target_group

プロパティ 説明
name “alb-tg” ターゲットグループ名
port 80 ポート
protocol “HTTP” プロトコル
vpc_id var.vpc_id 属するVPCのID
tags
{
  Name = “${var.prefix}-alb-tg”
}
Nameタグを付与しておく

 

・aws_lb_target_group_attachment

プロパティ 説明
for_each toset(var.ec2_id_list) リスト内の要素を一つずつ取り出し、resourceを作成していく
target_group_arn aws_lb_target_group.tg.arn 紐づけるターゲットグループのARN。
target_id each.value ターゲットグループにアタッチするインスタンスのID。
each.valueでループ中のリスト内の値がとれる
port 80 インスタンスの80ポートで受け取る

 

 

outputs.tf

 

EC2のSecurity GroupのIngressに必要なALBのSecurity GroupのIDをoutputします

 

必要なIAMポリシー

 

今回使用したIAMポリシーはこちらです

  • AmazonEC2FullAccess
  • AmazonS3FullAccess
  • AmazonVPCFullAccess
  • ElasticLoadBalancingFullAccess

 

もう少し権限を絞りたかった。。。

 

リソース作成&確認

 

ルートディレクトリで以下のコマンドを実行してデプロイしましょう

 

デプロイしたらAWSコンソールで作成されているか確認しましょう

 

動作確認

 

ALBのDNS(×××.ap-northeast-1.elb.amazonaws.com) にアクセスして、
Nginxの画面が表示されたらOK!

 

 

参考記事

 

Terraform Registry

 

 

 

 

コメント

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