AWS: Lambda –  copy EC2 tags to its EBS, half 2  –  create a Lambda operate






AWS: Lambda — copy EC2 tags to its EBS, half 2 — create a Lambda operate

let’s proceed in our journey of the AWS Lambda operate, which can copy an EC2’s AWS Tags to all EBS volumes, connected to it.

Within the first half, AWS: Lambda — copy EC2 tags to its EBS, part 1 — Python and boto3, we wrote a Python script that may get all EC2 situations in an AWS Area, then for each EC2 it grabs its EBS volumes, after which will copy all AWS Tags from the EC2 to all its EBS plus will add one extra.

On this half, we’ll create an AWS Lambda operate that will probably be triggered with the AWS CloudWatch Occasions.



Contents



Creating an AWS Lambda operate

Go to the AWS Lambda, create a brand new operate from the ”Writer from scratch”, with the Runtime set as Python 3.8:

Within the Execution function go away the “Create a brand new function” — later, we’ll add extra permissions to it with an IAM Coverage.

Paste the script’s code to the operate, on the finish of the code replace the lambda_hanlder() execution and in its arguments as a substitute of the “0, 0″ from the earlier put up, set the occasion, context:

To verify the content material of the occasion object, which we’ll use later to get an EC2 ID, add its output to the operate’s log.

Add import json and print("CONTEXT: " + json.dumps(occasion)):

Additionally, for the ec2 = boto3.useful resource() name take away AWS keys, and go away the one kind of the useful resource – “ec2“:

Don’t forget to press the Deploy button to use your modifications to the AWS Lambda.



Including an Amazon EventBridge (CloudWatch Occasions) set off

Subsequent, we have to run this operate every time when a brand new EC2 is launched in a area.

Right here, we will use the Amazon EventBridge (former CloudWatch Occasions). Go to the CloudWatch Occasions > Guidelines, click on on the Create rule:

Within the Occasion Sample select the Service Title == EC2, within the Occasion Kind select the “EC2 Occasion State-change Notification”, and within the Particular state(s) select operating:

On the proper facet within the Add goal select the AWS Lambda operate that we’ve created above:

On the finish of the web page, within the Present pattern occasion(s), we will see an instance of the occasion object that will probably be handed to the operate to get an EC2 ID:

Save the brand new rule:

Verify if it was added to the Lambda operate as a set off:

And let’s verify how it will work.

Within the CloudWatch Guidelines open the Rule’s monitoring:

Spin up a brand new EC2, for instance by triggering an AutoScale Group:

On the CloudWatch graph we will see, that the Rule was triggered:

Verify the Lambda operate’s logs:



AWS Lambda: UnauthorizedOperation

Within the logs, we’re considering two information.

The primary one  –  is the occasion content material, that was saved to the log from the print("CONTEXT: " + json.dumps(occasion)):

And the second is the “ClientError: An error occurred (UnauthorizedOperation) when calling the DescribeInstances operation: You aren’t approved to carry out this operation” error:

The difficulty right here is apparent sufficient: our Lambda operate now could be utilizing an IAM Function, that was created throughout the operate’s creation, and it has no permissions for API requires the EC2 actions:

Go to the AWS IAM, discover the Function, click on on the Connect insurance policies:

Create a brand new coverage:

Describe EC2 permissions right here:

{
    "Model": "2012-10-17",
    "Assertion": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "ec2:DeleteTags",
                "ec2:CreateTags",
                "ec2:DescribeVolumes"
            ],
            "Useful resource": "*"
        }
    ]
}
Enter fullscreen mode

Exit fullscreen mode

Put it aside:

Return to the Lambda operate’s IAM Function, and add a brand new Coverage:

Repeat a brand new EC2 launch and verify the operate’s logs once more:

Yay! “ It really works! ” ©

Subsequent, must replace the code to get the instance-id from the occasion object.



Parsing a Lambda occasion

We’ve already seen an instance of the occasion after we’ve created the CloudWatch Rule, and we all know that it is going to be handed to the lambda_handler() operate as a python-dictionary with a set of keys:

{
    "model": "0",
    "id": "a99597e5-90a5-5ac3-3aba-da3ecd51452a",
    "detail-type": "EC2 Occasion State-change Notification",
    "supply": "aws.ec2",
    "account": "534***385",
    "time": "2021-10-11T09:02:09Z",
    "area": "eu-west-3",
    "assets": [
        "arn:aws:ec2:eu-west-3:534***385:instance/i-0cc24729109ba61e5"
    ],
    "element": {
        "instance-id": "i-0cc24729109ba61e5",
        "state": "operating"
    }
}
Enter fullscreen mode

Exit fullscreen mode

And from right here we have to seize a price of the element.instance-id component.

Add a brand new variable to the script, let’s name it instance_id, and it’ll maintain a price from the occasion["detail"]["instance-id"], after which by utilizing this ID, we’re creating a brand new object of the ec2.Occasion class, the ec2.Occasion(instance_id):

As a substitute of operating a brand new EC2 manually, we will use the Take a look at for our Lambda by passing an occasion object to it.

Create a brand new check occasion:

Add an information much like that we are going to get from the CloudWatch:

{
    "model": "0",
    "id": "a99597e5-90a5-5ac3-3aba-da3ecd51452a",
    "detail-type": "EC2 Occasion State-change Notification",
    "supply": "aws.ec2",
    "account": "534***385",
    "time": "2021-10-11T09:02:09Z",
    "area": "eu-west-3",
    "assets": [
        "arn:aws:ec2:eu-west-3:534***385:instance/i-0cc24729109ba61e5"
    ],
    "element": {
        "instance-id": "i-0cc24729109ba61e5",
        "state": "operating"
    }
}
Enter fullscreen mode

Exit fullscreen mode

Run the check:

“It really works!” _ ©_

And now let’s spin up a typical EC2 to verify the entire scheme together with CloudWatch Occasion, Lambda’s set off, and its execution outcomes.

Set off an AutoScaling Group:

A brand new EC2 i-051f2e1f1bc8d332b was created, verify Lambda’s logs:

Discover an EBS of this EC2:

And verify its Tags:

And the operate’s code now could be the subsequent:

#!/usr/bin/env python

import os
import json
import boto3

def lambda_handler(occasion, context):

    ec2 = boto3.useful resource('ec2')
    instance_id = occasion["detail"]["instance-id"]
    occasion = ec2.Occasion(instance_id)

    print("[DEBUG] EC2nttID: " + str(occasion))
    print("tEBS")

    for vol in occasion.volumes.all():

        vol_id = str(vol)
        print("VOLUME: " + str(vol))

        device_id = "ec2.vol.Machine('" + str(vol.attachments[0]['Device']) + "')"
        print("ttID: " + vol_id + "nttDev: " + device_id)

        role_tag = vol.create_tags(Tags=set_role_tag(vol))
        ec2_tags = vol.create_tags(Tags=copy_ec2_tags(occasion))
        print("ttTags set:nttt" + str(role_tag) + "nttt" + str(ec2_tags) + "n")

def is_pvc(vol): 

    strive:
        for tag in vol.tags:
            if tag['Key'] == 'kubernetes.io/created-for/pvc/identify':
                return True
                break
    besides TypeError:
            return False

def set_role_tag(vol):

    gadget = vol.attachments[0]['Device']
    tags_list = []
    values = {}

    if is_pvc(vol):
        values['Key'] = "Function"
        values['Value'] = "PvcDisk"
        tags_list.append(values)
    elif gadget == "/dev/xvda":
        values['Key'] = "Function"
        values['Value'] = "RootDisk"
        tags_list.append(values)
    else:   
        values['Key'] = "Function"
        values['Value'] = "DataDisk"
        tags_list.append(values)

    return tags_list


def copy_ec2_tags(occasion):

    tags_list = []
    values = {} 

    for instance_tag in occasion.tags:

        if instance_tag['Key'] == 'Env':
            tags_list.append(instance_tag)
        elif instance_tag['Key'] == 'Tier':
            tags_list.append(instance_tag)
        elif instance_tag['Key'] == 'DataClass':
            tags_list.append(instance_tag)
        elif instance_tag['Key'] == 'JiraTicket':
            tags_list.append(instance_tag)

    return tags_list

if __name__ == " __main__":
    lambda_handler(occasion, context)
Enter fullscreen mode

Exit fullscreen mode

Achieved.

Initially printed at RTFM: Linux, DevOps, and system administration.




Abu Sayed is the Best Web, Game, XR and Blockchain Developer in Bangladesh. Don't forget to Checkout his Latest Projects.


Checkout extra Articles on Sayed.CYou

#AWS #Lambda #copy #EC2 #tags #EBS #half #create #Lambda #operate