Search code examples
amazon-web-servicesamazon-ec2aws-cloudformationuser-datacloud-init

Userdata script not executed on AWS CloudFormation Template


I am trying to create a CloudFormation stack which has UserData script to install java, tomcat, httpd and java application on launch of an EC2 instance. However, the stack gets created successfully with all the resources but when I connect to EC2 instance to check the configuration of above applications I don't find any. My usecase is to spin-up an instance with all the above applications/software to be installed with automation.

UserData:
   Fn::Base64: 
    Fn::Join: 
    - ' '
    - - '#!/bin/bash -xe\n'

      - 'sudo yum update && install pip && pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n'
      - 'date > /home/ec2-user/starttime\n'
      - 'sudo yum update -y aws-cfn-bootstrap\n'

        # Initialize CloudFormation bits\n
      - ' ' 
      - '/opt/aws/bin/cfn-init -v\n'
      - '             --stack\n'
      - '!Ref AWS::StackName\n'
      - '             --resource LaunchConfig\n'
      - 'ACCESS_KEY=${HostKeys}&SECRET_KEY=${HostKeys.SecretAccessKey}\n'

       # Start servers\n
      - 'service tomcat8 start\n'
      - '/etc/init.d/httpd start\n'

      - 'date > /home/ec2-user/stoptime\n'
Metadata: 
 AWS::CloudFormation::Init:
  config: 
   packages: 
    yum:
    - java-1.8.0-openjdk.x86_64: []   
    - tomcat8: []
    - httpd: []
   services:
    sysvinit:
     httpd:
      enabled: 'true'
      ensureRunning: 'true'
  files: 
  - /usr/share/tomcat8/webapps/sample.war:
    - source: https://s3-eu-west-1.amazonaws.com/testbucket/sample.war
    - mode: 000500
    - owner: tomcat
    - group: tomcat
   CfnUser:
    Type: AWS::IAM::User
    Properties: 
     Path: '/'  
     Policies: 
     - PolicyName: Admin
       PolicyDocument: 
        Statement:
        - Effect: Allow
          Action: '*'
          Resource: '*'
   HostKeys:
    Type: AWS::IAM::AccessKey
    Properties: 
      UserName: !Ref CfnUser

Solution

  • The problem is in the way you have formatted your UserData. I would suggest that you launch the EC2 instance and manually test the script first. It has a number of problems in it.

    Try formatting your UserData like this:

    UserData:
      Fn::Base64:
        !Sub |
          #!/bin/bash -xe
    
          # FIXME. This won't work either.
          # sudo yum update && install pip && pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz
    
          date > /home/ec2-user/starttime
          sudo yum update -y aws-cfn-bootstrap
    
          # Initialize CloudFormation bits
          /opt/aws/bin/cfn-init -v \
            --stack ${AWS::StackName} \
            --resource LaunchConfig
    
          # FIXME. Not sure why these are here.
          # ACCESS_KEY=${HostKeys}
          # SECRET_KEY=${HostKeys.SecretAccessKey}
    
          # Start servers\n
          service tomcat8 start
          /etc/init.d/httpd start
    
          date > /home/ec2-user/stoptime
    

    Things to note:

    • You can't interpolate here using !Ref notation. Notice I changed it to ${AWS::StackName} and notice the whole block is inside !Sub.
    • As my comments indicate, the yum update line has invalid commands in it.
    • As noted in the comments, it is a bad practice to inject access keys. Also, the keys don't seem to be required for anything in this script.

    Note also that the files section is specified incorrectly in the MetaData, as Arrays instead of Hash keys.

    It should be:

      files: 
        /usr/share/tomcat8/webapps/sample.war:
          source: https://s3-eu-west-1.amazonaws.com/testbucket/sample.war
          mode: '000500'
          owner: tomcat
          group: tomcat