如何使用boto3为含无初始标签新桶的S3桶批量追加标签
需求说明
使用Python boto3为指定AWS账号下的所有S3存储桶添加标签,覆盖范围包含已存在的存量存储桶、创建后未设置任何初始标签的新建存储桶。标签配置需遵守以下规则:
- 若存储桶已配置
Key="Falcon Managed", Value="true"标签(即Falcon托管桶),直接跳过该桶,不做任何标签修改 - 其余非Falcon托管桶,需在保留全部原有标签的基础上追加新标签,不得删除已有标签,也不得重复添加相同Key的标签
现有实现与问题
初始实现脚本如下:
import boto3 from botocore.exceptions import ClientError s3bucket=boto3.client("s3") s3=boto3.resource('s3') falcon_s3=False print ("=================Adding tags to S3 Buckets==================") list_bucket=s3bucket.list_buckets() for buckets in list_bucket['Buckets']: try: Bucket_Existing_tags = s3.BucketTagging(buckets['Name']).tag_set for tags in Bucket_Existing_tags: if tags["Key"]=="Falcon Managed" and tags["Value"] =="true": print("This Bucket is belonged to Falcons -->"+ buckets["Name"]) falcon_s3=True break else: bucket_tagging = s3.BucketTagging(buckets['Name']) tags = bucket_tagging.tag_set tags.append({'Key':'Technical:Patcher', 'Value': 'goats'}) Set_Tag = bucket_tagging.put(Tagging={'TagSet':tags}) print('Tags added for ---> ' + buckets['Name']) except ClientError as e: print("Unexpected error: %s" % e)
脚本初始逻辑为遍历账号下所有S3桶,读取桶现有标签集,识别到Falcon托管桶则打印标识并跳过,其余桶直接在现有标签集后追加{'Key':'Technical:Patcher', 'Value': 'goats'}标签后提交。运行时存在三类问题:
- 无法处理无初始标签的新建桶:读取这类桶的标签集时会触发
NoSuchTagSet错误,导致无法为这类桶添加标签 - 重复运行容错性差:脚本未检查待追加标签是否已存在,重复运行时会重复添加同Key标签,触发
InvalidTag错误 - 逻辑bug:
falcon_s3变量定义在循环外,遍历到第一个Falcon托管桶后标记会被永久设为True,后续所有桶都会被误判为Falcon托管桶
脚本实际运行输出如下:
=================Adding tags to S3 Buckets================== Unexpected error: An error occurred (NoSuchTagSet) when calling the GetBucketTagging operation: The TagSet does not exist Unexpected error: An error occurred (InvalidTag) when calling the PutBucketTagging operation: Cannot provide multiple Tags with the same key This Bucket is belonged to Falcons -->test-1-test-tag-adder Tags added for ---> test-2-test-tag-adder Unexpected error: An error occurred (NoSuchTagSet) when calling the GetBucketTagging operation: The TagSet does not exist Unexpected error: An error occurred (NoSuchTagSet) when calling the GetBucketTagging operation: The TagSet does not exist Unexpected error: An error occurred (InvalidTag) when calling the PutBucketTagging operation: Cannot provide multiple Tags with the same key Unexpected error: An error occurred (InvalidTag) when calling the PutBucketTagging operation: Cannot provide multiple Tags with the same key
修复后代码
修复点对应上述三类问题:
- 单独捕获
NoSuchTagSet异常,无初始标签的桶将现有标签集初始化为空列表 - 追加标签前先校验现有标签的Key,已存在目标标签则直接跳过,不重复添加
- 将Falcon桶标记的变量移入循环内部,每次遍历桶时重置状态,避免跨桶的标记污染
import boto3 from botocore.exceptions import ClientError # 固定配置项 TARGET_TAG_KEY = 'Technical:Patcher' TARGET_TAG_VALUE = 'goats' FALCON_TAG_KEY = 'Falcon Managed' FALCON_TAG_VALUE = 'true' s3_client = boto3.client("s3") s3_resource = boto3.resource('s3') print("=================Adding tags to S3 Buckets==================") bucket_list = s3_client.list_buckets() for bucket in bucket_list['Buckets']: bucket_name = bucket['Name'] is_falcon_managed = False existing_tags = [] try: # 读取桶现有标签 bucket_tagging = s3_resource.BucketTagging(bucket_name) existing_tags = bucket_tagging.tag_set except ClientError as e: if e.response['Error']['Code'] == 'NoSuchTagSet': # 桶无任何初始标签,初始化为空标签列表 existing_tags = [] else: print(f"读取桶{bucket_name}标签失败,错误: {e}") continue # 校验是否为Falcon托管桶 for tag in existing_tags: if tag["Key"] == FALCON_TAG_KEY and tag["Value"] == FALCON_TAG_VALUE: print(f"Falcon托管桶,跳过处理 --> {bucket_name}") is_falcon_managed = True break if is_falcon_managed: continue # 校验目标标签是否已存在 tag_already_exists = False for tag in existing_tags: if tag["Key"] == TARGET_TAG_KEY: tag_already_exists = True break if tag_already_exists: print(f"目标标签已存在,跳过追加 --> {bucket_name}") continue # 追加新标签并提交 existing_tags.append({'Key': TARGET_TAG_KEY, 'Value': TARGET_TAG_VALUE}) try: s3_resource.BucketTagging(bucket_name).put(Tagging={'TagSet': existing_tags}) print(f"标签添加成功 --> {bucket_name}") except ClientError as e: print(f"为桶{bucket_name}添加标签失败,错误: {e}")
运行前需确保执行环境的AWS身份拥有
s3:GetBucketTagging、s3:PutBucketTagging权限,否则会触发权限类错误。
内容的提问来源于stack exchange,提问作者DMUN
相关产品推荐
相关产品推荐

