EC2: link IAM instance profile with instance (#5617)

This commit is contained in:
rafcio19 2022-10-29 23:06:21 +01:00 committed by GitHub
parent 9b316c6d60
commit 1aabd3fd95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 70 additions and 1 deletions

View File

@ -17,6 +17,11 @@ class IamInstanceProfileAssociation(CloudFormationModel):
self.instance = instance
self.iam_instance_profile = iam_instance_profile
self.state = "associated"
ec2_backend.modify_instance_attribute(
instance.id,
"iam_instance_profile",
{"Arn": self.iam_instance_profile.arn, "Id": association_id},
)
class IamInstanceProfileAssociationBackend:

View File

@ -140,6 +140,7 @@ class Instance(TaggedEC2Resource, BotoInstance, CloudFormationModel):
self.architecture = ami.architecture if ami else "x86_64"
self.root_device_name = ami.root_device_name if ami else None
self.disable_api_stop = False
self.iam_instance_profile = kwargs.get("iam_instance_profile")
# handle weird bug around user_data -- something grabs the repr(), so
# it must be clean

View File

@ -73,6 +73,10 @@ class InstanceResponse(EC2BaseResponse):
),
"launch_template": self._get_multi_param_dict("LaunchTemplate"),
"hibernation_options": self._get_multi_param_dict("HibernationOptions"),
"iam_instance_profile_name": self._get_param("IamInstanceProfile.Name")
or None,
"iam_instance_profile_arn": self._get_param("IamInstanceProfile.Arn")
or None,
}
if len(kwargs["nics"]) and kwargs["subnet_id"]:
raise InvalidParameterCombination(
@ -87,6 +91,16 @@ class InstanceResponse(EC2BaseResponse):
new_reservation = self.ec2_backend.add_instances(
image_id, min_count, user_data, security_group_names, **kwargs
)
if kwargs.get("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"),
)
if kwargs.get("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"),
)
template = self.response_template(EC2_RUN_INSTANCES)
return template.render(
@ -422,6 +436,12 @@ EC2_RUN_INSTANCES = """<RunInstancesResponse xmlns="http://ec2.amazonaws.com/doc
<ebsOptimized>{{ instance.ebs_optimized }}</ebsOptimized>
<amiLaunchIndex>{{ instance.ami_launch_index }}</amiLaunchIndex>
<instanceType>{{ instance.instance_type }}</instanceType>
{% if instance.iam_instance_profile %}
<iamInstanceProfile>
<arn>{{ instance.iam_instance_profile['Arn'] }}</arn>
<id>{{ instance.iam_instance_profile['Id'] }}</id>
</iamInstanceProfile>
{% endif %}
<launchTime>{{ instance.launch_time }}</launchTime>
{% if instance.lifecycle %}
<instanceLifecycle>{{ instance.lifecycle }}</instanceLifecycle>
@ -573,6 +593,12 @@ EC2_DESCRIBE_INSTANCES = """<DescribeInstancesResponse xmlns="http://ec2.amazona
<amiLaunchIndex>{{ instance.ami_launch_index }}</amiLaunchIndex>
<productCodes/>
<instanceType>{{ instance.instance_type }}</instanceType>
{% if instance.iam_instance_profile %}
<iamInstanceProfile>
<arn>{{ instance.iam_instance_profile['Arn'] }}</arn>
<id>{{ instance.iam_instance_profile['Id'] }}</id>
</iamInstanceProfile>
{% endif %}
<launchTime>{{ instance.launch_time }}</launchTime>
{% if instance.lifecycle %}
<instanceLifecycle>{{ instance.lifecycle }}</instanceLifecycle>

View File

@ -9,7 +9,7 @@ import pytest
import sure # noqa # pylint: disable=unused-import
from botocore.exceptions import ClientError, ParamValidationError
from freezegun import freeze_time
from moto import mock_ec2, settings
from moto import mock_ec2, mock_iam, settings
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
from tests import EXAMPLE_AMI_ID
@ -2516,6 +2516,43 @@ def test_describe_instances_filter_vpcid_via_networkinterface():
found.should.equal([instance])
@mock_ec2
@mock_iam
def test_instance_iam_instance_profile():
ec2_resource = boto3.resource("ec2", "us-west-1")
iam = boto3.client("iam", "us-west-1")
profile_name = "fake_profile"
profile = iam.create_instance_profile(
InstanceProfileName=profile_name,
)
result1 = ec2_resource.create_instances(
ImageId="ami-d3adb33f",
MinCount=1,
MaxCount=1,
IamInstanceProfile={
"Name": profile_name,
},
)
instance = result1[0]
assert "Arn" in instance.iam_instance_profile
assert "Id" in instance.iam_instance_profile
assert profile["InstanceProfile"]["Arn"] == instance.iam_instance_profile["Arn"]
result2 = ec2_resource.create_instances(
ImageId="ami-d3adb33f",
MinCount=1,
MaxCount=1,
IamInstanceProfile={
"Arn": profile["InstanceProfile"]["Arn"],
},
)
instance = result2[0]
assert "Arn" in instance.iam_instance_profile
assert "Id" in instance.iam_instance_profile
assert profile["InstanceProfile"]["Arn"] == instance.iam_instance_profile["Arn"]
def retrieve_all_reservations(client, filters=[]): # pylint: disable=W0102
resp = client.describe_instances(Filters=filters)
all_reservations = resp["Reservations"]