I am starting to use CloudFormation for orchestration/provisioning and I see there are two ways to install packages:
First way is with a bash script in userdata section, example:
"UserData": {
"Fn::Base64": {
"Fn::Join": [
"\n",
[
"#!/bin/bash",
"apt-get update",
"apt-get upgrade -y",
"apt-get install apache2 -y",
"echo \"<html><body><h1>Welcome</h1>\" > /var/www/index.html",
Another way is to use cfn-init:
"UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
"yum update -y aws-cfn-bootstrap\n",
"# Install the files and packages from the metadata\n",
"/opt/aws/bin/cfn-init -v ",
" --stack ", { "Ref" : "AWS::StackName" },
" --resource WebServerInstance ",
" --configsets Install ",
" --region ", { "Ref" : "AWS::Region" }, "\n"
]]}}
Is there any reasons to use cfn-init and not bash in UserData?
Actually it makes no difference if you use bash in UserData or cfn-init. But to use cnf-init you need to install the package aws-cfn-bootstrap as you have already done and also need to define
cfn-init is like a clean way to get things done instead of you needing to do yum install in bash of UserData though you will get the same outcome from both the methods.