getmoto / moto

A library that allows you to easily mock out tests based on AWS infrastructure.
http://docs.getmoto.org/en/latest/
Apache License 2.0
7.6k stars 2.03k forks source link

EC2 CreateTags throws TagLimitExceeded while updating existing tags #8151

Closed elstak closed 3 days ago

elstak commented 4 days ago

Exiting tags cannot be overwritten using CreateTags API call when the number of tags has reached the limit of 50.

The following code reproduces the bug:

import os
import boto3
from moto import mock_aws

with mock_aws():
    os.environ['AWS_ACCESS_KEY_ID'] = 'testing'
    os.environ['AWS_SECRET_ACCESS_KEY'] = 'testing'
    os.environ['AWS_SECURITY_TOKEN'] = 'testing'
    os.environ['AWS_SESSION_TOKEN'] = 'testing'
    client = boto3.client('ec2', region_name='us-east-1')
    response = client.describe_images(Filters=[{'Name': 'Name', 'Values': ['al2023-ami-*']}], Owners=['137112412989'])
    ami_id = response['Images'][0]['ImageId']
    ami_tags = len(response['Images'][0]['Tags'])
    print(f'AMI ID {ami_id} has {ami_tags} tags - Creating tags...')
    client.create_tags(
        Resources=[ami_id],
        Tags=[{'Key': f'tag{i}', 'Value': f'value{i}'} for i in range(ami_tags, 50)]
    )
    response = client.describe_images(Filters=[{'Name': 'Name', 'Values': ['al2023-ami-*']}], Owners=['137112412989'])
    ami_id = response['Images'][0]['ImageId']
    ami_tags = len(response['Images'][0]['Tags'])
    print(f'AMI ID {ami_id} has {ami_tags} tags - Updating tags...')
    client.create_tags(
        Resources=[ami_id],
        Tags=[{'Key': 'tag33', 'Value': 'new-value'}]
    )

Although tag limit (50) has been reached, we should be able to overwrite existing tags. Instead, an exception is thrown:

botocore.exceptions.ClientError: An error occurred (TagLimitExceeded) when calling the CreateTags operation: The maximum number of Tags for a resource has been reached.

I've created a fix: #8150

Thanks.

ayetealab commented 4 days ago

+1 @elstak