[CloudFormation] テスト用 web サーバと ALB を作成
この記事でやること
・EC2 インスタンス(Web サーバ)をデプロイ
・ALB をデプロイ
・EC2 インスタンスと ALB 用に Security Group を作成しアタッチ
使用するテンプレート
AWSTemplateFormatVersion: 2010-09-09
Parameters:
ImageId:
Type: String
AllowIP:
Type: String
PrivateSubnetId:
Type: String
VPCId:
Type: String
PublicSubnet1Id:
Type: String
PublicSubnet2Id:
Type: String
Resources:
EC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref ImageId
InstanceType: t2.micro
SecurityGroupIds:
- !Ref EC2SecurityGroup
SubnetId: !Ref PrivateSubnetId
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-EC2
UserData:
!Base64 |
#!/bin/bash
amazon-linux-extras install nginx1.12 -y
systemctl start nginx
systemctl enable nginx
EC2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub ${AWS::StackName}-EC2-SG
GroupDescription: Used Web Server
VpcId: !Ref VPCId
SecurityGroupIngress:
-
IpProtocol: tcp
FromPort: 80
ToPort: 80
SourceSecurityGroupId: !Ref ALBSecurityGroup
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-EC2-SG
ALBSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub ${AWS::StackName}-ALB-SG
GroupDescription: Used ALB
VpcId: !Ref VPCId
SecurityGroupIngress:
-
IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: !Ref AllowIP
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-ALB-SG
TargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
VpcId: !Ref VPCId
Name: !Sub ${AWS::StackName}-TG
Protocol: HTTP
Port: 80
HealthCheckProtocol: HTTP
HealthCheckPath: /
HealthCheckPort: traffic-port
HealthyThresholdCount: 5
UnhealthyThresholdCount: 2
HealthCheckTimeoutSeconds: 5
HealthCheckIntervalSeconds: 30
Matcher:
HttpCode: 200
Targets:
- Id: !Ref EC2Instance
Port: 80
InternetALB:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: !Sub ${AWS::StackName}-ALB
Scheme: internet-facing
LoadBalancerAttributes:
- Key: deletion_protection.enabled
Value: false
- Key: idle_timeout.timeout_seconds
Value: 4000
SecurityGroups:
- !Ref ALBSecurityGroup
Subnets:
- !Ref PublicSubnet1Id
- !Ref PublicSubnet2Id
ALBListenerHTTP:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
Port: 80
Protocol: HTTP
DefaultActions:
- TargetGroupArn: !Ref TargetGroup
Type: forward
LoadBalancerArn: !Ref InternetALB
Outputs:
HTTPWebSiteURL:
Value: !GetAtt InternetALB.DNSName
※ Parameters セクションの値はハードコードしても問題ありません
このテンプレートではテンプレートの汎用性のために Paramaters セクションにしてます
テンプレートの展開確認
下記リソースが展開されます
出力では ALB の URL が表示されます
アクセスすると HTTP で nginx の welcome ページが表示されます
各リソースの説明
EC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref ImageId
InstanceType: t2.micro
SecurityGroupIds:
- !Ref EC2SecurityGroup
SubnetId: !Ref PrivateSubnetId
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-EC2
UserData:
!Base64 |
#!/bin/bash
amazon-linux-extras install nginx1.12 -y
systemctl start nginx
systemctl enable nginx
EC2 インスタンス(Web サーバ)を作成します
※今回はテスト用のため EC2 インスタンスは 1台としています
・SecurityGroupIds: EC2 インスタンにアタッチする Security Group のID を指定します
→ 今回は下記で作成するものを !Ref で指定します
※リスト形式で記載する必要があるため注意
・UserData: EC2 インスタンスを起動するときに実行するコマンドを記載します
→ 今回は Web サーバを構築するため nginx をインストールし、起動しています
EC2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub ${AWS::StackName}-EC2-SG
GroupDescription: Used Web Server
VpcId: !Ref VPCId
SecurityGroupIngress:
-
IpProtocol: tcp
FromPort: 80
ToPort: 80
SourceSecurityGroupId: !Ref ALBSecurityGroup
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-EC2-SG
ALBSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub ${AWS::StackName}-ALB-SG
GroupDescription: Used ALB
VpcId: !Ref VPCId
SecurityGroupIngress:
-
IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: !Ref AllowIP
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-ALB-SG
EC2 インスタンスと ALB 用に Security Group を作成します
・VpcId: Security Group を作成する VPC の ID を指定します
・SecurityGroupIngress: Security Group のインバウンドルールを指定します
→ 今回は下記ルールで各 Security Group のインバウンドルールを作成します
・ALB 用の Security Group:ユーザが指定した IP アドレスからの Port 80 通信
・EC2 インスタンス 用の Security Group:ALB 用の Security Group からの Port 80 通信
TargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
VpcId: !Ref VPCId
Name: !Sub ${AWS::StackName}-TG
Protocol: HTTP
Port: 80
HealthCheckProtocol: HTTP
HealthCheckPath: /
HealthCheckPort: traffic-port
HealthyThresholdCount: 5
UnhealthyThresholdCount: 2
HealthCheckTimeoutSeconds: 5
HealthCheckIntervalSeconds: 30
Matcher:
HttpCode: 200
Targets:
- Id: !Ref EC2Instance
Port: 80
ALB で使用するターゲットグループを作成します
※ヘルスチェックの設定に関しては細かいのでここでは割愛します
・VpcId: ターゲットグループを作成する VPC の ID を指定します
・Targets: ターゲットの ID とポートを指定します
→ 今回は 作成した EC2 インスタンスを !Ref で指定します
InternetALB:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: !Sub ${AWS::StackName}-ALB
Scheme: internet-facing
LoadBalancerAttributes:
- Key: deletion_protection.enabled
Value: false
- Key: idle_timeout.timeout_seconds
Value: 4000
SecurityGroups:
- !Ref ALBSecurityGroup
Subnets:
- !Ref PublicSubnet1Id
- !Ref PublicSubnet2Id
ALB を作成します
・Scheme: ALB を内部/外部用にするかを指定します
→ デフォルトでは internet-facing となっているため今回は指定しなくても問題ありません
・LoadBalancerAttributes: ALB の属性を設定します
→ 今回は削除保護を無効化、アイドルタイムアウトを 4000秒にしています
・SecurityGroups: ALB にアタッチする Security Group の ID を指定します
→ 今回は上記で作成するものを !Ref で指定します
※リスト形式で記載する必要があるため注意
・Subnets: EC2 インスタンスをデプロイするサブネットの ID を指定します
※ALB では 2つ以上のサブネットにデプロイする必要があります
※リスト形式で記載する必要があるため注意
ALBListenerHTTP:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
Port: 80
Protocol: HTTP
DefaultActions:
- TargetGroupArn: !Ref TargetGroup
Type: forward
LoadBalancerArn: !Ref InternetALB
ALB で使用するリスナーを作成します
・Port: リスナーの受信ポートを指定します
・Protocol: リスナーの受信プロトコルを指定します
・DefaultActions: リスナーがアクセスされた際の動作を指定します
→ 今回は上記で作成したターゲットグループにフォワードします
・LoadBalancerArn: リスナーを設定する ALB の ARN を指定します
→ 今回は上記で作成した ALB の ARN を !Ref で指定します
Outputs:
HTTPWebSiteURL:
Value: !GetAtt InternetALB.DNSName
Web サーバのアクセス用の URL を出力します
ALB の URL を出力する場合、組み込み関数の !GetAtt を使用し .DNSName で取得します
上記以外の説明
テンプレートの詳細で上記で解説していないものに関して、
[CloudFormation] SSM アクセスができる EC2 インスタンスを作成で使用したテンプレートを編集しているのでこちらの記事も併せて確認ください
参考
Discussion