【问题标题】:How do you automate tagging using a Lambda function on AWS?如何在 AWS 上使用 Lambda 函数自动标记?
【发布时间】:2019-10-22 09:12:42
【问题描述】:

我正在尝试自动标记 AWS 上的以下资源:

  • 亚马逊 RDS
  • Amazon DynamoDB
  • 亚马逊图像 AMI
  • Amazon EC2 实例
  • Amazon Lambda 函数
  • Amazon RDS 快照
  • Amazon RDS 安全性
  • Amazon RDS 子网
  • Amazon Route 53 托管
  • Amazon S3 存储桶
  • Amazon CloudFormation

目前我有一个与本文几乎相同的 Lambda 函数:How to Automatically Tag Amazon EC2 Resources in Response to API Events | AWS Security Blog

如何修改此 Lambda 函数,使其也标记上述资源?

我已尝试查找有关如何标记这些特定资源的文档,但似乎找不到与使用 Lambda 函数进行标记相关的任何内容。

elif eventname == 'CreateImage':
    ids.append(detail['responseElements']['imageId'])
    logger.info(ids)

elif eventname == 'CreateSnapshot':
    ids.append(detail['responseElements']['snapshotId'])
    logger.info(ids)
elif eventname == 'CreateSecurityGroup':
    ids.append(detail['responseElements']['groupId'])
else:
    logger.warning('Not supported action')

上面的代码是为 EC2 添加标签,但是我们需要它来为我上面列出的资源添加标签。

