3

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
Madhur Asati
  • 185
  • 3
  • 13
  • It's not clear what the problem is. What happens after you log in? That sentence isn't complete. What error message do you see? – Alex Harvey Jan 31 '19 at 06:31
  • 1
    Also, independently of the problem you have, DO NOT inject an access key and secret key in your instance. Create a role instead and assign the role to your EC2 instance. https://aws.amazon.com/blogs/aws/iam-roles-for-ec2-instances-simplified-secure-access-to-aws-service-apis-from-ec2/ – Sébastien Stormacq Jan 31 '19 at 06:47
  • Problem is software are not being installed at the time of stack creation. Upon viewing /var/log/cloud-init.log file I get this: cloud-init[3369]: util.py[WARNING]: Failed running /var/lib/cloud/instance/scripts/part-001 [1] util.py[DEBUG]: Failed running /var/lib/cloud/instance/scripts/part-001 [1] Traceback (most recent call last): File "/usr/lib/python2.7/site-packages/cloudinit/util.py", line 860, in runparts subp(prefix + [exe_path], capture=False, shell=True) File "/usr/lib/python2.7/site-packages/cloudinit/util.py", line 2053, in subp cmd=args) – Madhur Asati Jan 31 '19 at 07:00

1 Answers1

6

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
Alex Harvey
  • 14,494
  • 5
  • 61
  • 97
  • Thank you so much for your answer @Alex. I launched an instance by editing the script which you suggested. I no longer get an error in /var/log/cloud-init.log and it gave me a good start. However, the instance still not have the applications installed on it. Am I missing something in Metadata section of my script mentioned in the main question above? Please suggest. – Madhur Asati Jan 31 '19 at 09:26
  • Is your call to cfn-init pointing to the correct resource name? https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-init.html It should be "The logical resource ID of the resource that contains the metadata." – Alex Harvey Jan 31 '19 at 09:35
  • I updated to note another syntax error in your template. – Alex Harvey Jan 31 '19 at 09:36
  • Could you please elaborate on the following comment: Is your call to cfn-init pointing to the correct resource name? It should be "The logical resource ID of the resource that contains the metadata." Also, I would like to know another syntax error which you traced in my script. – Madhur Asati Jan 31 '19 at 09:58
  • What is the resource name of the resource that contains your MetaData block. Is it really “LaunchConfig”? – Alex Harvey Jan 31 '19 at 10:01
  • Yes. The Logical resource ID of the resource is "LauchConfig" which contains metadata. – Madhur Asati Jan 31 '19 at 10:10
  • You may need to specify a region? The cfn-init region defaults to us-east-1. – Alex Harvey Jan 31 '19 at 10:34
  • Can we specify MetaData section in AWS::AutoScaling::LaunchConfiguration? I have script as below: LaunchConfig: Type: AWS::AutoScaling::LaunchConfiguration Properties: AssociatePublicIpAddress: 'true' UserData: <......> Metadata: AWS::CloudFormation::Init: config: packages: yum: - java-1.8.0-openjdk.x86_64: [] - tomcat8: [] - httpd: [] services: sysvinit: httpd: enabled: 'true' ensureRunning: 'true' files: <.....> – Madhur Asati Jan 31 '19 at 10:42
  • Send it to me on LinkedIn and I'll have a look. – Alex Harvey Jan 31 '19 at 10:57