{"id":1174,"date":"2018-02-24T16:52:15","date_gmt":"2018-02-24T16:52:15","guid":{"rendered":"http:\/\/wiki.thomasandsofia.com\/?p=1174"},"modified":"2018-03-03T19:25:36","modified_gmt":"2018-03-03T19:25:36","slug":"cfn-init-and-ec2-user-data","status":"publish","type":"post","link":"https:\/\/wiki.thomasandsofia.com\/?p=1174","title":{"rendered":"CFN Init and EC2 User Data"},"content":{"rendered":"<p><a href=\"http:\/\/wiki.thomasandsofia.com\/2018\/02\/18\/cloud-formation-main-menu\/\" rel=\"noopener\">Course Main Menu<\/a><\/p>\n<h2>Section 4 Main Menu<\/h2>\n<ul>\n<li><a href=\"#EC2UserDataOverview\">EC2 User Data Overview<\/a><\/li>\n<li><a href=\"#EC2UserDatainCloudFormation\">EC2 User Data &amp; Fn::Base64 in CloudFormation<\/a><\/li>\n<li><a href=\"#CloudFormationInitOverview\">CloudFormation Init Overview<\/a><\/li>\n<li><a href=\"#Packages\">Packages<\/a><\/li>\n<li><a href=\"#GroupsandUsers\">Groups and Users<\/a><\/li>\n<li><a href=\"#Sources\">Sources<\/a><\/li>\n<li><a href=\"#Files\">Files<\/a><\/li>\n<li><a href=\"#FnSub\">Fn::Sub (substitute function)<\/a><\/li>\n<li><a href=\"#Commands\">Commands<\/a><\/li>\n<li><a href=\"#Services\">Services<\/a><\/li>\n<li><a href=\"#CFNInitandSignal\">CFN Init and Signal<\/a><\/li>\n<li><a href=\"#CFNHandsOn\">CFN Hands On<\/a><\/li>\n<li><a href=\"#Summary\">Summary<\/a><\/li>\n<\/ul>\n<p><a name=\"EC2UserDataOverview\"><\/a><\/p>\n<h2>EC2 User Data Overview<\/h2>\n<p><a href=\"https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8139272?start=0\" target=\"_blank\" rel=\"noopener\">https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8139272?start=0<\/a><\/p>\n<h3>What is CFN-Init and EC2-user data<\/h3>\n<ul>\n<li>Many of the CF templates will be about provisioning computing resources in your AWS Cloud<\/li>\n<li>These resources can be either:\n<ul>\n<li>EC2 Instances<\/li>\n<li>AutoScaling Groups<\/li>\n<\/ul>\n<\/li>\n<li>Usually, you want the instances to be self configured so that they can perform the job they are supposed to perform.<\/li>\n<li>You can fully automate your EC2 fleet state with CloudFormation Init.<\/li>\n<\/ul>\n<h3>EC2 User data<\/h3>\n<ul>\n<li>This is the area of the AWS Console under EC2 Provisioning where you upload\/enter your boot scripts<\/li>\n<\/ul>\n<p>Example:<\/p>\n<pre>#!\/bin\/bash\r\nyum update -y\r\nyum install -y httpd24 php56 mysql55-server php56-mysqlnd\r\nservice httpd start\r\nchkconfig httpd on\r\ngroupadd www\r\nusermod -a -G www ec2-user\r\nchown -R root:www \/var\/www\r\nchmod 2775 \/var\/www\r\nfind \/var\/www -type d -exec chmod 2775 {} +\r\nfind \/var\/www -type f -exec chmod 0664 {} +\r\necho \"&lt;?php phpinfo(); ?&gt;\" &gt; \/var\/www\/html\/phpinfo.php<\/pre>\n<p><a name=\"&quot;EC2UserDatainCloudFormation\"><\/a><\/p>\n<h2>EC2 User Data &amp; Fn::Base64 in CloudFormation<\/h2>\n<p><a href=\"https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8162182?start=0\" target=\"_blank\" rel=\"noopener\">https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8162182?start=0<\/a><\/p>\n<h3>Same Script as above, using CloudFormation and Fn::Base64<\/h3>\n<h4>General Outline<\/h4>\n<pre>Resources:\r\n   ResourceID:\r\n      Properties:\r\n         UserData:\r\n            Fn::Base64: |\r\n               #! \/bin\/bash\r\n               ...<\/pre>\n<h4>Example:<\/h4>\n<pre>Resources:\r\n  WebServer:\r\n    Type: AWS::EC2::Instance\r\n    Properties:\r\n      UserData:\r\n        Fn::Base64: <strong><span style=\"color: #ff0000;\">|<\/span><\/strong>\r\n           #!\/bin\/bash\r\n           yum update -y\r\n           yum install -y httpd24 php56 mysql55-server php56-mysqlnd\r\n           service httpd start\r\n           chkconfig httpd on\r\n           groupadd www\r\n           usermod -a -G www ec2-user\r\n           chown -R root:www \/var\/www\r\n           chmod 2775 \/var\/www\r\n           find \/var\/www -type d -exec chmod 2775 {} +\r\n           find \/var\/www -type f -exec chmod 0664 {} +\r\n           echo \"<!--?php phpinfo(); ?-->\" &gt; \/var\/www\/html\/phpinfo.php\r\n<\/pre>\n<div class=\"notice\">Notice the red <strong><span style=\"color: #ff0000;\">|<\/span><\/strong> symbol in the YAML code.\u00a0 This symbol in YAML means &#8220;post everything as is, including all line breaks.&#8221;<\/div>\n<p><a name=\"CloudFormationInitOverview\"><\/a><\/p>\n<h2>CloudFormation Init Overview<\/h2>\n<p><a href=\"https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8139294?start=0\" target=\"_blank\" rel=\"noopener\">https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8139294?start=0<\/a><\/p>\n<h4>Syntax<\/h4>\n<pre>cfn-init --stack|-s stack.name.or.id \\\r\n         --resource|-r logical.resource.id \\\r\n         --region region\r\n         --access-key access.key \\\r\n         --secret-key secret.key \\\r\n         --role rolename\\\r\n         --credential-file|-f credential.file \\\r\n         --configsets|-c config.sets \\\r\n         --url|-u service.url \\\r\n         --http-proxy HTTP.proxy \\\r\n         --https-proxy HTTPS.proxy \\\r\n         --verbose|-v<\/pre>\n<p>&nbsp;<\/p>\n<h3>The Problems with EC2 User Data<\/h3>\n<ul>\n<li>What if you have a very large instance configuration\n<ul>\n<li>UserData only allows a certain number of characters<\/li>\n<\/ul>\n<\/li>\n<li>What if you want to evolve the state of the EC2 instance without terminating it and creating a new one?<\/li>\n<li>How do we make our EC2 user data more readable?<\/li>\n<li>How do we know or signal that our CE2 user-data script actually completed successfully?<\/li>\n<\/ul>\n<h3>CloudFormation Helper Scripts<\/h3>\n<ul>\n<li>There are 4 Python scrips that come directly on Amazon Linux AMI, or can be installed using yum on non-Amazon Linux\n<ul>\n<li><strong>cfn-init<\/strong>\n<ul>\n<li>Used to retrieve and interpret the resource metadata, installing packages, creating files and starting services<\/li>\n<\/ul>\n<\/li>\n<li><strong>cfn-signal<\/strong>\n<ul>\n<li>A simple wrapper to signal an AWS CF CreationPolicy or WaitCondition, enabling you to synchronize other resources in the stack with the application being ready.<\/li>\n<\/ul>\n<\/li>\n<li><strong>chn-get-metadata<\/strong>\n<ul>\n<li>A wrapper scrip making it easy to retrieve either all metadata defined for a resource or path to a specific key or subtree of the resource metadata.<\/li>\n<\/ul>\n<\/li>\n<li><strong>cfn-hup<\/strong>\n<ul>\n<li>A daemon to check for updates to metadata and execute custom hooks when the changes are detected.<\/li>\n<li><em>#This seems very similar to a cron job.<\/em><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>Usual flow:\n<ul>\n<li>cfn-init<\/li>\n<li>cfn-signal<\/li>\n<li>Optionally cfn-hup<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3>AWS::CloudFormation::Init pt.1<\/h3>\n<ul>\n<li>A config contains the following and is executed in that order:\n<ul>\n<li>Packages: Install a list of packages on the Linux OS (mysql, wordpress, etc.)<\/li>\n<li>Groups: defines user groups<\/li>\n<li>Users: define users and which group they belong to<\/li>\n<li>Sources: download an archive file and place it on the ec2 instance (tar, zip, bz2)<\/li>\n<li>Files: create files on the ec2 instance using inline or can be pulled from a URL<\/li>\n<li>Commands: run a series of commands<\/li>\n<li>Services: launch a list of sysvinit<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h4>General Outline<\/h4>\n<pre>Resources:\r\n   ResourceID:\r\n      Metadata:\r\n         AWS::CloudFormation::Init:\r\n            config:               #! \/bin\/bash\r\n               packages:\r\n                  ...<\/pre>\n<h4>Example:<\/h4>\n<pre>Resources:\r\n  MyInstance:\r\n    Type: \"AWS::EC2::Instance\"\r\n    Metadata:\r\n      AWS::CloudFormation::Init:\r\n        config:\r\n          packages:\r\n            :\r\n          groups:\r\n            :\r\n          users:\r\n            :\r\n          sources:\r\n            :\r\n          files:\r\n            :\r\n          commands:\r\n            :\r\n          services:\r\n            :\r\n    Properties:\r\n      :\r\n<\/pre>\n<h3>AWS::CloudFormation::Init pt.2<\/h3>\n<ul>\n<li>You can have multiple configs in your CloudFormation::Init<\/li>\n<li>You create configsets with multiple configs<\/li>\n<li>You invoke config sets from your ec2-user data<\/li>\n<\/ul>\n<p><a name=\"Packages\"><\/a><\/p>\n<h2>Packages<\/h2>\n<p><a href=\"https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8139306?start=0\" target=\"_blank\" rel=\"noopener\">https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8139306?start=0<\/a><\/p>\n<ul>\n<li>You can install packages from the following repositories:\n<ul>\n<li>apt<\/li>\n<li>msi<\/li>\n<li>python<\/li>\n<li>rpm<\/li>\n<li>rubygems<\/li>\n<li>yum<\/li>\n<\/ul>\n<\/li>\n<li>Packages are processed in the following order:\n<ul>\n<li>rpm<\/li>\n<li>yum\/apt<\/li>\n<li>rubygems<\/li>\n<li>python<\/li>\n<\/ul>\n<\/li>\n<li>You can specify a version, or no version (empty array) to get the latest version<\/li>\n<\/ul>\n<pre>rpm:\r\n  epel: \"http:\/\/download.fedoraproject.org\/pub\/epel\/5\/i386\/epel-release-5-4.noarch.rpm\"\r\nyum:\r\n  httpd: []\r\n  php: []\r\n  wordpress: []\r\nrubygems:\r\n  chef:\r\n    - \"0.10.2\" <a name=\"GroupsandUsers\"><\/a><\/pre>\n<p>Example from script:<\/p>\n<pre>  WebServerHost:\r\n    Type: AWS::EC2::Instance\r\n    Metadata:\r\n      Comment: Install a simple PHP application\r\n      AWS::CloudFormation::Init:\r\n        config:\r\n          packages:\r\n            yum:\r\n              httpd: []\r\n              php: []\r\n          groups:\r\n            ...<\/pre>\n<h2>Groups and Users<\/h2>\n<p><a href=\"https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8139308?start=0\" target=\"_blank\" rel=\"noopener\">https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8139308?start=0<\/a><\/p>\n<ul>\n<li>If you want to have multiple users and groups (with an optional gid) in your ec2 instance, you and do the following.<\/li>\n<li>Let&#8217;s add groups and users to our CloudFormation Init Metadata<\/li>\n<\/ul>\n<pre>groups:\r\n  groupOne: {}\r\n  groupTwo:\r\n    gid: \"45\"\r\nusers:\r\n  myUser:\r\n    groups:\r\n      - \"groupOne\"\r\n      - \"groupTwo\"\r\n    uid: \"50\"\r\n    homeDir: \"\/tmp\"\r\n<\/pre>\n<p>Example from script:<\/p>\n<pre>  WebServerHost:\r\n    Type: AWS::EC2::Instance\r\n    Metadata:\r\n      Comment: Install a simple PHP application\r\n      AWS::CloudFormation::Init:\r\n        config:\r\n          packages:\r\n            ...\r\n          groups:\r\n            apache: {}\r\n          users:\r\n            \"apache\":\r\n              groups:\r\n                - \"apache\"\r\n          sources:\r\n            ...<\/pre>\n<p><a name=\"Sources\"><\/a><\/p>\n<h2>Sources<\/h2>\n<p><a href=\"https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8139310?start=0\" target=\"_blank\" rel=\"noopener\">https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8139310?start=0<\/a><\/p>\n<h4>In short, these are used to download and extract archived (.zip, .tar, .tgz, etc.)<\/h4>\n<ul>\n<li>We can download whole compressed archives from the web and unpack them on the instance directly<\/li>\n<li>It is very handy if you:\n<ul>\n<li>Have a set of standardized scripts for your instances that you store in S3 for example<\/li>\n<li>Want to download a whole github project directly on your instance.<\/li>\n<\/ul>\n<\/li>\n<li>Each source is set in a key: value comfiguration\n<ul>\n<li>The key is the location of the unpacked source (Where you download to)<\/li>\n<li>The value is the url of the file<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<pre>sources:\r\n  \/etc\/puppet: \"https:\/\/github.com\/user1\/cfn-demo\/tarball\/master\"\r\n  \/etc\/myapp: \"https:\/\/s3.amazonaws.com\/mybucket\/myapp.tar.gz\"<\/pre>\n<p>Example from script:<\/p>\n<pre>  WebServerHost:\r\n    Type: AWS::EC2::Instance\r\n    Metadata:\r\n      Comment: Install a simple PHP application\r\n      AWS::CloudFormation::Init:\r\n        config:\r\n          ...\r\n          sources:\r\n            \"\/home\/ec2-user\/aws-cli\": \"https:\/\/github.com\/aws\/aws-cli\/tarball\/master\"\r\n          ...<\/pre>\n<p><a name=\"Files\"><\/a><\/p>\n<h2>Files<\/h2>\n<p><a href=\"https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8139312?start=0\" target=\"_blank\" rel=\"noopener\">https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8139312?start=0<\/a><\/p>\n<h4>This is pretty cool&#8230; pay close attention!<\/h4>\n<ul>\n<li>Files are very powerful as you have full control over any content you want.<\/li>\n<li>They can come from a specific URL, or be written inline<\/li>\n<\/ul>\n<pre>files:\r\n  \/tmp\/setup.mysql:\r\n    content: !Sub |\r\n      CREATE DATABASE ${DBName};\r\n      CREATE USER '${dbuSERNAME}'@'localhost' IDENTIFIED BY '${DBPassword}';\r\n      GRANT ALL ON ${DBName}.* TO '${DBUswername}'.@'localhost';\r\n      FLUSH PRIVILEGES;\r\n    mode\" \"000644\"\r\n    owner: \"root\"\r\n    group: \"root\"<\/pre>\n<h4>Example from script:<\/h4>\n<pre>  WebServerHost:\r\n    Type: AWS::EC2::Instance\r\n    Metadata:\r\n      Comment: Install a simple PHP application\r\n      AWS::CloudFormation::Init:\r\n        config:\r\n          ...\r\n          files:\r\n            \"\/tmp\/cwlogs\/apacheaccess.conf\":\r\n              content: !Sub |\r\n                [general]\r\n                state_file= \/var\/awslogs\/agent-state\r\n                [\/var\/log\/httpd\/access_log]\r\n                file = \/var\/log\/httpd\/access_log\r\n                log_group_name = ${AWS::StackName}\r\n                log_stream_name = {instance_id}\/apache.log\r\n                datetime_format = %d\/%b\/%Y:%H:%M:%S\r\n              mode: '000400'\r\n              owner: apache\r\n              group: apache\r\n            \"\/var\/www\/html\/index.php\":\r\n              content: !Sub |\r\n                <!--?php echo '&lt;\/p&gt; &lt;h1&gt;AWS CloudFormation sample PHP application for ${AWS::StackName}&lt;\/h1&gt; &lt;p&gt;'; ?-->\r\n              mode: '000644'\r\n              owner: apache\r\n              group: apache\r\n            \"\/etc\/cfn\/cfn-hup.conf\":\r\n              content: !Sub |\r\n                [main]\r\n                stack=${AWS::StackId}\r\n                region=${AWS::Region}\r\n              mode: \"000400\"\r\n              owner: \"root\"\r\n              group: \"root\"\r\n            \"\/etc\/cfn\/hooks.d\/cfn-auto-reloader.conf\":\r\n              content: !Sub |\r\n                [cfn-auto-reloader-hook]\r\n                triggers=post.update\r\n                path=Resources.WebServerHost.Metadata.AWS::CloudFormation::Init\r\n                action=\/opt\/aws\/bin\/cfn-init -v --stack ${AWS::StackName} --resource WebServerHost --region ${AWS::Region}\r\n              mode: \"000400\"\r\n              owner: \"root\"\r\n              group: \"root\"\r\n          commands:\r\n            ...<\/pre>\n<p><a name=\"FnSub\"><\/a><\/p>\n<h2>Fn::Sub (substitute function)<\/h2>\n<p><a href=\"https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8139314?start=0\" target=\"_blank\" rel=\"noopener\">https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8139314?start=0<\/a><\/p>\n<ul>\n<li>Fn::Sub or !Sub as a shorthand, is used to substitute variables from a text allowing you to fully customize your templates.<\/li>\n<li>For example, you can combine Fn::Sub with References or AWS Pseudo varables<\/li>\n<li>String must contain ${VariableName} and will substitute them.<\/li>\n<\/ul>\n<p>Syntax Example 1 (less common):<\/p>\n<pre>!Sub\r\n  - <span style=\"color: #ff0000;\"><em>String<\/em><\/span>\r\n  - { <em><span style=\"color: #ff0000;\">Var1Name<\/span><\/em>: <span style=\"color: #ff0000;\"><em>Var1Value<\/em><\/span>, <span style=\"color: #ff0000;\"><em>Var2Name<\/em><\/span>: <span style=\"color: #ff0000;\"><em>Var2Value<\/em><\/span> }<\/pre>\n<p>Syntax Example 2 (more common):<\/p>\n<pre>!Sub <em><span style=\"color: #ff0000;\">String<\/span><\/em><\/pre>\n<p><a name=\"Commands\"><\/a><\/p>\n<h2>Commands<\/h2>\n<p>https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8139318?start=0<\/p>\n<ul>\n<li>You can run commands one at a time in alphabetical order<\/li>\n<li>You can set a directory from which that command is run as well as environmental variables<\/li>\n<li>You can provide a test to control whether the command is executied or not\n<ul>\n<li>Example: test:if a file does not exist, command: the download command)<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Example: Call the echo command only if the file does not exist<\/p>\n<pre>commands:\r\n  test:\r\n    command: \"echo \\\"$MAGIC\\\" &gt; test.txt\r\n    env:\r\n      MAGIC: \"I come from the environment!\"\r\n    cwd: \"~\"\r\n    test: \"test ! -e ~\/test.txt\"\r\n    ignoreErrors: \"false\"<\/pre>\n<ul>\n<li>It is recommended to:\n<ul>\n<li>use command as a last resort since most of this can be performed in the above sections<\/li>\n<li>Use the Files section to write your scripts, then use command to execute those scripts.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><a name=\"Services\"><\/a><\/p>\n<h2>Services<\/h2>\n<p>https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8139320?start=0<\/p>\n<ul>\n<li>Launch several services at the instance launch<\/li>\n<li>Ensure services are restarted when files change, or packages are updated by cfn-init.<\/li>\n<\/ul>\n<h4>Example from script:<\/h4>\n<pre>  WebServerHost:\r\n    Type: AWS::EC2::Instance\r\n    Metadata:\r\n      Comment: Install a simple PHP application\r\n      AWS::CloudFormation::Init:\r\n        config:\r\n          ...\r\n          services:\r\n            sysvinit:\r\n              httpd:\r\n                enabled: 'true'\r\n                ensureRunning: 'true'\r\n              sendmail:\r\n                enabled: 'false'\r\n                ensureRunning: 'false'<\/pre>\n<p><a name=\"CFNInitandSignal\"><\/a><\/p>\n<h2>CFN Init and Signal<\/h2>\n<p><a href=\"https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8162188?start=0\" target=\"_blank\" rel=\"noopener\">https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8162188?start=0<\/a><\/p>\n<h3>Calling cfn-signal<\/h3>\n<ul>\n<li>Use cfn-init first to launch the configuration<\/li>\n<li>Next use cfn-signal when the configuration has completed to let CF know that the resoiurce creation has been successful\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>This has to be used in conjunction with a CreationPolicy.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<pre>CreationPolicy:\r\n  ResourceSignal:\r\n    Timeout: PT5M<\/pre>\n<ul>\n<li>This example means we are waiting a maximum of 5 minutes for the instance to come online and be self configured. If we don&#8217;t hear from cfn-signal by then, the CF will fail and roll back.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Properties:<br \/>\n&#8230;<br \/>\nUserData:<br \/>\n&#8220;Fn::Base64&#8221;:<br \/>\n!Sub |<br \/>\n#!\/bin\/bash -xe<br \/>\n# Get the latest CloudFormation package<br \/>\nyum update -y aws-cfn-bootstrap<br \/>\n# Start cfn-init<br \/>\n\/opt\/aws\/bin\/cfn-init -s ${AWS::StackId} -r WebServerHost &#8211;region ${AWS::Region} || error_exit &#8216;Failed to run cfn-init&#8217;<br \/>\n# Start up the cfn-hup daemon to listen for changes to the EC2 instance metadata<br \/>\n\/opt\/aws\/bin\/cfn-hup || error_exit &#8216;Failed to start cfn-hup&#8217;<br \/>\n# All done so signal success<br \/>\n\/opt\/aws\/bin\/cfn-signal -e $? &#8211;stack ${AWS::StackId} &#8211;resource WebServerHost &#8211;region ${AWS::Region}<\/p>\n<pre>* -s == --stack (StackId)\r\n* -r == --resource<\/pre>\n<h3>Cfn-hup (cfn Helper Update?)<\/h3>\n<p>&nbsp;<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>Cfn-hup can be used to tell your EC2 instnaces to look for Metadata changes every 15 minutes and apply the metadata configuration again.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>Very powerful, but strongly recommended to tro try it to fully understand how it works.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>Relies on a cfn-hup configuration, reference:\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>\/etc\/cfn\/cfn-hup.conf<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>\/etc\/cfn\/hooks.d\/cfn-auto-reloader.conf<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<h4>Example from script<\/h4>\n<p>&nbsp;<\/p>\n<pre>          files:\r\n            ...\r\n            \"\/etc\/cfn\/cfn-hup.conf\":\r\n              content: !Sub |\r\n                [main]\r\n                stack=${AWS::StackId}\r\n                region=${AWS::Region}\r\n              mode: \"000400\"\r\n              owner: \"root\"\r\n              group: \"root\"\r\n            \"\/etc\/cfn\/hooks.d\/cfn-auto-reloader.conf\":\r\n              content: !Sub |\r\n                [cfn-auto-reloader-hook]\r\n                triggers=post.update\r\n                path=Resources.WebServerHost.Metadata.AWS::CloudFormation::Init\r\n                action=\/opt\/aws\/bin\/cfn-init -v --stack ${AWS::StackName} --resource WebServerHost --region ${AWS::Region}\r\n              mode: \"000400\"\r\n              owner: \"root\"\r\n              group: \"root\"\r\n<\/pre>\n<p><a name=\"CFNHandsOn\"><\/a><\/p>\n<h2>CFN Hands On<\/h2>\n<p><a href=\"https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8139328?start=0\" target=\"_blank\" rel=\"noopener\">https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8139328?start=0<\/a><\/p>\n<p>Upload the script and run it.<\/p>\n<ul>\n<li>View the updates on the CF Events tab<\/li>\n<li>View the outputs on the CD Outputs tab<\/li>\n<\/ul>\n<p><a name=\"Summary\"><\/a><\/p>\n<h2>Summary<\/h2>\n<p><a href=\"https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8139330?start=0\" target=\"_blank\" rel=\"noopener\">https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8139330?start=0<\/a><\/p>\n<ul>\n<li>Use the template as a basis for future CloudFormation scripts.<\/li>\n<li>For practice, create a CF script with Init for an AutoScaling group.<\/li>\n<li>Log locations\n<ul>\n<li>EC2-user data: \/var\/log\/cloud-init-output.log<\/li>\n<li>cfn-init: \/var\/log\/cfn-init.log<\/li>\n<\/ul>\n<\/li>\n<li>Use the logs to see which commands did not complete as expected and why.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h2><\/h2>\n","protected":false},"excerpt":{"rendered":"<p>Course Main Menu Section 4 Main Menu EC2 User Data Overview EC2 User Data &amp; Fn::Base64 in CloudFormation CloudFormation Init Overview Packages Groups and Users Sources Files Fn::Sub (substitute function) Commands Services CFN Init and Signal CFN Hands On Summary EC2 User Data Overview https:\/\/www.udemy.com\/aws-cloudformation-master-class\/learn\/v4\/t\/lecture\/8139272?start=0 What is CFN-Init and EC2-user data Many of the CF ..<\/p>\n<div class=\"clear-fix\"><\/div>\n<p><a href=\"https:\/\/wiki.thomasandsofia.com\/?p=1174\" title=\"read more...\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-1174","post","type-post","status-publish","format-standard","hentry","category-cloudformation"],"_links":{"self":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts\/1174","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1174"}],"version-history":[{"count":40,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts\/1174\/revisions"}],"predecessor-version":[{"id":1233,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts\/1174\/revisions\/1233"}],"wp:attachment":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1174"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1174"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1174"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}