Path is an optional property of instance profile cloudformation resource (#1382)

* Path is an optional property of instance profile cloudformation resource

http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-instanceprofile.html

* Path is also optional for iam role clouformation resources

Based on http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html

* Use `properities.get` with a default instead of doing default handling myself
This commit is contained in:
William Richard 2017-12-14 07:06:04 -05:00 committed by Terry Cain
parent 2346e14e00
commit df7a7958c1
2 changed files with 69 additions and 29 deletions

View File

@ -122,7 +122,7 @@ class Role(BaseModel):
role = iam_backend.create_role(
role_name=resource_name,
assume_role_policy_document=properties['AssumeRolePolicyDocument'],
path=properties['Path'],
path=properties.get('Path', '/'),
)
policies = properties.get('Policies', [])
@ -173,7 +173,7 @@ class InstanceProfile(BaseModel):
role_ids = properties['Roles']
return iam_backend.create_instance_profile(
name=resource_name,
path=properties['Path'],
path=properties.get('Path', '/'),
role_ids=role_ids,
)

View File

@ -891,19 +891,25 @@ def test_iam_roles():
"my-launch-config": {
"Properties": {
"IamInstanceProfile": {"Ref": "my-instance-profile"},
"IamInstanceProfile": {"Ref": "my-instance-profile-with-path"},
"ImageId": "ami-1234abcd",
},
"Type": "AWS::AutoScaling::LaunchConfiguration"
},
"my-instance-profile": {
"my-instance-profile-with-path": {
"Properties": {
"Path": "my-path",
"Roles": [{"Ref": "my-role"}],
"Roles": [{"Ref": "my-role-with-path"}],
},
"Type": "AWS::IAM::InstanceProfile"
},
"my-role": {
"my-instance-profile-no-path": {
"Properties": {
"Roles": [{"Ref": "my-role-no-path"}],
},
"Type": "AWS::IAM::InstanceProfile"
},
"my-role-with-path": {
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
@ -961,6 +967,26 @@ def test_iam_roles():
]
},
"Type": "AWS::IAM::Role"
},
"my-role-no-path": {
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Principal": {
"Service": [
"ec2.amazonaws.com"
]
}
}
]
},
},
"Type": "AWS::IAM::Role"
}
}
}
@ -974,37 +1000,51 @@ def test_iam_roles():
iam_conn = boto.iam.connect_to_region("us-west-1")
role_result = iam_conn.list_roles()['list_roles_response'][
'list_roles_result']['roles'][0]
role = iam_conn.get_role(role_result.role_name)
role.role_name.should.contain("my-role")
role.path.should.equal("my-path")
role_results = iam_conn.list_roles()['list_roles_response'][
'list_roles_result']['roles']
role_name_to_id = {}
for role_result in role_results:
role = iam_conn.get_role(role_result.role_name)
role.role_name.should.contain("my-role")
if 'with-path' in role.role_name:
role_name_to_id['with-path'] = role.role_id
role.path.should.equal("my-path")
else:
role_name_to_id['no-path'] = role.role_id
role.role_name.should.contain('no-path')
role.path.should.equal('/')
instance_profile_response = iam_conn.list_instance_profiles()[
'list_instance_profiles_response']
cfn_instance_profile = instance_profile_response[
'list_instance_profiles_result']['instance_profiles'][0]
instance_profile = iam_conn.get_instance_profile(
cfn_instance_profile.instance_profile_name)
instance_profile.instance_profile_name.should.contain(
"my-instance-profile")
instance_profile.path.should.equal("my-path")
instance_profile.role_id.should.equal(role.role_id)
instance_profile_responses = iam_conn.list_instance_profiles()[
'list_instance_profiles_response']['list_instance_profiles_result']['instance_profiles']
instance_profile_responses.should.have.length_of(2)
instance_profile_names = []
for instance_profile_response in instance_profile_responses:
instance_profile = iam_conn.get_instance_profile(instance_profile_response.instance_profile_name)
instance_profile_names.append(instance_profile.instance_profile_name)
instance_profile.instance_profile_name.should.contain(
"my-instance-profile")
if "with-path" in instance_profile.instance_profile_name:
instance_profile.path.should.equal("my-path")
instance_profile.role_id.should.equal(role_name_to_id['with-path'])
else:
instance_profile.instance_profile_name.should.contain('no-path')
instance_profile.role_id.should.equal(role_name_to_id['no-path'])
instance_profile.path.should.equal('/')
autoscale_conn = boto.ec2.autoscale.connect_to_region("us-west-1")
launch_config = autoscale_conn.get_all_launch_configurations()[0]
launch_config.instance_profile_name.should.contain("my-instance-profile")
launch_config.instance_profile_name.should.contain("my-instance-profile-with-path")
stack = conn.describe_stacks()[0]
resources = stack.describe_resources()
instance_profile_resource = [
resource for resource in resources if resource.resource_type == 'AWS::IAM::InstanceProfile'][0]
instance_profile_resource.physical_resource_id.should.equal(
instance_profile.instance_profile_name)
instance_profile_resources = [
resource for resource in resources if resource.resource_type == 'AWS::IAM::InstanceProfile']
{ip.physical_resource_id for ip in instance_profile_resources}.should.equal(set(instance_profile_names))
role_resource = [
resource for resource in resources if resource.resource_type == 'AWS::IAM::Role'][0]
role_resource.physical_resource_id.should.equal(role.role_id)
role_resources = [
resource for resource in resources if resource.resource_type == 'AWS::IAM::Role']
{r.physical_resource_id for r in role_resources}.should.equal(set(role_name_to_id.values()))
@mock_ec2_deprecated()