この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは。池田です。札幌では八重桜がちらほら咲き始めてきました。道産子にもようやく屋外焼肉シーズンがやってまいりました。 ※ ハマりポイントというよりは「これ忘れることあるよねー」という意図でしたので、タイトルと本文の一部を追記・変更しました。
はじめに
早速ですが問題です。マネジメントコンソールにてテスト用の新規VPNとサブネット2つを作成し、下記の(某所からコピーしてちょっとカスタマイズした)AWS CloudFormationテンプレート(225行)を実行したところ、図のようなエラーにより失敗してしまいました。その原因と、最も簡単に解決するためのテンプレート修正方法を見つけられるでしょうか。制限時間は5分です。ではスクロールし過ぎのネタバレに気をつけてご覧ください。
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
- ''
- - 'http://'
- !GetAtt
- ApplicationLoadBalancer
- DNSName
正解
原因はわかりましたでしょうか。実は初心者に限らずとも、つい見落としがちなミスが原因でした。
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行追記するだけで済む)方法を今回の正解とさせていただきました。