AWS:elastic_ip 使用 cloudformation 为弹性 ip 分配名称

AWS:elastic_ip Assign a name to an elastic ip using cloudformation

我正在尝试使用 cloudformation 并使用正常流程将 "name" 分配给弹性 ip,即:

  IPAddress:
    Description: 'ip:${AWS::Region}:${AWS::StackName} - elastic up for something'
    Type: 'AWS::EC2::EIP'
    Properties:
      Tags:
        - Key: Name
          Value: !Sub 'ec2:${AWS::Region}:${AWS::StackName}'

出于某种原因,cloudformation 抛出错误:"tags not supported",所以我想我在问,有没有办法用 cloud-formation 设置弹性 ip 的 "Name"?

干杯

您的错误原因在于 CloudFormation,弹性 IP 资源 "AWS::EC2::EIP" 不支持属性标签。

关于第二个问题,据我所知,目前无法从云形成中命名一个弹性IP。

更新(2019 年 11 月 22 日) 现在支持标签。请参阅文档 here.

不要屏住呼吸,这是 AWS 论坛上的一个 thread,从 2012 年开始就这个主题。

而是使用 CloudFormation Custom Resources 来弥补这个和其他 CFN 缺点。

以下是我使用 Python 和 boto3 的实现。

Python source code for tag-ec2-resource.py

import cfnresponse
import boto3
import os


def lambda_handler(event, context):
    print(event, context)
    ec2 = boto3.client('ec2', region_name=os.environ['AWS_REGION'])
    ResourceId = event['ResourceProperties']['ResourceId']
    TagKey = event['ResourceProperties']['TagKey']
    TagValue = event['ResourceProperties']['TagValue']
    responseData = {}

    if event['RequestType'] == 'Delete':
        try:
            response = ec2.delete_tags(
                Resources=[
                    ResourceId,
                ],
                Tags=[
                    {
                        'Key': TagKey,
                        'Value': TagValue
                    }
                ]
            )
            print(response)
        except Exception as e:
            print(e)

        cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, physicalResourceId=ResourceId)
        return

    if event['RequestType'] == 'Update':
        try:
            OldResourceId = event['OldResourceProperties']['ResourceId']
            OldTagKey = event['OldResourceProperties']['TagKey']
            OldTagValue = event['OldResourceProperties']['TagValue']
            response = ec2.delete_tags(
                Resources=[
                    OldResourceId,
                ],
                Tags=[
                    {
                        'Key': OldTagKey,
                        'Value': OldTagValue
                    }
                ]
            )
            print(response)
        except Exception as e:
            print(e)

    try:
        response = ec2.create_tags(
            Resources=[
                ResourceId,
            ],
            Tags=[
                {
                    'Key': TagKey,
                    'Value': TagValue
                },
            ]
        )
        print(response)
    except:
        pass

    cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, physicalResourceId=ResourceId)

(你需要用这个函数打包 cfn-response

define Lambda role

  TagEC2ResourceLambdaRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - 'lambda.amazonaws.com'
          Action:
          - 'sts:AssumeRole'
      Path: '/'
      Policies:
      - PolicyName: 'AmazonLambdaServicePolicy'
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Effect: Allow
            Action:
            - 'logs:CreateLogGroup'
            - 'logs:CreateLogStream'
            - 'logs:PutLogEvents'
            - 'ec2:Describe*'
            - 'ec2:CreateTags'
            - 'ec2:DeleteTags'
            Resource: '*'

define Lambda function

  TagEC2ResourceLambda:
    Type: 'AWS::Lambda::Function'
    Properties:
      FunctionName: !Join [ '-', [ 'tag-ec2-resource', !Select [ 2, !Split [ '/', !Ref 'AWS::StackId' ]]]]
      Handler: 'tag-ec2-resource.lambda_handler'
      Code:
        S3Bucket: !Ref 'S3Bucket'
        S3Key: !Sub 'lambda-functions/tag-ec2-resource-${LambdaVersion}.zip'
      Runtime: python2.7
      Role: !Ref 'TagEC2ResourceLambdaRoleArn'
      Description: 'Tag EC2 resource.'
      Timeout: 30
      Tags:
      - Key: Name
        Value: !Ref 'NameTag'

Lastly, tag EIP using custom resource in your template

  MyEipTag:
    Type: 'Custom::TagEC2Resource'
    Properties:
      ServiceToken: !Sub 'arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:tag-ec2-resource-${LambdaStackGuid}'
      ResourceId: !GetAtt MyEiP.AllocationId
      TagKey: 'Name'
      TagValue: 'my-very-special-EIP'

希望对您有所帮助。