构建Labmda函数实现AWS资源自动标签

3185f0d5ae8c4472a1b852641ca5b6e9.gif

 新钛云服已累计为您分享809篇技术干货

9c6b4a27051fe4d475aea511920d96ad.gif

本篇文章介绍了一种自动为AWS资源打标签的解决方案,当前支持以下资源的自动打标签:

  • EC2Elastic Compute Cloud

  • EBSElastic Block Store

  • RDSRelational Database Service

  • S3 bucket

  • S3 object(需要开启事件记录,默认不开启)

  • VPCVirtual Private Cloud

  • ELBElastic Load Balancer

  • Target Groups

程序逻辑

通过CloudTrail追踪创建资源事件,EventBridge根据预设的规则判断并触发Lambda函数。Lambda 函数运行 Python代码进行打标签操作。

整个过程实现自动化,无需人工干涉。这种解决方案不仅提高了资源管理的效率,还能帮助组织更好地进行成本管理和合规性检查。

具体实现

Lambda

创建Lambda资源

将编写好的Lambda函数部署到AWS Lambda服务中。配置EventBridge规则,使Lambda函数能够响应预定义的事件,如EC2实例启动、S3对象创建等。

efc2daf99975ae0086465b7ced48c114.png

在Lambda函数首页选择创建函数

63e8efbebf399ee3c124da2f013fe376.png

Lambda 将创建一个名为 Lambda-AutoTag-role-1n9jg0j9 的执行角色,此角色具有将日志上传到 Amazon CloudWatch Logs 的权限。

设置角色权限

在角色列表中找到Lambda角色

749c0f3364d48209da0e0fcedd7121f2.png

点击权限策略

556cebf5db24188beeb1948f5feed254.png

点击编辑角色权限

2d80bdc7eaa049ff3e3d1245a1063656.png

添加如下权限

JSON
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ec2:Describe*",
                "ec2:CreateTags*",
                "rds:AddTagsToResource",
                "elasticloadbalancing:AddTags",
                "s3:PutObjectTagging",
                "s3:PutBucketTagging",
                "logs:CreateLogGroup",
                "logs:PutLogEvents",
                "logs:CreateLogStream"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

添加代码到Lambda

在代码源中新增两个python文件

372967360875a68cafe696d815488455.png

lambda_function.py

用于根据事件名称判断具体触发事件

Python
from __future__ import print_function
import logging
from autotag import AutoTag


logger = logging.getLogger()
logger.setLevel(logging.INFO)




def lambda_handler(event, context):
    logger.info(f"{event=}")
    detail = event['detail']
    eventname = detail['eventName']
    logger.info(f"{eventname=}")




    tools = AutoTag(event)
    if eventname == 'RunInstances':
        # EC2
        tools.create_tag_to_ec2()


    elif eventname == 'CreateDBInstance':
        # RDS
        tools.create_tag_to_rds()


    elif eventname == 'CreateVpc':
     # VPC
        tools.create_tag_to_vpc()


    elif eventname == 'CreateBucket':
        # 给 S3 桶打标签
        tools.create_tag_to_s3_bucket()


    elif eventname == 'CreateLoadBalancer':
        # ELB
        tools.create_tag_to_elb()


    elif eventname == 'CreateTargetGroup':
        # TargetGroup ELB目标组
        tools.create_tag_to_target_groups()


    elif eventname == 'PutObject':
        # 给 S3 中 Object 打标签
        tools.create_tag_to_s3_object()




    else:
        logger.error(f'{eventname=} 未定义的操作')
        return False


    logger.info("Success!")
    return True

autotag.py

提取资源实例ID,并进行具体的打标签操作

Python
import logging
import boto3


logger = logging.getLogger()
logger.setLevel(logging.INFO)


