EC2: link IAM instance profile with instance (#5617)
This commit is contained in:
parent
9b316c6d60
commit
1aabd3fd95
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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"]
|
||||
|
Loading…
Reference in New Issue
Block a user