Есть ли способ пометить корневой том при инициализации из шаблона cloudformation?

Я создаю экземпляр через формирование облака script.

Единственный способ найти раздел ОС - это свойство "BlockDeviceMappings". (Ранее я пытался использовать свойство "Тома", но экземпляр не мог быть смонтирован, система сообщила мне, что /dev/sda уже сопоставлена ​​и откатывается от создания экземпляра)

Вот соответствующая часть моего шаблона:

  "Resources" :
  {
    "Ec2Instance" :
    {
      "Type" : "AWS::EC2::Instance",
      "Properties" :
      {
        "BlockDeviceMappings" :
        [{
          "DeviceName" : "/dev/sda",
          "Ebs" :
          {
            "VolumeSize" : { "Ref" : "RootVolumeSize" },
            "SnapshotId" :
            { "Fn::FindInMap" : [ "RegionMap",
              { "Ref" : "AWS::Region" }, "RootVolumeSnapshotId" ]
            }
          }
        }],
        ...
       }
     }

Мой вопрос: как я могу пометить том Ebs, который я создаю здесь с свойством BlockDeviceMappings? Я не нашел очевидного решения.

Спасибо.

Ответ 1

Было возможно сделать это через интерфейс AWI CLI, роль IAM и инициализацию UserData.

Добавил это к 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\"",
  ""
]]}}

Также необходимо добавить ссылку на роль IAM, которая может описывать тома и создавать теги.

Добавлено в раздел "Ресурсы":

"InstanceProfile" :
{
  "Type" : "AWS::IAM::InstanceProfile",
  "Properties" :
  {
    "Path" : "/",
    "Roles" : [ "ec2-tag-instance" ]
  }
}

Ссылка на этот профиль в ресурсе Instance:

"Ec2Instance" :
{
  "Type" : "AWS::EC2::Instance",
  "Properties" :
  {
    ...
    "IamInstanceProfile" : {"Ref" : "InstanceProfile"},
    ...
  }
}

И в пользовательском интерфейсе IAM создайте новую роль под названием ec2-tag-instance и назначьте эту политику:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:Describe*",
        "ec2:CreateTags"
      ],
      "Resource": "*"
    }
  ]
}

Это было бы гораздо приятнее, если BlockDeviceMappings:Ebs поддерживал элемент Tags.

Ответ 2

Спасибо Алекс,

Я обнаружил, что после ec2-create-tags отсутствует двойная кавычка:)

  "\"${AWS_BIN_DIR}/ec2-create-tags\" \\",
  "  \"${ROOT_DISK_ID}\" \\",
  "  --tag \"Name=${AWS_STACK_NAME}-root\"",

Кроме того, если экземпляры не находятся в регионе us-east-1 по умолчанию, укажите " - регион REGION" в тегах ec2-create и ec2-описать-тома.

Ответ 3

Если ваш стек CloudFormation помечен и вы хотите, чтобы подключенные тома EC2 копировали теги из стека, вы можете использовать приведенное ниже значение UserData.

Fn::Base64: !Sub |
    #!/bin/bash -xe
    exec > /tmp/part-001.log 2>&1
    # --==Tagging Attached Volumes==--
    TAGS=$(aws cloudformation describe-stacks --stack-name ${AWS::StackName} --query 'Stacks[0].Tags' --region ${AWS::Region})
    EC2_INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
    EBS_IDS=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values="$EC2_INSTANCE_ID" --region ${AWS::Region} --query 'Volumes[*].[VolumeId]' --out text | tr "\n" " ")
    aws ec2 create-tags --resources $EBS_IDS --tags "$TAGS" --region ${AWS::Region}
    TAGS=$(echo $TAGS | tr "Key" "key" | tr "Value" "value")
    aws ecs tag-resource --resource-arn arn:aws:ecs:${AWS::Region}:${AWS::AccountId}:cluster/${EcsClusterName} --tags "$TAGS"

  1. Запишите все stdout и stderr в файл для отладки:

    'exec>/tmp/part-001.log 2> & 1

  2. (требуется разрешение) Получить теги из стека:

    TAGS=$(aws cloudformation describe-stacks --stack-name ${AWS::StackName} --query 'Stacks[0].Tags' --region ${AWS::Region})

  3. Получите идентификатор экземпляра EC2 из конечной точки метаданных:

    EC2_INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)

  4. (требуется разрешение) Получить EBS IDS:

    EBS_IDS=$(aws ec2 describe-volumes --filters Name=attachment.instance-id,Values="$EC2_INSTANCE_ID" --region ${AWS::Region} --query 'Volumes[*].[VolumeId]' --out text | tr "\n" " ")

  5. (требуется разрешение) Добавление тегов в тома EBS: aws ec2 create-tags --resources $EBS_IDS --tags "$TAGS" --region ${AWS::Region}

  6. Формат тегов для маркировки ECS:

    TAGS=$(echo $TAGS | tr "Key" "key" | tr "Value" "value")

  7. (требуется разрешение) Пометить кластер ECS:

    aws ecs tag-resource --resource-arn arn:aws:ecs:${AWS::Region}:${AWS::AccountId}:cluster/${EcsClusterName} --tags "$TAGS"

Политика должна выглядеть так:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ec2:DeleteTags",
                "ec2:CreateTags",
                "ecs:TagResource", 
                "cloudformation:DescribeStacks"
            ],
            "Resource": "*"
        }
    ]
}

Ответ 4

Вы можете использовать шаблон CloudFormation для создания ресурсов, таких как правило событий CloudWatch и Lambda. Лямбда-вызов может запускаться не только при наличии события создания экземпляра, но и при обновлении тегов экземпляра.

Ответ 5

Это то, что я сделал в своих пользовательских данных ec2. Я думаю, это намного проще, чем выше ответ.

Key=<Your Tag Name>
Value=<Your Tag Value>
Region=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | grep -oP "(?<=\"region\" : \")[^\"]+")

aws ec2 create-tags --resources $(aws ec2 describe-instances --instance-ids $(curl -s http://169.254.169.254/latest/meta-data/instance-id) --region $Region | grep -oP "(?<=\"VolumeId\": \")[^\"]+") --tags Key=$Key,Value=$Value --region $Region