diff --git a/moto/iam/models.py b/moto/iam/models.py index 7839d3a74..57d24826d 100644 --- a/moto/iam/models.py +++ b/moto/iam/models.py @@ -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, ) diff --git a/tests/test_cloudformation/test_cloudformation_stack_integration.py b/tests/test_cloudformation/test_cloudformation_stack_integration.py index c4a138de7..051d8bed7 100644 --- a/tests/test_cloudformation/test_cloudformation_stack_integration.py +++ b/tests/test_cloudformation/test_cloudformation_stack_integration.py @@ -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()