AWS CloudFormation模板创建遇WaitCondition验证错误求助
Let's break down the issues in your CloudFormation template that are causing the WaitCondition failure, and walk through the fixes step by step:
1. Duplicate File Entry in CloudFormation Init
Your AWS::CloudFormation::Init config has two identical entries for /var/www/html/index.html. This is invalid—you can't define the same file twice in the files section. This causes cfn-init to crash, which triggers the error signal sent to your WaitCondition.
Fix: Remove one of the duplicate entries for /var/www/html/index.html.
2. Wrong Resource Name in cfn-init Command
In your EC2 instance's UserData, the cfn-init command uses -r FormEngine, but your EC2 instance resource is named WebServer. This mismatch means cfn-init can't locate the correct initialization configuration, leading to a failure.
Fix: Change -r FormEngine to -r WebServer in the UserData script.
3. Unsafe IAM Permissions & Deprecated Access Key Usage
Using an IAM user with full * permissions is a security risk. Additionally, passing access keys directly in UserData is not recommended—instead, use an IAM Instance Role to grant the EC2 instance permission to interact with CloudFormation.
Fix: Replace the CfnUser and HostKeys resources with an IAM Instance Role that has minimal permissions for cfn-init and cfn-signal.
Fixed CloudFormation Template
Here's the corrected template incorporating all the fixes above:
{ "AWSTemplateFormatVersion": "2010-09-09", "Parameters": { "KeyName": { "Description": "Name of an existing EC2 KeyPair to enable SSH access to the instances", "Type": "AWS::EC2::KeyPair::KeyName" }, "InstanceType": { "Description": "FormEngine EC2 instance type", "Type": "String", "Default": "t2.micro" } }, "Mappings": { "AWSInstanceType2Arch": { "t2.micro": { "Arch": "64" } }, "AWSRegionArch2AMI": { "us-west-2": { "64": "ami-f2d3638a" } } }, "Resources": { "WebServerGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "Enable SSH and HTTP access", "SecurityGroupIngress": [ { "IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "CidrIp": "0.0.0.0/0" }, { "IpProtocol": "tcp", "FromPort": "80", "ToPort": "80", "CidrIp": "0.0.0.0/0" } ] } }, "CloudFormationInitRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }, "Path": "/", "Policies": [ { "PolicyName": "CloudFormationInitAccess", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "cloudformation:DescribeStackResource", "cloudformation:SignalResource" ], "Resource": { "Ref": "AWS::StackId" } } ] } } ] } }, "WebServerInstanceProfile": { "Type": "AWS::IAM::InstanceProfile", "Properties": { "Path": "/", "Roles": [ { "Ref": "CloudFormationInitRole" } ] } }, "WebServer": { "Type": "AWS::EC2::Instance", "Metadata": { "AWS::CloudFormation::Init": { "config": { "packages": { "yum": { "java-1.6.0-openjdk": [], "tomcat6": [], "httpd": [] } }, "files": { "/var/www/html/index.html": { "source": "http://a00807428-lab02/index.html", "mode": "000600", "owner": "apache", "group": "apache" } } } } }, "Properties": { "ImageId": { "Fn::FindInMap": [ "AWSRegionArch2AMI", { "Ref": "AWS::Region" }, { "Fn::FindInMap": [ "AWSInstanceType2Arch", { "Ref": "InstanceType" }, "Arch" ] } ] }, "InstanceType": { "Ref": "InstanceType" }, "SecurityGroups": [ { "Ref": "WebServerGroup" } ], "KeyName": { "Ref": "KeyName" }, "IamInstanceProfile": { "Ref": "WebServerInstanceProfile" }, "Tags": [ { "Key": "Name", "Value": "WebServer" } ], "UserData": { "Fn::Base64": { "Fn::Join": [ "", [ "#!/bin/bash -v\n", "date > /home/ec2-user/starttime\n", "yum update -y aws-cfn-bootstrap\n", "## Error reporting helper function\n", "function error_exit\n", "{\n", " /opt/aws/bin/cfn-signal -e 1 -r \"$1\" '", { "Ref": "WaitHandle" }, "'\n", " exit 1\n", "}\n", "## Initialize CloudFormation bits\n", "/opt/aws/bin/cfn-init -v -s ", { "Ref": "AWS::StackId" }, " -r WebServer", " --region ", { "Ref": "AWS::Region" }, " > /tmp/cfn-init.log 2>&1 || error_exit $(</tmp/cfn-init.log)\n", "# Configure Apache HTTPD\n", "chkconfig httpd on\n", "chkconfig --level 345 httpd on\n", "# Start servers\n", "/etc/init.d/httpd start\n", "# Send signal to WaitHandle that the setup is completed\n", "/opt/aws/bin/cfn-signal", " -e 0", " '", { "Ref": "WaitHandle" }, "'", "\n", "date > /home/ec2-user/stoptime" ] ] } } } }, "WaitHandle": { "Type": "AWS::CloudFormation::WaitConditionHandle" }, "WaitCondition": { "Type": "AWS::CloudFormation::WaitCondition", "DependsOn": "WebServer", "Properties": { "Handle": { "Ref": "WaitHandle" }, "Timeout": "1200" } }, "IPAddress": { "Type": "AWS::EC2::EIP" }, "IPAssoc": { "Type": "AWS::EC2::EIPAssociation", "Properties": { "InstanceId": { "Ref": "WebServer" }, "EIP": { "Ref": "IPAddress" } } } }, "Outputs": { "InstanceIPAddress": { "Value": { "Ref": "IPAddress" }, "Description": "public IP address of the new WebServer" }, "InstanceName": { "Value": { "Fn::GetAtt": [ "WebServer", "PublicDnsName" ] }, "Description": "public DNS name of the new WebServer" } } }
Additional Validation Steps
After deploying the fixed template:
- Check the EC2 instance's system logs (via the AWS Console or
aws ec2 get-console-output) to confirmcfn-initruns successfully. - Verify that Apache is running with
service httpd statusvia SSH. - Confirm the WaitCondition receives the success signal within the 1200-second timeout.
内容的提问来源于stack exchange,提问作者user1790618

