Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I am trying to use cloudformation and assign a "name" to an elastic ip using the normal process i.e:

  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}'

For some reason cloudformation throws an error: "tags not supported", so I guess I am asking, is there a way to set the "Name" of the elastic ip with cloud-formation?

Cheers

like image 350
donkeyx Avatar asked Apr 24 '18 04:04

donkeyx


People also ask

How do I associate AWS Elastic IP?

To associate an Elastic IP address with a network interfaceOpen the Amazon EC2 console at https://console.aws.amazon.com/ec2/ . In the navigation pane, choose Elastic IPs. Select the Elastic IP address to associate and choose Actions, Associate Elastic IP address. For Resource type, choose Network interface.

Can CloudFormation create elastic IP?

You can allocate an Elastic IP address from an address pool owned by AWS or from an address pool created from a public IPv4 address range that you have brought to AWS for use with your AWS resources using bring your own IP addresses (BYOIP).

How do I name an EC2 instance in CloudFormation?

My comment is not about templates, but this is the only question I find about naming EC2 instances, so I'm writing this here. You can name an instance by select the instance and choosing Actions => Edit Tags and add a tag for Name (case sensitive).


2 Answers

Reason for your error is in CloudFormation, elastic IP resources "AWS::EC2::EIP" not supporting Tags for Properties.

For the second question, as far as I know, there's no way, at the moment to name an elastic IP from cloud formation.

Update (11/22/2019) Tags are now supported. Refer the Docs here.

like image 119
SAUJ Avatar answered Jan 02 '23 20:01

SAUJ


Don't hold your breath, here is a thread on AWS forums, started in 2012 on this subject.

Instead use CloudFormation Custom Resources to varnish over this and other CFN shortcomings.

Following is my implementation using Python and 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)

(you'll need to package cfn-response with this function)

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'

Hope this helps.

like image 43
ab77 Avatar answered Jan 02 '23 21:01

ab77