Skip to content

Commit

Permalink
Add support for creating an IAM role
Browse files Browse the repository at this point in the history
This adds `stacker_blueprints.iam_roles.IAMRole`, which creates an IAM
Role, accepting a list of principals allowed to assume the role, and
attached policies. It's expected that this would be used with an
existing user and policy.
  • Loading branch information
aengelas committed Aug 5, 2020
1 parent 7013151 commit 7bbb415
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 1 deletion.
73 changes: 72 additions & 1 deletion stacker_blueprints/iam_roles.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
iam,
)

from awacs.aws import Policy
from awacs.aws import Policy, Statement, Principal
from awacs import sts
from awacs.helpers.trust import (
get_default_assumerole_policy,
get_lambda_assumerole_policy
Expand Down Expand Up @@ -227,3 +228,73 @@ def create_template(self):
self.create_lambda_role(role)

self.create_policy()


class IAMRole(Blueprint):
"""
Blueprint to create an IAM role.
- class_path: stacker_blueprints.iam_roles.IAMRole
name: my-role
variables:
Name: myRole
Path: /
AttachedPolicies:
- arn:aws:iam::aws:policy/CloudWatchLogsFullAccess
AssumeRole:
- arn:aws:iam::123456789012:user/JohnDoe
"""
VARIABLES = {
"Name": {
"type": str,
"description": "The name of the role",
"default": "Role",
},
"Path": {
"type": str,
"description": "Provide the path",
"default": "/",
},
"AttachedPolicies": {
"type": list,
"description": "List of ARNs of policies to attach",
"default": [],
},
"AssumeRole": {
"type": list,
"description": "List of ARNs of entities allowed to assume this role",
"default": [],
},
}

def create_template(self):
variables = self.get_variables()

ar_policy = Policy(
Statement=[
Statement(
Effect='Allow',
Principal=Principal("AWS", p),
Action=[
sts.AssumeRole,
],
) for p in variables['AssumeRole']
]
)

role = self.template.add_resource(
iam.Role(
variables['Name'],
Path=variables['Path'],
ManagedPolicyArns=variables['AttachedPolicies'],
AssumeRolePolicyDocument=ar_policy,
)
)

self.template.add_output(
Output("RoleName", Value=Ref(role))
)

self.template.add_output(
Output("RoleArn", Value=GetAtt(role.title, "Arn"))
)
41 changes: 41 additions & 0 deletions tests/fixtures/blueprints/test_iam_roles_iam_role.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"Outputs": {
"RoleArn": {
"Value": {
"Fn::GetAtt": [
"Role",
"Arn"
]
}
},
"RoleName": {
"Value": {
"Ref": "Role"
}
}
},
"Resources": {
"Role": {
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:user/JohnDoe"
}
}
]
},
"ManagedPolicyArns": [
"arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"
],
"Path": "/"
},
"Type": "AWS::IAM::Role"
}
}
}
41 changes: 41 additions & 0 deletions tests/fixtures/blueprints/test_iam_roles_iam_role_name.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"Outputs": {
"RoleArn": {
"Value": {
"Fn::GetAtt": [
"myRole",
"Arn"
]
}
},
"RoleName": {
"Value": {
"Ref": "myRole"
}
}
},
"Resources": {
"myRole": {
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:user/JohnDoe"
}
}
]
},
"ManagedPolicyArns": [
"arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"
],
"Path": "/"
},
"Type": "AWS::IAM::Role"
}
}
}
34 changes: 34 additions & 0 deletions tests/test_iam_roles.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,37 @@ def test_role_name(self):
blueprint.resolve_variables(self.generate_variables())
blueprint.create_template()
self.assertRenderedBlueprint(blueprint)


class TestIamRoleBlueprint(TestIamRolesCommon):

def test_role(self):
self.common_variables = {
'Path': '/',
'AttachedPolicies': [
'arn:aws:iam::aws:policy/CloudWatchLogsFullAccess',
],
'AssumeRole': [
'arn:aws:iam::123456789012:user/JohnDoe',
],
}
blueprint = self.create_blueprint('test_iam_roles_iam_role', class_name=iam_roles.IAMRole)
blueprint.resolve_variables(self.generate_variables())
blueprint.create_template()
self.assertRenderedBlueprint(blueprint)

def test_role_name(self):
self.common_variables = {
'Name': 'myRole',
'Path': '/',
'AttachedPolicies': [
'arn:aws:iam::aws:policy/CloudWatchLogsFullAccess',
],
'AssumeRole': [
'arn:aws:iam::123456789012:user/JohnDoe',
],
}
blueprint = self.create_blueprint('test_iam_roles_iam_role_name', class_name=iam_roles.IAMRole)
blueprint.resolve_variables(self.generate_variables())
blueprint.create_template()
self.assertRenderedBlueprint(blueprint)

0 comments on commit 7bbb415

Please sign in to comment.