class AutoTag:
    def __init__(self, event):
        self.detail = event['detail']
        self.Tag_Key = 'map-migrated'
        self.Tag_Value = 'migX1EPYP8W1L'
        self.Tags = [{'Key': self.Tag_Key, 'Value': self.Tag_Value}]


    def create_tag_to_ec2(self):
        ids = []
        client = boto3.resource('ec2')


        items = self.detail['responseElements']['instancesSet']['items']
        for item in items:
            ids.append(item['instanceId'])
        logger.info(ids)
        base = client.instances.filter(InstanceIds=ids)
        for instance in base:
            for vol in instance.volumes.all():
                ids.append(vol.id)
            for eni in instance.network_interfaces:
                ids.append(eni.id)
        if ids:
            logger.info(f"对ec2实例列表: {ids}进行打标")
            response = client.create_tags(Resources=ids,
                        Tags=self.Tags)
            logger.info(f"打标完成! {response=}")




    def create_tag_to_dynamodb(self):
        client = boto3.client('dynamodb')
        resource_arn = self.detail['responseElements']['tableDescription']['tableArn']
        logger.info(f"对dynamodb实例列表: {resource_arn}进行打标")
        client.tag_resource(ResourceArn=resource_arn, Tags=self.Tags)




    def create_tag_to_lambda(self):
        # Lambda 的实际 API 与文档中并不一致, 其组成为 AIP 名字+版本
        client = boto3.client('lambda')


        function_arn = self.detail['responseElements']['functionArn']
        logger.info(f"对lambda实例列表: {function_arn}进行打标")
        client.tag_resource(Resource=function_arn, Tags=self.Tags)


    def create_tag_to_rds(self):
        client = boto3.client('rds')
        resource_arn = self.detail['responseElements']['dBInstanceArn']
        logger.info(f"对rds实例列表: {resource_arn}进行打标")
        client.add_tags_to_resource(ResourceName=resource_arn, Tags=self.Tags)


    def create_tag_to_elb(self):
        client = boto3.client('elbv2')
        resource_arn = self.detail['responseElements']['loadBalancers'][0]['loadBalancerArn']
        ids = []
        ids.append(resource_arn)
        logger.info(f"对elb实例列表: {ids}进行打标")
        client.add_tags(ResourceArns=ids, Tags=self.Tags)


    def create_tag_to_target_groups(self):
        client = boto3.client('elbv2')
        resource_arn = self.detail['responseElements']['targetGroups'][0]['targetGroupArn']
        ids = []
        ids.append(resource_arn)
        logger.info(f"对elb实例列表: {ids}进行打标")
        client.add_tags(ResourceArns=ids, Tags=self.Tags)


    def create_tag_to_s3_object(self):
        s3 = boto3.client("s3")
        bucket_name = self.detail['requestParameters']['bucketName']
        object_name = self.detail['requestParameters']['key']


        tags = [{'Key': 'Owner', 'Value': self.user}, {'Key': 'PrincipalId', 'Value': self.principal}]
        s3.put_object_tagging(Bucket=bucket_name, Key=object_name, Tagging={'TagSet': tags})


    def create_tag_to_s3_bucket(self):
        s3 = boto3.client("s3")
        bucket_name = self.detail['requestParameters']['bucketName']
        logger.info(f"对s3_bucket: {bucket_name}进行打标")
        s3.put_bucket_tagging(Bucket=bucket_name, Tagging={'TagSet': self.Tags})


    def create_tag_to_vpc(self):
        vpc_id = self.detail['responseElements']['vpc']['vpcId']


        ec2 = boto3.resource('ec2')
        vpc = ec2.Vpc(vpc_id)
        logger.info(f"对vpc: {vpc}进行打标")
        vpc.create_tags(DryRun=False, Tags=self.Tags)

修改预设标签值

按需更改以下三个参数即可:

Python
AutoTag.Tag_Key = 'map-migrated'
AutoTag.Tag_Value = 'migX1EPYP8W1L'
AutoTag.Tags = [{'Key': self.Tag_Key, 'Value': self.Tag_Value}]

创建事件跟踪(CloudTrail)

使用 AWS CloudTrail 来跟踪资源创建事件。CloudTrail能够记录所有对AWS 账户的 API 调用,并生成日志文件。确保 CloudTrail 已经启用,并且记录了所有必要的事件。 重点在于将事件信息发送到CloudWatch

进入 CloudTrail 首页

8f93e2ba0eacf53c007edd263b7e4bda.png

选择并创建跟踪

d980177ca5318583a3e241ca424fcf6c.png

创建 EventBridge 资源

设置AWS EventBridge规则,根据CloudTrail捕获的资源创建事件来触发特定的Lambda函数。EventBridge可以根据事件模式匹配预设规则,从而准确地选择需要处理的事件。

在 CloudWatch 中点击事件规则

c396c1a085be9a52e63431fdde41a977.png

创建规则

规则类型选择具有事件模式的规则

5f765d65c5d5960eb8c1413824add8ba.png

事件模式

选择自定义模式(JSON编辑器)

d60ff145eb2db74041e8bc08dac515a6.png

预设触发规则

将以下自定义规则填入事件模式中

JSON
{
  "source": [
      "aws.ec2", 
      "aws.s3", 
      "aws.rds", 
      "aws.vpn", 
      "aws.elasticloadbalancing"
  ],
  "detail-type": ["AWS API Call via CloudTrail"],
  "detail": {
    "eventSource": [
        "ec2.amazonaws.com", 
        "s3.amazonaws.com", 
        "rds.amazonaws.com", 
        "vpn.amazonaws.com", 
        "elasticloadbalancing.amazonaws.com"
    ],
    "eventName": [
        "RunInstances", 
        "CreateBucket", 
        "CreateDBInstance", 
        "CreateVpc", 
        "CreateLoadBalancer", 
        "CreateTargetGroup", 
        "PutObject"
    ]
  }
}

预设目标动作

选择刚创建的Lambda函数

f7d52f6e74e0ca946c81b1242d891dbd.png

生成规则

点击创建规则,并检查Lambda函数是否成功绑定

4b6b713ec73cbfaefc0de214a4f3dfcd.png

检查Lambda 函数触发器

创建完成EventBridge后,返回Lambda页面,检查是否自动绑定触发器,如果未绑定,手动添加

f5d409e30274b22bf70eb342b53d12db.png

结果展示

创建一台EC2服务器,查看标签已经被添加成功

7b4bd34e5314d650159b2f96ccdde383.png

查看其存储卷,自动增加标签

48c8297e78bacc95d1b3f18e4be12671.png

RDS自动增加标签

66789a20db3c902e925be651b1bb6a29.png

VPC自动增加标签

8d1c5c39b77cf8f4b93ab9aecdb1ff99.png

ELB自动增加标签

84603078ccf23f7bff6c49bd68f086c1.png

TargetGroup自动增加标签

d2b8fa402302913e6910ede186118e85.png

S3 bucket自动增加标签

996bf56fc3ec29868adc2c5b045e90a0.png

如有相关问题,请在文章后面给小编留言,小编安排作者第一时间和您联系,为您答疑解惑。

    推荐阅读   

7274b49d9ef4e802a9b6ec55f0e0c193.png

29a7450507c22e12c71c76705c7ef74e.png

    推荐视频    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值