Back

Explore Courses Blog Tutorials Interview Questions
0 votes
2 views
in AWS by (19.1k points)

I am creating an instance through the cloud formation script.

The only way I found to attach an OS partition was through "BlockDeviceMappings" property. (I've tried to use "Volumes" property before, but the instance could not be mounted, the system told me that /dev/sda was already mapped and rolled back the instance creation)

Here is the relevant portion of my template:

  "Resources" :

  {

    "Ec2Instance" :

    {

      "Type" : "AWS::EC2::Instance",

      "Properties" :

      {

        "BlockDeviceMappings" :

        [{

          "DeviceName" : "/dev/sda",

          "Ebs" :

          {

            "VolumeSize" : { "Ref" : "RootVolumeSize" },

            "SnapshotId" :

            { "Fn::FindInMap" : [ "RegionMap",

              { "Ref" : "AWS::Region" }, "RootVolumeSnapshotId" ]

            }

          }

        }],

        ...

       }

     }

My question is, how can I tag the Ebs volume, that I am creating here with "BlockDeviceMappings" property? I did not find an obvious solution.

1 Answer

0 votes
by (44.4k points)

Solved it like this and also got some insights from AWS documentations.

Added this to AWS::EC2::Instance:Properties:UserData

{ "Fn::Base64" : { "Fn::Join" : [ "\n", [

  "#!/bin/bash",

  "set -eux",

  "exec > >(tee /tmp/user-data.log | logger -t user-data -s 2>/dev/console) 2>&1",

  { "Fn::Join" : [ "", [

    "AWS_STACK_NAME='", { "Ref" : "AWS::StackName" }, "'"

  ]]},

  { "Fn::Join" : [ "", [

    "AWS_ROOT_VOLUME_SNAPSHOT_ID='",

      { "Fn::FindInMap" :

         [ "RegionMap", { "Ref" : "AWS::Region" }, "RootVolumeSnapshotId" ]},

      "'"

  ]]},

  "AWS_INSTANCE_ID=$( curl http://169.254.169.254/latest/meta-data/instance-id )",

  "",

  "AWS_HOME=/opt/aws",

  "AWS_BIN_DIR=\"${AWS_HOME}/bin\"",

  "export EC2_HOME=\"${AWS_HOME}/apitools/ec2\"",

  "export JAVA_HOME=/etc/alternatives/jre_1.7.0",

  "",

  "ROOT_DISK_ID=$(",

  "    \"${AWS_BIN_DIR}/ec2-describe-volumes\" \\",

  "        --filter \"attachment.instance-id=${AWS_INSTANCE_ID}\" \\",

  "        --show-empty-fields \\",

  "      | grep '^VOLUME' \\",

  "      | awk '{printf \"%s,%s\\n\", $4, $2}' \\",

  "      | grep '^${AWS_ROOT_VOLUME_SNAPSHOT_ID}' \\",

  "      | cut --delimiter=, --fields=2",

  "    exit ${PIPESTATUS[0]}",

  "  )",

  "\"${AWS_BIN_DIR}/ec2-create-tags \\",

  "  \"${ROOT_DISK_ID}\" \\",

  "  --tag \"Name=${AWS_STACK_NAME}-root\"",

  ""

]]}}

Had to do some changes to the IAM role:

Added this to the "Resources" section:

"InstanceProfile" :

{

  "Type" : "AWS::IAM::InstanceProfile",

  "Properties" :

  {

    "Path" : "/",

    "Roles" : [ "ec2-tag-instance" ]

  }

}

Referenced this profile in the Instance resource:

"Ec2Instance" :

{

  "Type" : "AWS::EC2::Instance",

  "Properties" :

  {

    ...

    "IamInstanceProfile" : {"Ref" : "InstanceProfile"},

    ...

  }

}

Create a new IAM role using the UI and name it ec2-tag-instance. Assign this policy:

{

  "Version": "2012-10-17",

  "Statement": [

    {

      "Effect": "Allow",

      "Action": [

        "ec2:Describe*",

        "ec2:CreateTags"

      ],

      "Resource": "*"

    }

  ]

}

That’s it!

Browse Categories

...