2
votes

I am new to cloudformation. I am using cfn-init to create a file. But doesnt create a file nor my stack fails. Stack successfully gets created with required resources like EC2 instance. Also it installs AWS CLI as mentioned in User data. But it just does not create file i wish to create. I tried using Advanced options of not allowing rollback of stack. But the /var/log/cfn-init.log does not get created. See the template below? Am I doing anything wrong in this?

{
  "Parameters" : {
    "KeyName" : {
      "Description" : "The EC2 Key Pair to allow SSH access to the instance",
      "Type" : "AWS::EC2::KeyPair::KeyName"
    }
  },
  "Resources" : {
    "Ec2Instance" : {
      "Type" : "AWS::EC2::Instance",
      "Metadata" : {
        "Comment" : "Install a simple application",
        "AWS::CloudFormation::Init" : {
          "config" : {
          "files" : {
              "/tmp/setup.mysql" : {
                "content" : { "Fn::Join" : ["", ["[default]\n","region=",{"Ref": "AWS::Region"}]]},
                "mode"    : "000775",
                "owner"   : "ec2-user",
                "group"   : "ec2-user"
              }       
          }
          }
          } },

      "Properties" : {
        "SecurityGroups" : [ { 
                "Ref" : "InstanceSecurityGroup" } 
                ],
        "IamInstanceProfile" : {"Ref" : "RootInstanceProfile"} ,
        "KeyName" : { "Ref" : "KeyName"},
        "InstanceType" : "t2.micro",
        "ImageId" : "ami-58277d3d",
        "UserData": {
                    "Fn::Base64": {
                        "Fn::Join": [
                            "",
                            [
                                "curl https://s3.amazonaws.com/aws-cli/awscli-bundle.zip -o awscli-bundle.zip\n",
                                "unzip awscli-bundle.zip\n",
                                "sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws\n",
                                "/opt/aws/bin/cfn-init -v ",
                                 "         --stack ", { "Ref" : "AWS::StackName" },
                                 "         --resource Ec2Instance ",
                                 "         --region ", { "Ref" : "AWS::Region" }, "\n",
                                "cfn-signal -e 0",
                                " --stack ",
                                {
                                    "Ref": "AWS::StackName"
                                },
                                " --region ",
                                {
                                    "Ref": "AWS::Region"
                                },
                                " --resource ",
                                "Ec2Instance",
                                "\n"
                            ]
                        ]
                    }
                }
      }
    },


      "RootRole": {
         "Type": "AWS::IAM::Role",
         "Properties": {
            "AssumeRolePolicyDocument": {
               "Version" : "2012-10-17",
               "Statement": [ {
                  "Effect": "Allow",
                  "Principal": {
                     "Service": [ "ec2.amazonaws.com" ]
                  },
                  "Action": [ "sts:AssumeRole" ]
               } ]
            },
            "Path": "/",
            "Policies": [ {
               "PolicyName": "root",
               "PolicyDocument": {
                  "Version" : "2012-10-17",
                  "Statement": [ {
                     "Effect": "Allow",
                     "Action": ["cloudwatch:PutMetricData"],
                     "Resource": "*"
                  } ]
               }
               } ]
            }
      },
      "RootInstanceProfile": {
         "Type": "AWS::IAM::InstanceProfile",
         "Properties": {
            "Path": "/",
            "Roles": [ {
               "Ref": "RootRole"
            } ]
         }
      },



    "InstanceSecurityGroup" : {
      "Type" : "AWS::EC2::SecurityGroup",
      "Properties" : {
        "GroupDescription" : "Enable SSH access via port 22",
        "Tags" : [{  "Key" : "Name",  "Value" : "SecurityGr_EC2WithParam" }],
        "SecurityGroupIngress" : [ {
          "IpProtocol" : "tcp",
          "FromPort" : "22",
          "ToPort" : "22",
          "CidrIp" : "0.0.0.0/0"
        } ]
      }
    }
  }
} 
1
what are you trying to insert in file content exactly? is it default region? you might want to have a check on that block againAli
I was able to solve this Ali. Added first line in "UserData" as "#!/bin/bash\n", For any commands to work we need to provide a shell environment in Userdata without which it cannot create any files. ThanksWills

1 Answers

3
votes

As discovered in your comment, the UserData property on your AWS::EC2::Instance Resource requires the first line to be #!/bin/bash\n.

This is necessary in order for the user-data processed by cloud-init to be interpreted as a User-Data Script, as noted in the AWS EC2 documentation section, Running Commands on Your Linux Instance at Launch:

User data shell scripts must start with the #! characters and the path to the interpreter you want to read the script (commonly /bin/bash).

Note also that sudo is not necessary in your user-data script, as also noted in the documentation:

Scripts entered as user data are executed as the root user, so do not use the sudo command in the script.

Finally, note that the AWS CLI comes pre-installed on the Amazon Linux AMI instances by default, which is why you noticed the AWS CLI was still installed on your instance despite your user-data script not running correctly.