AWS再入門2018 上級者でもたまに忘れる!? AWS CloudFormation 小ネタ編
こんにちは。池田です。札幌では八重桜がちらほら咲き始めてきました。道産子にもようやく屋外焼肉シーズンがやってまいりました。
※ ハマりポイントというよりは「これ忘れることあるよねー」という意図でしたので、タイトルと本文の一部を追記・変更しました。
はじめに
早速ですが問題です。マネジメントコンソールにてテスト用の新規VPNとサブネット2つを作成し、下記の(某所からコピーしてちょっとカスタマイズした)AWS CloudFormationテンプレート(225行)を実行したところ、図のようなエラーにより失敗してしまいました。その原因と、最も簡単に解決するためのテンプレート修正方法を見つけられるでしょうか。制限時間は5分です。ではスクロールし過ぎのネタバレに気をつけてご覧ください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | AWSTemplateFormatVersion: 2010-09-09 Description: >- Test Template. Parameters: VpcId: Type: 'AWS::EC2::VPC::Id' Description: VpcId of your existing Virtual Private Cloud (VPC) Subnets: Type: 'List<AWS::EC2::Subnet::Id>' Description: The list of SubnetIds in your Virtual Private Cloud (VPC) InstanceType: Description: WebServer EC2 instance type Type: String Default: t2.micro AllowedValues: - t2.nano - t2.micro - t2.small ConstraintDescription: must be a valid EC2 instance type. KeyName: Description: Name of an existing EC2 KeyPair to enable SSH access to the instances Type: 'AWS::EC2::KeyPair::KeyName' ConstraintDescription: must be the name of an existing EC2 KeyPair. SSHLocation: Description: The IP address range that can be used to SSH to the EC2 instances Type: String MinLength: '9' MaxLength: '18' Default: 0.0.0.0/0 AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})' ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Mappings: AWSInstanceType2Arch: t2.nano: Arch: HVM64 t2.micro: Arch: HVM64 t2.small: Arch: HVM64 AWSInstanceType2NATArch: t2.nano: Arch: NATHVM64 t2.micro: Arch: NATHVM64 t2.small: Arch: NATHVM64 AWSRegionArch2AMI: ap-northeast-1: PV64: ami-3e42b65f HVM64: ami-ceafcba8 HVMG2: ami-edfd658b Resources: WebServerGroup: Type: 'AWS::AutoScaling::AutoScalingGroup' Properties: VPCZoneIdentifier: !Ref Subnets LaunchConfigurationName: !Ref LaunchConfig MinSize: '2' MaxSize: '2' TargetGroupARNs: - !Ref ALBTargetGroup CreationPolicy: ResourceSignal: Timeout: PT15M UpdatePolicy: AutoScalingRollingUpdate: MinInstancesInService: '1' MaxBatchSize: '1' PauseTime: PT15M WaitOnResourceSignals: 'true' LaunchConfig: Type: 'AWS::AutoScaling::LaunchConfiguration' Metadata: Comment: Install a simple application 'AWS::CloudFormation::Init' : config: packages: yum: httpd: [ ] files: /var/www/html/index .html: content: !Join - |+ - - >- <h3>You have successfully launched the AWS CloudFormation test.</h3> mode: '000644' owner: root group: root /etc/cfn/cfn-hup .conf: content: !Join - '' - - | [ main ] - stack= - !Ref 'AWS::StackId' - |+ - region= - !Ref 'AWS::Region' - |+ mode: '000400' owner: root group: root /etc/cfn/hooks.d/cfn-auto-reloader .conf: content: !Join - '' - - | [ cfn-auto-reloader-hook ] - | triggers=post.update - > path=Resources .LaunchConfig.Metadata.AWS: : CloudFormation : : Init - 'action=/opt/aws/bin/cfn-init -v ' - ' --stack ' - !Ref 'AWS::StackName' - ' --resource LaunchConfig ' - ' --region ' - !Ref 'AWS::Region' - |+ - | runas=root mode: '000400' owner: root group: root services: sysvinit: httpd: enabled: 'true' ensureRunning: 'true' cfn-hup: enabled: 'true' ensureRunning: 'true' files: - /etc/cfn/cfn-hup.conf - /etc/cfn/hooks.d/cfn-auto-reloader.conf Properties: ImageId: !FindInMap - AWSRegionArch2AMI - !Ref 'AWS::Region' - !FindInMap - AWSInstanceType2Arch - !Ref InstanceType - Arch SecurityGroups: - !Ref InstanceSecurityGroup InstanceType: !Ref InstanceType KeyName: !Ref KeyName UserData: !Base64 'Fn::Join' : - '' - - | #!/bin/bash -xe - | yum update -y aws-cfn-bootstrap - '/opt/aws/bin/cfn-init -v ' - ' --stack ' - !Ref 'AWS::StackName' - ' --resource LaunchConfig ' - ' --region ' - !Ref 'AWS::Region' - |+ - '/opt/aws/bin/cfn-signal -e $? ' - ' --stack ' - !Ref 'AWS::StackName' - ' --resource WebServerGroup ' - ' --region ' - !Ref 'AWS::Region' - |+ ApplicationLoadBalancer: Type: 'AWS::ElasticLoadBalancingV2::LoadBalancer' Properties: Subnets: !Ref Subnets SecurityGroups: - !Ref InstanceSecurityGroup ALBListener: Type: 'AWS::ElasticLoadBalancingV2::Listener' Properties: DefaultActions: - Type : forward TargetGroupArn: !Ref ALBTargetGroup LoadBalancerArn: !Ref ApplicationLoadBalancer Port: '80' Protocol: HTTP ALBTargetGroup: Type: 'AWS::ElasticLoadBalancingV2::TargetGroup' Properties: HealthCheckIntervalSeconds: 30 HealthCheckTimeoutSeconds: 5 HealthyThresholdCount: 3 Port: 80 Protocol: HTTP UnhealthyThresholdCount: 5 VpcId: !Ref VpcId InstanceSecurityGroup: Type: 'AWS::EC2::SecurityGroup' Properties: GroupDescription: Enable SSH access and HTTP access on the inbound port SecurityGroupIngress: - IpProtocol : tcp FromPort: '80' ToPort: '80' CidrIp: !Ref SSHLocation - IpProtocol : tcp FromPort: '22' ToPort: '22' CidrIp: !Ref SSHLocation VpcId: !Ref VpcId Outputs: URL: Description: URL of the website Value: !Join - '' - !GetAtt - ApplicationLoadBalancer - DNSName |
正解
原因はわかりましたでしょうか。実は初心者に限らずとも、つい見落としがちなミスが原因でした。
143 144 145 146 147 148 149 150 151 | Properties: AssociatePublicIpAddress: true ImageId: !FindInMap - AWSRegionArch2AMI - !Ref 'AWS::Region' - !FindInMap - AWSInstanceType2Arch - !Ref InstanceType - Arch |
AssociatePublicIpAddress
VPC の Amazon EC2 インスタンスで、Auto Scaling グループのインスタンスがパブリック IP アドレスを受け取るかどうかを示します。true の場合には、Auto Scaling の各インスタンスが一意のパブリック IP を受け取ります。
AWS::AutoScaling::LaunchConfiguration
そうです。CloudFormationにより作成されたEC2インスタンスにパブリックIPアドレスが割り当てられていないことで、yumコマンドが完了せず、インスタンス作成のsuccessシグナルが送られないままタイムアウトが発生し、ロールバックされていたのでした。
まとめ
慣れたつもりでヒョイヒョイっとコピペして使うと、こういううっかりミスに遭遇して(マネジメントコンソールに表示される簡易エラー表示からは連想できずに)ハマってしまうことがあるよね。新規作成したVPC側の設定忘れはよくやらかすわー。などという話題がオフィスで出たのでご紹介でした。
※ 他にもサブネットを作成するときにPublic IPの自動付与をしておく、NAT経由で外部との通信が可能となるようにするなど、複数の解消方法はありますが、もっとも簡単な(テンプレートに1行追記するだけで済む)方法を今回の正解とさせていただきました。