When your CloudFormation template defines package installations through AWS::CloudFormation::Init
metadata but the packages don't actually get installed on the EC2 instance, you're likely missing critical bootstrapping components. Here's a complete technical breakdown.
The packages section in your metadata only defines what to install - you still need to trigger the installation process during instance launch. Add this UserData section to your instance definition:
"UserData": {
"Fn::Base64": {
"Fn::Join": [
"",
[
"#!/bin/bash\n",
"apt-get update -y\n",
"apt-get install -y awscli\n",
"/usr/local/bin/aws s3 cp s3://aws-codedeploy-us-east-1/latest/install . --region us-east-1\n",
"chmod +x ./install\n",
"./install auto\n",
"/opt/aws/bin/cfn-init -v ",
" --stack ", { "Ref": "AWS::StackName" },
" --resource Tomcat ",
" --region ", { "Ref": "AWS::Region" }, "\n",
"/opt/aws/bin/cfn-signal -e $? ",
" --stack ", { "Ref": "AWS::StackName" },
" --resource Tomcat ",
" --region ", { "Ref": "AWS::Region" }, "\n"
]
]
}
}
Here's a corrected version that includes all necessary components for package installation:
{
"Resources": {
"TomcatInstance": {
"Type": "AWS::EC2::Instance",
"Properties": {
"ImageId": "ami-0abcdef1234567890",
"InstanceType": "t2.micro",
"UserData": {
"Fn::Base64": {
"Fn::Join": [
"",
[
"#!/bin/bash\n",
"apt-get update -y\n",
"apt-get install -y python-setuptools\n",
"mkdir -p /opt/aws/bin\n",
"easy_install --script-dir /opt/aws/bin https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
"/opt/aws/bin/cfn-init -v --stack ", { "Ref": "AWS::StackName" },
" --resource TomcatInstance --region ", { "Ref": "AWS::Region" }, "\n",
"/opt/aws/bin/cfn-signal -e $? --stack ", { "Ref": "AWS::StackName" },
" --resource TomcatInstance --region ", { "Ref": "AWS::Region" }, "\n"
]
]
}
},
"Metadata": {
"AWS::CloudFormation::Init": {
"config": {
"packages": {
"apt": {
"tomcat8": [],
"git": []
}
},
"services": {
"sysvinit": {
"tomcat8": {
"enabled": "true",
"ensureRunning": "true"
}
}
}
}
}
}
}
}
}
}
After deployment, check these logs to troubleshoot:
# View cfn-init execution logs
cat /var/log/cfn-init.log
# Check cloud-init output
cat /var/log/cloud-init-output.log
# Verify package installation
dpkg -l tomcat8 git
- Using outdated AMIs that don't include cloud-init
- Missing IAM permissions for the instance to access CloudFormation metadata
- Not waiting for package installation to complete before running dependent configurations
- Using incorrect package names (e.g., tomcat6 vs tomcat8)
When working with AWS CloudFormation's cfn-init
process, many developers encounter situations where packages specified in the Metadata section fail to install during instance launch. This commonly occurs with:
- APT packages (Ubuntu/Debian)
- YUM packages (Amazon Linux/RHEL)
- Custom installation scripts
Your template shows the package declaration but lacks critical elements for actual execution. Here's what's missing:
\"Resources\": {
\"TomcatInstance\": {
\"Type\": \"AWS::EC2::Instance\",
\"Metadata\": {
\"AWS::CloudFormation::Init\": {
\"config\": {
\"packages\": {
\"apt\": {
\"tomcat8\": [],
\"git\": []
}
}
}
}
},
\"Properties\": {
\"UserData\": {
\"Fn::Base64\": {
\"Fn::Join\": [\"\", [
\"#!/bin/bash\n\",
\"apt-get update -y\n\",
\"/opt/aws/bin/cfn-init -v \",
\" --stack \", {\"Ref\": \"AWS::StackName\"}, \" \",
\" --resource TomcatInstance \",
\" --region \", {\"Ref\": \"AWS::Region\"}, \"\n\",
\"# Signal completion\n\",
\"/opt/aws/bin/cfn-signal -e $? \",
\" --stack \", {\"Ref\": \"AWS::StackName\"}, \" \",
\" --resource TomcatInstance \",
\" --region \", {\"Ref\": \"AWS::Region\"}, \"\n\"
]]
}
}
}
}
}
For package installation to work properly:
- UserData Execution: Must explicitly call
cfn-init
in the instance's UserData - IAM Permissions: The EC2 instance role needs
cloudformation:DescribeStackResource
- Package Availability: Verify packages exist in your distribution's repositories
Here's a functional template demonstrating proper package installation:
{
\"AWSTemplateFormatVersion\": \"2010-09-09\",
\"Resources\": {
\"WebServerInstance\": {
\"Type\": \"AWS::EC2::Instance\",
\"Metadata\": {
\"AWS::CloudFormation::Init\": {
\"configSets\": {
\"install_all\": [\"install_packages\"]
},
\"install_packages\": {
\"packages\": {
\"yum\": {
\"httpd\": [],
\"git\": []
}
},
\"services\": {
\"sysvinit\": {
\"httpd\": {
\"enabled\": \"true\",
\"ensureRunning\": \"true\"
}
}
}
}
}
},
\"Properties\": {
\"ImageId\": \"ami-0c55b159cbfafe1f0\",
\"InstanceType\": \"t2.micro\",
\"UserData\": {
\"Fn::Base64\": {
\"Fn::Join\": [\"\", [
\"#!/bin/bash -xe\n\",
\"# Install cfn bootstrap tools\n\",
\"yum install -y aws-cfn-bootstrap\n\",
\"# Run cfn-init\n\",
\"/opt/aws/bin/cfn-init -v --stack \", {\"Ref\": \"AWS::StackName\"}, \" \",
\"--resource WebServerInstance --region \", {\"Ref\": \"AWS::Region\"}, \" \",
\"--configsets install_all\n\",
\"# Signal completion\n\",
\"/opt/aws/bin/cfn-signal -e $? --stack \", {\"Ref\": \"AWS::StackName\"}, \" \",
\"--resource WebServerInstance --region \", {\"Ref\": \"AWS::Region\"}, \"\n\"
]]
}
},
\"IamInstanceProfile\": {\"Ref\": \"EC2InstanceProfile\"}
}
},
\"EC2InstanceProfile\": {
\"Type\": \"AWS::IAM::InstanceProfile\",
\"Properties\": {
\"Roles\": [{\"Ref\": \"EC2InstanceRole\"}]
}
},
\"EC2InstanceRole\": {
\"Type\": \"AWS::IAM::Role\",
\"Properties\": {
\"AssumeRolePolicyDocument\": {
\"Version\": \"2012-10-17\",
\"Statement\": [{
\"Effect\": \"Allow\",
\"Principal\": {\"Service\": [\"ec2.amazonaws.com\"]},
\"Action\": [\"sts:AssumeRole\"]
}]
},
\"ManagedPolicyArns\": [
\"arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore\",
\"arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy\"
],
\"Policies\": [{
\"PolicyName\": \"CloudFormationAccess\",
\"PolicyDocument\": {
\"Version\": \"2012-10-17\",
\"Statement\": [{
\"Effect\": \"Allow\",
\"Action\": [\"cloudformation:DescribeStackResource\"],
\"Resource\": \"*\"
}]
}
}]
}
}
}
}
If packages still don't install:
- Check
/var/log/cloud-init-output.log
for execution errors - Verify
cfn-init
was actually executed (search logs for "cfn-init") - Ensure your base AMI has the AWS CloudFormation helper scripts installed
- Confirm network connectivity to package repositories