From de714eb4cc2ebf4065eba8cc886c4eb6649b061b Mon Sep 17 00:00:00 2001 From: Bert Blommers Date: Thu, 12 Oct 2023 21:25:56 +0000 Subject: [PATCH] EC2: Validate instance profile before creating Instances (#6905) --- moto/ec2/responses/instances.py | 20 ++++++++++++++++---- tests/test_ec2/test_instances.py | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/moto/ec2/responses/instances.py b/moto/ec2/responses/instances.py index c3bbf45ee700..30785bf1cd0f 100644 --- a/moto/ec2/responses/instances.py +++ b/moto/ec2/responses/instances.py @@ -5,6 +5,7 @@ InvalidParameterCombination, InvalidRequest, ) +from moto.ec2.utils import filter_iam_instance_profiles from copy import deepcopy @@ -98,20 +99,31 @@ def run_instances(self) -> str: if mappings: kwargs["block_device_mappings"] = mappings + iam_instance_profile_name = kwargs.get("iam_instance_profile_name") + iam_instance_profile_arn = kwargs.get("iam_instance_profile_arn") + if iam_instance_profile_arn or iam_instance_profile_name: + # Validate the profile exists, before we error_on_dryrun and add_instances + filter_iam_instance_profiles( + self.current_account, + iam_instance_profile_arn=iam_instance_profile_arn, + iam_instance_profile_name=iam_instance_profile_name, + ) + self.error_on_dryrun() new_reservation = self.ec2_backend.add_instances( image_id, min_count, user_data, security_group_names, **kwargs ) - if kwargs.get("iam_instance_profile_name"): + if iam_instance_profile_name: self.ec2_backend.associate_iam_instance_profile( instance_id=new_reservation.instances[0].id, - iam_instance_profile_name=kwargs.get("iam_instance_profile_name"), + iam_instance_profile_name=iam_instance_profile_name, ) - if kwargs.get("iam_instance_profile_arn"): + + if iam_instance_profile_arn: self.ec2_backend.associate_iam_instance_profile( instance_id=new_reservation.instances[0].id, - iam_instance_profile_arn=kwargs.get("iam_instance_profile_arn"), + iam_instance_profile_arn=iam_instance_profile_arn, ) template = self.response_template(EC2_RUN_INSTANCES) diff --git a/tests/test_ec2/test_instances.py b/tests/test_ec2/test_instances.py index 7122f75d7dd3..d57fcfef52b8 100644 --- a/tests/test_ec2/test_instances.py +++ b/tests/test_ec2/test_instances.py @@ -2616,6 +2616,25 @@ def test_instance_iam_instance_profile(): assert "Id" in instance.iam_instance_profile assert profile["InstanceProfile"]["Arn"] == instance.iam_instance_profile["Arn"] + tag_key = str(uuid4())[0:6] + with pytest.raises(ClientError) as exc: + ec2_resource.create_instances( + ImageId=EXAMPLE_AMI_ID, + MinCount=1, + MaxCount=1, + IamInstanceProfile={"Arn": "unknown:instance:profile"}, + TagSpecifications=[ + {"ResourceType": "instance", "Tags": [{"Key": tag_key, "Value": "val"}]} + ], + ) + err = exc.value.response["Error"] + assert err["Code"] == "NoSuchEntity" + assert err["Message"] == "Instance profile unknown:instance:profile not found" + + ec2_client = boto3.client("ec2", "us-west-1") + filters = [{"Name": "tag-key", "Values": [tag_key]}] + assert retrieve_all_instances(ec2_client, filters) == [] + def retrieve_all_reservations(client, filters=[]): # pylint: disable=W0102 resp = client.describe_instances(Filters=filters)