CloudFormation Template for Creating EC2 with Load Balancer | DevelopersIO
ん-?CloudFormationで動かしてみたけど動かないぞ。Load Balancerの設定が苦手だから試しているのに困ったな。
いろいろと調整をしてみて,最終的に動かせたのはこれ。
最終形態
AWSTemplateFormatVersion: 2010-09-09 Parameters: AvailabilityZone1: Description: AvailabilityZone1 Type: String Default: ap-northeast-1a AvailabilityZone2: Description: AvailabilityZone1 Type: String Default: ap-northeast-1c ImageId: Description: ami-id Type: String Default: ami-052c9af0c988f8bbd Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: VPC1 InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: VPC Internet Gateway AttachGateway: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref VPC InternetGatewayId: !Ref InternetGateway PublicSubnet1: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.1.0/24 AvailabilityZone: !Ref AvailabilityZone1 MapPublicIpOnLaunch: true Tags: - Key: Name Value: Public Subnet 1 PrivateSubnet1: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.2.0/24 MapPublicIpOnLaunch: false AvailabilityZone: !Ref AvailabilityZone1 Tags: - Key: Name Value: Private Subnet 1 PublicSubnet2: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.3.0/24 AvailabilityZone: !Ref AvailabilityZone2 MapPublicIpOnLaunch: true Tags: - Key: Name Value: Public Subnet 2 PrivateSubnet2: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.4.0/24 AvailabilityZone: !Ref AvailabilityZone2 MapPublicIpOnLaunch: false Tags: - Key: Name Value: Private Subnet 2 PublicRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: Public Route Table PublicRoute: Type: AWS::EC2::Route Properties: RouteTableId: !Ref PublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway PublicSubnetRouteTableAssociation1: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnet1 RouteTableId: !Ref PublicRouteTable PublicSubnetRouteTableAssociation2: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnet2 RouteTableId: !Ref PublicRouteTable PrivateRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: Private Route Table PrivateSubnetRouteTableAssociation1: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnet1 RouteTableId: !Ref PrivateRouteTable PrivateSubnetRouteTableAssociation2: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnet2 RouteTableId: !Ref PrivateRouteTable ELBSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: ELB Security Group VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 EC2SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: EC2 Security Group VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 0.0.0.0/0 SSMRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - 'sts:AssumeRole' Path: / Policies: - PolicyName: ssmAccess PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - "ssmmessages:CreateDataChannel" - "ssm:UpdateInstanceInformation" - "ssmmessages:OpenDataChannel" - "ssmmessages:OpenControlChannel" - "ssmmessages:CreateControlChannel" Resource: '*' SSMInstanceProfile: Type: 'AWS::IAM::InstanceProfile' Properties: Path: / Roles: - !Ref SSMRole #EC2 Instances EC2Instance1: Type: AWS::EC2::Instance Properties: ImageId: !Ref ImageId InstanceType: t2.micro SecurityGroupIds: - !Ref EC2SecurityGroup IamInstanceProfile: !Ref SSMInstanceProfile SubnetId: !Ref PublicSubnet1 Tags: - Key: Name Value: app-server-1 UserData: Fn::Base64: !Sub | #!/bin/bash yum update -y yum install -y httpd systemctl start httpd systemctl enable httpd echo "<h1>Hello from Region !Ref AvailabilityZone1</h1>" > /var/www/html/index.html EC2Instance2: Type: AWS::EC2::Instance Properties: ImageId: !Ref ImageId InstanceType: t2.micro SecurityGroupIds: - !Ref EC2SecurityGroup IamInstanceProfile: !Ref SSMInstanceProfile SubnetId: !Ref PublicSubnet2 Tags: - Key: Name Value: app-server-2 UserData: Fn::Base64: !Sub | #!/bin/bash yum update -y yum install -y httpd systemctl start httpd systemctl enable httpd echo "<h1>Hello from Region !Ref AvailabilityZone2</h1>" > /var/www/html/index.html EC2TargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: HealthCheckIntervalSeconds: 30 HealthCheckProtocol: HTTP HealthCheckTimeoutSeconds: 15 HealthyThresholdCount: 5 Matcher: HttpCode: '200' Name: EC2TargetGroup Port: 80 Protocol: HTTP TargetGroupAttributes: - Key: deregistration_delay.timeout_seconds Value: '20' Targets: - Id: !Ref EC2Instance1 Port: 80 - Id: !Ref EC2Instance2 Port: 80 UnhealthyThresholdCount: 3 VpcId: !Ref VPC ALBListener: Type: AWS::ElasticLoadBalancingV2::Listener Properties: DefaultActions: - Type: forward TargetGroupArn: !Ref EC2TargetGroup LoadBalancerArn: !Ref ApplicationLoadBalancer Port: 80 Protocol: HTTP ApplicationLoadBalancer: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Scheme: internet-facing Subnets: - !Ref PublicSubnet1 - !Ref PublicSubnet2 SecurityGroups: - !GetAtt ELBSecurityGroup.GroupId
感想
設定手順通りに上から書いているはずなので,後半の設定を消したテンプレートでstackを作ったあと,消した部分をコピペしながらstackのupdateをしていけば,「どこで何が行われているか」「手作業だったらどうやるか」を確認できる。
最初のDeveloperIOの記事はこれはこれでありがたい。一撃で動かないからこそ,いろいろ調査する勉強になる。
なお,このテンプレートはセキュリティ的にはまだ設定が緩い。
あとはAuto Scalingまでいけば,負荷分散系の把握は一段落かな。
よく「好きなAWSサービスは〇〇です」という紹介をしている人がいる。
私は,技術に中立であることが講師の信頼に関わると思っているのでそういう自己紹介はしないが,あえて言うならAWSではCloudFormation,AWS CLIあたりが重要技術だと考えている。
「他のAPIを叩くAPI」は技術の寿命が長い上,統一的な観点から他の技術を把握できる。