【问题标题】:Set Tag on AWS::EC2::Instances BlockStorage of root Volume via CloudFormation通过 CloudFormation 在根卷的 AWS::EC2::Instances BlockStorage 上设置标签
【发布时间】:2019-09-02 00:37:20
【问题描述】:

我们希望使用特定标签标记 cloudformation 堆栈的每个资源(出于计费和财务原因)。这包括安装在 (/dev/sda1) 下的主分区上使用的主存储。

这就是我们所拥有的:

---
AWSTemplateFormatVersion: '2010-09-09'
Description: The Name
Parameters:
  InstanceType:
    Description: EC2 instance type
    Type: String
    Default: t3.small
    AllowedValues:
    - t3.nano
    - ...
  InstanceName:
    Description: Name Tag
    Type: String
Resources:
  TheECCInstance:
    Type: AWS::EC2::Instance
    Properties:
      KeyName: jenkins
      ImageId: !FindInMap [RegionMap, !Ref 'AWS::Region', AMI]
      InstanceType:
        Ref: InstanceType
      SubnetId: subnet-0e9c7d7c2711aaf9e
      BlockDeviceMappings:
        - DeviceName: "/dev/sda1"
          Ebs:
            VolumeSize:
              Ref: EBSBlockSize
            VolumeType: gp2
      Tags:
      - Key: Name
        Value:
          Ref: InstanceName
      - Key: Type
        Value: TheType

Mappings:
  RegionMap:
    'ap-northeast-3':
      NAME: ap-northeast-3b
      AMI: 'ami-05e896b95030bd37c'
    'sa-east-1':
      NAME: sa-east-1b
      AMI: 'ami-03c6239555bb12112'
    'eu-west-1':
      NAME: eu-west-1b
      AMI: 'ami-00035f41c82244dab'
    ...

Outputs:
  ...

不介意使用类似的东西

  RootVolume:
    Type: AWS::EC2::Volume      // Or Something in that direction (EFS / EBS / whatever)
    Properties:
      Size:
        Ref: EBSBlockSize
      VolumeType: gp2
      AvailabilityZone: !FindInMap [RegionMap, !Ref 'AWS::Region', NAME]
      Tags:
        - Key: Type
          Value: TheType

并安装它。将其作为主分区连接似乎是不可能的。可以是 AWS::EC2::Volume、AWS::EFS 等。如有任何帮助,我们将不胜感激。我们目前创建实例,然后在创建堆栈后进行标记。但这似乎有些脆弱,应该有一种更简单的方法来做到这一点......

【问题讨论】:

  • 为了便于阅读,对上面的代码进行了简化和修改。
  • AFAIK 您可以使用 BlockDeviceMappings 来执行此操作。不过,您确实需要单独定义 EBS。
  • 谢谢@DroidX86。但问题一般不在于设备。它是根设备。我可以生成临时文件,但“/dev/sda1”似乎是个问题......
  • 这是为什么呢?有什么错误吗?
  • 不同的错误。我会在收集问题后尝试更新问题。

标签: amazon-web-services configuration tags config amazon-cloudformation


【解决方案1】:

不可能形成云

事实证明,这对于 aws cloudformation 是不可能的。 这个问题提示了我这个答案:https://serverfault.com/questions/876942/create-new-ec2-instance-with-existing-ebs-volume-as-root-device-using-cloudforma

使用 terraform 的解决方案

使用“terraform”非常简单:


resource "aws_instance" "someName" {
  ami           = "ami-***********"
  instance_type = "t2.*******"
  tags          = {
    Type = "InstanceTag"
  }
  volume_tags   = {
    Type = "VolumeTag"
  }
}

我们的解决方案(Jenkins 和 shell 脚本)

我们使用 cloudformation 通过 jenkins 生成我们的 CI 实例。迁移到 terraform 会导致我们愿意承担更多的工作。我们需要标签来计算成本。因此,当意识到 cloudformation 不是选项时,我们使用 cli 在创建实例后对其进行标记。

显然,必须安装 awscli。凭据来自环境变量。

这是我们使用的脚本:

sleep 1m
EC2_VOLUMES=$(aws ec2 describe-instances --region "${INSTANCE_REGION}" --filter "Name=tag-key,Values=Type" "Name=tag-value,Values=Jenkins" --filter "Name=tag-key,Values=Name" "Name=tag-value,Values=BackendJenkins${BUILD_NUMBER}" --query "Reservations[*].Instances[*].BlockDeviceMappings[*].Ebs.[VolumeId]" --output text)

echo $AWS_SECRET_ACCESS_KEY | base64 -i > foo.txt

while read -r RESOURCE; do
    # We set the name and the type tag
    aws ec2 create-tags --resources "$RESOURCE" --region "${INSTANCE_REGION}" --tags "Key=Type,Value=TheTagValue"
    aws ec2 create-tags --resources "$RESOURCE" --region "${INSTANCE_REGION}" --tags "Key=Name,Value=TheInstanceName${BUILD_NUMBER}"
done <<< "$EC2_VOLUMES"

感谢所有关于生成 EC2::Volumes 和标签传播的提示。

【讨论】:

  • 其实关于terraform的部分是不正确的。 github.com/hashicorp/terraform/issues/3531
  • 我还建议一个更好的方法,脚本将仅根据实例具有的标签标记 EBS 卷,因此标签的管理仍然在 CloudFormation 下进行可追溯性,并且仅自动化从已部署的实例标签中标记 EBS 卷(这就是我们正在做的)
  • @Dvir669 您提到的问题已通过以下方式关闭并解决:-github.com/hashicorp/terraform/pull/14007 据我所知,它确实对我们有用。抱歉,如果这对您有误导性。
  • @Dvir669 感谢第二个提示。我们目前使用 jenkins 并且可以 - 因此 - 按内部版本号分开构建。这意味着实例是使用唯一名称和提交-sha 生成的,因此我们非常确定构建的内容和将被标记的内容。我提出的解决方案只是我们所做工作的简化版本。仍然可以将功能内置到 Cloudformation 中。谢谢你的想法。
猜你喜欢
  • 2018-05-10
  • 1970-01-01
  • 1970-01-01
  • 2014-06-06
  • 2018-01-27
  • 2017-05-14
  • 2019-12-28
  • 1970-01-01
  • 2014-07-11
相关资源
最近更新 更多