【问题讨论】:

    标签: python-2.7 amazon-web-services aws-lambda tagging


    【解决方案1】:

    要在创建时标记资源,您需要使用 Lambda、Cloudwatch 事件和一些自动化。

    您可以使用资源创建者的 IAM ARN 和资源创建日期以及可用的文档 here 来标记资源,这是 AWS 的开源标记解决方案。 这将帮助您使用创建者的 IAM ARN 和资源创建日期标记您的资源。

    您可以通过两种方式实施上述链接中提供的解决方案, 1. Shell 脚本和 2. CloudFormation 模板。

    【讨论】:

      【解决方案2】:

      这应该对他们中的一些人有所帮助。

      以下是 cloudwatch 事件模式:

      {
        "detail-type": [
          "AWS API Call via CloudTrail"
        ],
        "detail": {
          "eventSource": [
            "ec2.amazonaws.com",
            "rds.amazonaws.com",
            "lambda.amazonaws.com",
            "s3.amazonaws.com",
            "dynamodb.amazonaws.com",
            "elasticfilesystem.amazonaws.com"
          ],
          "eventName": [
            "CreateVolume",
            "RunInstances",
            "CreateImage",
            "CreateSnapshot",
            "CreateDBInstance",
            "CreateFunction20150331",
            "UpdateFunctionConfiguration20150331v2",
            "UpdateFunctionCode20150331v2",
            "CreateBucket",
            "CreateTable",
            "CreateMountTarget"
          ]
        }
      }
      

      然后是相应的 lambda 代码,需要对您的环境进行一些修改。

      from __future__ import print_function
      import json
      import boto3
      import logging
      import time
      import datetime
      
      logger = logging.getLogger()
      logger.setLevel(logging.INFO)
      
      def lambda_handler(event, context):
          logger.info('################  Event: ############## ' + str(event))
          #print('Received event: ' + json.dumps(event, indent=2))
      
          ids = []
      
          try:
              region = event['region']
              detail = event['detail']
              eventname = detail['eventName']
              arn = detail['userIdentity']['arn']
              principal = detail['userIdentity']['principalId']
              userType = detail['userIdentity']['type']
      
              if userType == 'IAMUser':
                  user = detail['userIdentity']['userName']
      
              else:
                  user = principal.split(':')[1]
      
      
              logger.info('principalId: ' + str(principal))
              logger.info('region: ' + str(region))
              logger.info('eventName: ' + str(eventname))
              logger.info('detail: ' + str(detail))
      
              ec2_client = boto3.resource('ec2')
              lambda_client = boto3.client('lambda')
              rds_client = boto3.client('rds')
              s3_client = boto3.resource('s3')
              ddb_client = boto3.client('dynamodb')
              efs_client = boto3.client('efs')
      
              if eventname == 'CreateVolume':
                  ids.append(detail['responseElements']['volumeId'])
                  logger.info(ids)
      
              elif eventname == 'RunInstances':
                  items = detail['responseElements']['instancesSet']['items']
                  for item in items:
                      ids.append(item['instanceId'])
                  logger.info(ids)
                  logger.info('number of instances: ' + str(len(ids)))
      
                  base = ec2_client.instances.filter(InstanceIds=ids)
      
                  #loop through the instances
                  for instance in base:
                      for vol in instance.volumes.all():
                          ids.append(vol.id)
                      for eni in instance.network_interfaces:
                          ids.append(eni.id)
      
              elif eventname == 'CreateImage':
                  ids.append(detail['responseElements']['imageId'])
                  logger.info(ids)
      
              elif eventname == 'CreateSnapshot':
                  ids.append(detail['responseElements']['snapshotId'])
                  logger.info(ids)
      
              elif eventname == 'CreateFunction20150331':
                  try:
                      functionArn = detail['responseElements']['functionArn']
                      lambda_client.tag_resource(Resource=functionArn,Tags={'CreatedBy': user})
                      lambda_client.tag_resource(Resource=functionArn,Tags={'DateCreated': time.strftime("%B %d %Y")})
                  except Exception as e:
                      logger.error('Exception thrown at CreateFunction20150331' + str(e))
                      pass
              elif eventname == 'UpdateFunctionConfiguration20150331v2':
                  try:
                      functionArn = detail['responseElements']['functionArn']
                      lambda_client.tag_resource(Resource=functionArn,Tags={'LastConfigModifiedByNetID': user})
                  except Exception as e:
                      logger.error('Exception thrown at UpdateFunctionConfiguration20150331v2' + str(e))
                      pass
              elif eventname == 'UpdateFunctionCode20150331v2':
                  try:
                      functionArn = detail['responseElements']['functionArn']
                      lambda_client.tag_resource(Resource=functionArn,Tags={'LastCodeModifiedByNetID': user})
                  except Exception as e:
                      logger.error('Exception thrown at UpdateFunctionCode20150331v2' + str(e))
                      pass
              elif eventname == 'CreateDBInstance':
                  try:
                      dbResourceArn = detail['responseElements']['dBInstanceArn']
                      rds_client.add_tags_to_resource(ResourceName=dbResourceArn,Tags=[{'Key':'CreatedBy','Value': user}])
                  except Exception as e:
                      logger.error('Exception thrown at CreateDBInstance' + str(e))
                      pass
              elif eventname == 'CreateBucket':
                  try:
                      bucket_name = detail['requestParameters']['bucketName']
                      s3_client.BucketTagging(bucket_name).put(Tagging={'TagSet': [{'Key':'CreatedBy','Value': user}]})
                  except Exception as e:
                      logger.error('Exception thrown at CreateBucket' + str(e))
                      pass
              elif eventname == 'CreateTable':
                  try:
                      tableArn = detail['responseElements']['tableDescription']['tableArn']
                      ddb_client.tag_resource(ResourceArn=tableArn,Tags=[{'Key':'CreatedBy','Value': user}])
                  except Exception as e:
                      logger.error('Exception thrown at CreateTable' + str(e))
                      pass
              elif eventname == 'CreateMountTarget':
                  try:
                      system_id = detail['requestParameters']['fileSystemId']
                      efs_client.create_tags(FileSystemId=system_id, Tags=[{'Key':'CreatedBy','Value': user}])
                  except Exception as e:
                      logger.error('Exception thrown at CreateMountTarget' + str(e))
                      pass
              # todo: EMR and Glacier also possible candidates
              else:
                  logger.warning('No matching eventname found in the Auto Tag lambda function (Ln 118)')
      
              if ids:
                  for resourceid in ids:
                      print('Tagging resource ' + resourceid)
                  ec2_client.create_tags(Resources=ids, Tags=[{'Key': 'CreatedBy', 'Value': user}])
      
              logger.info(' Remaining time (ms): ' + str(context.get_remaining_time_in_millis()) + '\n')
              return True
          except Exception as e:
              logger.error('Something went wrong: ' + str(e))
              return False
      

      您受到 Cloudwatch 事件支持的限制,但这有望帮助您淘汰列表中的一些事件。

      【讨论】:

      • 非常感谢您的帮助。我会开始测试你的脚本,看看会发生什么。
      • 我们的环境已经有一个 cloudformation 堆栈来自动标记 EC2。我尝试将您的代码添加到我们当前的 Lambda 函数并修改 CloudWatch 规则。我仍然无法自动标记。你知道我可能做错了什么吗?我是否必须创建一个全新的 CloudFormation 堆栈才能使其正常工作?
      【解决方案3】:

      也许来自 python boto lib 的东西会有所帮助(以 RDS 为例):

      https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html#RDS.Client.add_tags_to_resource

      response = client.add_tags_to_resource(
      ResourceName='arn:aws:rXXXXX,
      Tags=[
      {
      'Key': 'Staging',
      'Value': '2019',
      },
      ], )
      

      【讨论】:

        猜你喜欢
        • 2017-10-11
        • 2021-03-20
        • 1970-01-01
        • 2020-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-19
        • 1970-01-01
        相关资源
        最近更新 更多