diff --git a/moto/ec2/models.py b/moto/ec2/models.py
index 5e55b6276..d6d92da43 100644
--- a/moto/ec2/models.py
+++ b/moto/ec2/models.py
@@ -2892,6 +2892,7 @@ class VPCBackend(object):
cidr_block,
instance_tenancy="default",
amazon_provided_ipv6_cidr_block=False,
+ tags=[],
):
vpc_id = random_vpc_id()
try:
@@ -2910,6 +2911,12 @@ class VPCBackend(object):
instance_tenancy,
amazon_provided_ipv6_cidr_block,
)
+
+ for tag in tags:
+ tag_key = tag.get("Key")
+ tag_value = tag.get("Value")
+ vpc.add_tag(tag_key, tag_value)
+
self.vpcs[vpc_id] = vpc
# AWS creates a default main route table and security group.
@@ -3409,6 +3416,7 @@ class SubnetBackend(object):
availability_zone=None,
availability_zone_id=None,
context=None,
+ tags=[],
):
subnet_id = random_subnet_id()
vpc = self.get_vpc(
@@ -3479,6 +3487,11 @@ class SubnetBackend(object):
assign_ipv6_address_on_creation=False,
)
+ for tag in tags:
+ tag_key = tag.get("Key")
+ tag_value = tag.get("Value")
+ subnet.add_tag(tag_key, tag_value)
+
# AWS associates a new subnet with the default Network ACL
self.associate_default_network_acl_with_subnet(subnet_id, vpc_id)
self.subnets[availability_zone][subnet_id] = subnet
diff --git a/moto/ec2/responses/subnets.py b/moto/ec2/responses/subnets.py
index 3bad8e12f..ef1b6249c 100644
--- a/moto/ec2/responses/subnets.py
+++ b/moto/ec2/responses/subnets.py
@@ -11,12 +11,21 @@ class Subnets(BaseResponse):
cidr_block = self._get_param("CidrBlock")
availability_zone = self._get_param("AvailabilityZone")
availability_zone_id = self._get_param("AvailabilityZoneId")
+ tags = self._get_multi_param("TagSpecification")
+ if tags:
+ tags = tags[0].get("Tag")
+
if not availability_zone and not availability_zone_id:
availability_zone = random.choice(
self.ec2_backend.describe_availability_zones()
).name
subnet = self.ec2_backend.create_subnet(
- vpc_id, cidr_block, availability_zone, availability_zone_id, context=self
+ vpc_id,
+ cidr_block,
+ availability_zone,
+ availability_zone_id,
+ context=self,
+ tags=tags,
)
template = self.response_template(CREATE_SUBNET_RESPONSE)
return template.render(subnet=subnet)
@@ -64,6 +73,16 @@ CREATE_SUBNET_RESPONSE = """
{{ subnet.assign_ipv6_address_on_creation }}
{{ subnet.ipv6_cidr_block_associations }}
arn:aws:ec2:{{ subnet._availability_zone.name[0:-1] }}:{{ subnet.owner_id }}:subnet/{{ subnet.id }}
+
+ {% for tag in subnet.get_tags() %}
+ -
+ {{ tag.resource_id }}
+ {{ tag.resource_type }}
+ {{ tag.key }}
+ {{ tag.value }}
+
+ {% endfor %}
+
"""
diff --git a/moto/ec2/responses/vpcs.py b/moto/ec2/responses/vpcs.py
index fc752fa7d..de4bb3feb 100644
--- a/moto/ec2/responses/vpcs.py
+++ b/moto/ec2/responses/vpcs.py
@@ -14,14 +14,19 @@ class VPCs(BaseResponse):
def create_vpc(self):
cidr_block = self._get_param("CidrBlock")
+ tags = self._get_multi_param("TagSpecification")
instance_tenancy = self._get_param("InstanceTenancy", if_none="default")
amazon_provided_ipv6_cidr_blocks = self._get_param(
"AmazonProvidedIpv6CidrBlock"
)
+ if tags:
+ tags = tags[0].get("Tag")
+
vpc = self.ec2_backend.create_vpc(
cidr_block,
instance_tenancy,
amazon_provided_ipv6_cidr_block=amazon_provided_ipv6_cidr_blocks,
+ tags=tags,
)
doc_date = self._get_doc_date()
template = self.response_template(CREATE_VPC_RESPONSE)
diff --git a/tests/test_ec2/test_subnets.py b/tests/test_ec2/test_subnets.py
index 45c9040fc..2d30171f0 100644
--- a/tests/test_ec2/test_subnets.py
+++ b/tests/test_ec2/test_subnets.py
@@ -327,7 +327,7 @@ def test_create_subnet_response_fields():
subnet.should.have.key("State")
subnet.should.have.key("SubnetId")
subnet.should.have.key("VpcId")
- subnet.shouldnt.have.key("Tags")
+ subnet.should.have.key("Tags")
subnet.should.have.key("DefaultForAz").which.should.equal(False)
subnet.should.have.key("MapPublicIpOnLaunch").which.should.equal(False)
subnet.should.have.key("OwnerId")
@@ -456,6 +456,23 @@ def test_create_subnets_with_overlapping_cidr_blocks():
)
+@mock_ec2
+def test_create_subnet_with_tags():
+ ec2 = boto3.resource("ec2", region_name="us-west-1")
+ vpc = ec2.create_vpc(CidrBlock="172.31.0.0/16")
+
+ subnet = ec2.create_subnet(
+ VpcId=vpc.id,
+ CidrBlock="172.31.48.0/20",
+ AvailabilityZoneId="use1-az6",
+ TagSpecifications=[
+ {"ResourceType": "subnet", "Tags": [{"Key": "name", "Value": "some-vpc"}]}
+ ],
+ )
+
+ assert subnet.tags == [{"Key": "name", "Value": "some-vpc"}]
+
+
@mock_ec2
def test_available_ip_addresses_in_subnet():
ec2 = boto3.resource("ec2", region_name="us-west-1")
diff --git a/tests/test_ec2/test_vpcs.py b/tests/test_ec2/test_vpcs.py
index 35705e482..8ad85072c 100644
--- a/tests/test_ec2/test_vpcs.py
+++ b/tests/test_ec2/test_vpcs.py
@@ -680,6 +680,19 @@ def test_create_vpc_with_invalid_cidr_range():
)
+@mock_ec2
+def test_create_vpc_with_tags():
+ ec2 = boto3.resource("ec2", region_name="us-west-1")
+ # Create VPC
+ vpc = ec2.create_vpc(
+ CidrBlock="10.0.0.0/16",
+ TagSpecifications=[
+ {"ResourceType": "vpc", "Tags": [{"Key": "name", "Value": "some-vpc"}]}
+ ],
+ )
+ assert vpc.tags == [{"Key": "name", "Value": "some-vpc"}]
+
+
@mock_ec2
def test_enable_vpc_classic_link():
ec2 = boto3.resource("ec2", region_name="us-west-1")