Skip to content

Instantly share code, notes, and snippets.

@amcginlay
Last active August 3, 2021 07:01
Show Gist options
  • Save amcginlay/650dd213ed679dce75baa58e2cfaa8e0 to your computer and use it in GitHub Desktop.
Save amcginlay/650dd213ed679dce75baa58e2cfaa8e0 to your computer and use it in GitHub Desktop.
# use https://amcginlay-cfn.s3.amazonaws.com/cfn-helper-demo-v1.yaml
# Commands to be run from EC2 Instance Connect terminal sessions
# [1] while true; do curl localhost; date; sleep 1; done
# [2] tail -f /var/log/cfn-hup.log
# [3] mysql
# NOTE when applied, a stack policy can prohibit updates to any (*) resources, for example:
# {"Statement" : [{"Effect" : "Deny", "Action" : "Update:*", "Principal": "*", "Resource" : "*"}]}
AWSTemplateFormatVersion: 2010-09-09
Description: cfn-helper-demo.yaml - see https://advancedweb.hu/how-to-use-cfn-init-to-set-up-ec2-instances-with-cloudformation/ and https://gist.github.com/libert-xyz/d1d7186ef3dc7ad23cbfe46eaf3fb27b
Parameters:
LatestAmiId:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
Resources:
# Use EC2 Instance Connect - opening port 22 without a keypair is quicker than assigning IAM policies for SSM
SecurityGroupAllowSSH:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Enable SSH access via port 22
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
WebServer:
Type: AWS::EC2::Instance
# postpone resource complete status until cfn-signal fires within timeout limit
CreationPolicy:
ResourceSignal:
Timeout: PT5M
# metadata is processed whenever cfn-init is invoked
Metadata:
AWS::CloudFormation::Init:
configSets:
setup:
- install_server
install_server:
packages:
yum:
httpd: []
# mariadb-server: []
files:
/var/www/html/index.html:
content: |
Hello world!
mode: "000644"
owner: root
group: root
/etc/cfn/cfn-hup.conf:
content: !Sub |
[main]
stack=${AWS::StackId}
region=${AWS::Region}
interval=1
mode: "000400"
owner: root
group: root
# The user actions that the cfn-hup daemon calls periodically are defined in the hooks.conf configuration file.
# To support composition of several applications deploying change notification hooks, cfn-hup supports a directory named hooks.d that is located in the hooks configuration directory. You can place one or more additional hooks configuration files in the hooks.d directory. The additional hooks files must use the same layout as the hooks.conf file.
/etc/cfn/hooks.d/cfn-auto-reloader.conf:
content: !Sub |
[cfn-auto-reloader-hook]
triggers=post.update
path=Resources.WebServer.Metadata.AWS::CloudFormation::Init
action=/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WebServer --configsets setup --region ${AWS::Region}
runas=root
mode: "000400"
owner: root
group: root
services:
sysvinit:
httpd:
enabled: true
ensureRunning: true
# mariadb:
# enabled: true
# ensureRunning: true
Properties:
ImageId: !Ref LatestAmiId
InstanceType: t2.micro
Tags:
- Key: Name
Value: cfn-helper-demo
SecurityGroupIds:
- !Ref SecurityGroupAllowSSH
UserData:
# runs the cfn-helper scripts
Fn::Base64:
!Sub |
#!/bin/bash -xe
yum update -y aws-cfn-bootstrap
# run the setup once, as per regular UserData
/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WebServer --configsets setup --region ${AWS::Region} || error_exit "Failed to run cfn-init"
# kick off the daemon to watch for metadata updates
/opt/aws/bin/cfn-hup || error_exit 'Failed to run cfn-hup'
# signal that WebServer is ready (CreationPolicy)
/opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource WebServer --region ${AWS::Region} || error_exit "Failed to run cfn-signal"
# you may query the current metadata at any time with the following
# /opt/aws/bin/cfn-get-metadata --stack <STACK_NAME> --resource WebServer --region <REGION>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment