def _bind_role(self, t, r): brefs = [] for b in self.buckets: bn = b.output_bucket_name() if bn in t.parameters: brefs.append(t.parameters[bn]) else: brefs.append(t.add_parameter(Parameter(bn, Type="String"))) r.Policies.append( iam.Policy( "s3fullaccess", PolicyName="s3fullaccess", PolicyDocument=aws.Policy(Statement=[ aws.Statement( Action=[awacs.aws.Action("s3", "*")], Effect=aws.Allow, Resource=[ Join("", ["arn:aws:s3:::", Ref(i)]) for i in brefs ]), aws.Statement(Action=[awacs.aws.Action("s3", "*")], Effect=aws.Allow, Resource=[ Join("", ["arn:aws:s3:::", Ref(i), "/*"]) for i in brefs ]), ])))
def _project_key(project: Config) -> kms.Key: """Construct the AWS CMK that will be used to protect project resources. :param project: Source project :return: Constructed key """ policy = AWS.PolicyDocument( Version="2012-10-17", Statement=[ AWS.Statement( Effect=AWS.Allow, Principal=AWS.Principal("AWS", account_arn("iam", "root")), Action=[ KMS.Encrypt, KMS.Decrypt, KMS.ReEncrypt, KMS.GenerateDataKey, KMS.GenerateDataKeyWithoutPlaintext, KMS.DescribeKey, KMS.GetKeyPolicy, ], Resource=["*"], ), # TODO: Change admin statement to some other principal? AWS.Statement( Effect=AWS.Allow, Principal=AWS.Principal("AWS", account_arn("iam", "root")), Action=[ KMS.GetKeyPolicy, KMS.PutKeyPolicy, KMS.ScheduleKeyDeletion, KMS.CancelKeyDeletion, KMS.CreateAlias, KMS.DeleteAlias, KMS.UpdateAlias, KMS.DescribeKey, KMS.EnableKey, KMS.DisableKey, KMS.GetKeyRotationStatus, KMS.EnableKeyRotation, KMS.DisableKeyRotation, KMS.ListKeyPolicies, KMS.ListResourceTags, KMS.TagResource, KMS.UntagResource, ], Resource=["*"], ), ], ) return kms.Key( resource_name(kms.Key, "Stack"), Enabled=True, EnableKeyRotation=False, KeyPolicy=policy, Tags=project_tags(project), )
def generate_role_template( command: str, actions: list, role_name: str, path: str, assuming_account_id: str, assuming_resource: str, output_format: str, ) -> str: t = troposphere.Template() t.description = f"Role used to run the {command} command" t.add_resource( iam.Role( title="role", RoleName=role_name, Path=path, Policies=[ iam.Policy( PolicyName=f"{command}-permissions", PolicyDocument=aws.PolicyDocument( Version="2012-10-17", Id=f"{command}-permissions", Statement=[ aws.Statement( Sid="1", Effect=aws.Allow, Action=actions, Resource=["*"], ), ], ), ) ], AssumeRolePolicyDocument=aws.Policy( Version="2012-10-17", Id="AllowAssume", Statement=[ aws.Statement( Sid="1", Effect=aws.Allow, Principal=aws.Principal("AWS", [ IAM_ARN(assuming_resource, "", assuming_account_id) ]), Action=[awacs_sts.AssumeRole], ), ], ), )) if output_format == "json": return t.to_json() else: return t.to_yaml()
def __init__(self, parameters): super(StackSetRole, self).__init__() self.AdministrationRole = iam.Role( "AdministrationRole", RoleName="AWSCloudFormationStackSetAdministrationRole", Path="/", AssumeRolePolicyDocument=aws.Policy( Version="2012-10-17", Statement=[ aws.Statement( Action=[aws.Action("sts", "AssumeRole")], Effect=aws.Allow, Principal=aws.Principal( "Service", "cloudformation.amazonaws.com" ) ) ], ), Policies=[ iam.Policy( PolicyName="AssumeRole-AWSCloudFormationStackSetExecutionRole", PolicyDocument=aws.Policy( Version="2012-10-17", Statement=[ aws.Statement( Action=[aws.Action("sts", "AssumeRole")], Effect=aws.Allow, Resource=["arn:aws:iam::*:role/AWSCloudFormationStackSetExecutionRole"], ) ] ), ) ] ) self.ExecutionRole = iam.Role( "ExecutionRole", RoleName="AWSCloudFormationStackSetExecutionRole", Path="/", ManagedPolicyArns=["arn:aws:iam::aws:policy/AdministratorAccess"], AssumeRolePolicyDocument=aws.Policy( Version="2012-10-17", Statement=[ aws.Statement( Action=[aws.Action("sts", "AssumeRole")], Effect=aws.Allow, Principal=aws.Principal( "AWS", Ref(parameters.AdministratorAccountId) ) ) ] ) )
def generate_role_template( command: str, actions: list, role_name: str, path: str, assuming_account_id: str, assuming_resource: str, additional_statements: list = [], ) -> troposphere.Template: t = troposphere.Template() t.description = f"Role used to run the {command} command" role = iam.Role( title="role", RoleName=role_name, Path=path, Policies=[ iam.Policy( PolicyName=f"{command}-permissions", PolicyDocument=aws.PolicyDocument( Version="2012-10-17", Id=f"{command}-permissions", Statement=[ aws.Statement(Sid="1", Effect=aws.Allow, Action=actions, Resource=["*"]) ] + additional_statements, ), ) ], AssumeRolePolicyDocument=aws.Policy( Version="2012-10-17", Id="AllowAssume", Statement=[ aws.Statement( Sid="1", Effect=aws.Allow, Principal=aws.Principal( "AWS", [IAM_ARN(assuming_resource, "", assuming_account_id)]), Action=[awacs_sts.AssumeRole], ) ], ), ) t.add_resource(role) t.add_output(troposphere.Output("RoleName", Value=troposphere.Ref(role))) t.add_output( troposphere.Output("RoleArn", Value=troposphere.GetAtt(role, "Arn"))) return t
def _bind_role(self, t, r): r.Policies.append( iam.Policy( 'codedeploy', PolicyName='codedeploy', PolicyDocument=aws.Policy(Statement=[ aws.Statement( Effect=aws.Allow, Resource=['*'], Action=[ aws.Action('autoscaling', '*'), aws.Action('elasticloadbalancing', 'DescribeLoadBalancers'), # noqa aws.Action('elasticloadbalancing', 'DescribeInstanceHealth'), # noqa aws.Action('elasticloadbalancing', 'RegisterInstancesWithLoadBalancer'), aws.Action('elasticloadbalancing', 'DeregisterInstancesFromLoadBalancer'), aws.Action('ec2', 'Describe*'), aws.Action('ec2', 'TerminateInstances'), aws.Action('tag', 'GetTags'), aws.Action('tag', 'GetResources'), aws.Action('tag', 'GetTagsForResource'), aws.Action('tag', 'GetTagsForResourceList'), aws.Action('lambda', '*') ]), ])))
def test_for_all_values(self): c = aws.Condition( aws.ForAllValuesStringLike("dynamodb:requestedAttributes", ["PostDateTime", "Message", "Tags"])) pd = aws.PolicyDocument(Statement=[ aws.Statement( Action=[s3.ListBucket], Effect=aws.Allow, Resource=[s3.ARN("myBucket")], Condition=c, ) ]) self.assertEqual( { "Statement": [{ "Action": ["s3:ListBucket"], "Condition": { "ForAllValues:StringLike": { "dynamodb:requestedAttributes": [ "PostDateTime", "Message", "Tags", ] } }, "Effect": "Allow", "Resource": ["arn:aws:s3:::myBucket"], }] }, json.loads(pd.to_json()), )
def test_for_all_values(self): c = aws.Condition( aws.ForAllValuesStringLike("dynamodb:requestedAttributes", ["PostDateTime", "Message", "Tags"])) pd = aws.Policy(Statement=[ aws.Statement( Action=[s3.ListBucket], Effect=aws.Allow, Resource=[s3.ARN("myBucket")], Condition=c, ) ]) self.assertEqual( { u'Statement': [{ u'Action': [u's3:ListBucket'], u'Condition': { u'ForAllValues:StringLike': { u'dynamodb:requestedAttributes': [u'PostDateTime', u'Message', u'Tags'] } }, u'Effect': u'Allow', u'Resource': [u'arn:aws:s3:::myBucket'] }] }, json.loads(pd.to_json()))
def _build_template(self, template): t = template if self.principals == "*": principal_title = "*" else: principal_title = "Service" role = t.add_resource( iam.Role(self.name, AssumeRolePolicyDocument=aws.Policy(Statement=[ aws.Statement(Action=[awacs.sts.AssumeRole], Effect=aws.Allow, Principal=aws.Principal( principal_title, self.principals)) ]), Path="/", Policies=[], ManagedPolicyArns=[])) for p in self.policies: p._bind_role(t, role) for m in self.managed_policies: role.ManagedPolicyArns.append(m) t.add_output([ Output('{}Role'.format(self.name), Value=Ref(role)), Output('{}RoleArn'.format(self.name), Value=GetAtt(role, "Arn")) ]) return t
def build_subscription(self, t, topic): policy = t.add_resource( iam.Role( "{}SlackSNSRole".format(self.name), AssumeRolePolicyDocument=aws.Policy(Statement=[ aws.Statement(Action=[awacs.sts.AssumeRole], Effect=aws.Allow, Principal=aws.Principal( "Service", ["lambda.amazonaws.com"])) ]), Path="/", Policies=[ iam.Policy( PolicyName='snspublic', PolicyDocument=aws.PolicyDocument(Statement=[ aws.Statement(Effect=aws.Allow, Action=[ awacs.sns.Publish, awacs.logs.PutLogEvents, awacs.logs.CreateLogGroup, awacs.logs.CreateLogStream, ], Resource=["*"]) ])) ], ManagedPolicyArns=[ # "arn:aws:iam::aws:policy/AdministratorAccess" ])) code = ["import sys"] # make lambda function fn = t.add_resource( awslambda.Function('{}SlackTopicFN'.format(self.name), Handler='index.handle', Runtime='python3.6', Role=GetAtt(policy, "Arn"), Code=awslambda.Code(ZipFile=Join("", code)))) t.add_resource( awslambda.Permission('{}LambdaPerm'.format(self.name), Action='lambda:InvokeFunction', FunctionName=GetAtt(fn, "Arn"), SourceArn=Ref(topic), Principal="sns.amazonaws.com")) return ("lambda", GetAtt(fn, "Arn"))
def _codebuild_role(artifacts_bucket: Parameter, resources_bucket: Parameter, cmk: Parameter) -> iam.Role: """Construct a role for use by CodeBuild. :param artifacts_bucket: Artifacts bucket parameter :param resources_bucket: Resources bucket parameter :param cmk: KMS CMK parameter :return: Constructed Role """ assume_policy = AWS.PolicyDocument(Statement=[ AWS.Statement( Principal=AWS.Principal( "Service", make_service_domain_name(CODEBUILD.prefix)), Effect=AWS.Allow, Action=[STS.AssumeRole], ) ]) policy = AWS.PolicyDocument(Statement=[ AWS.Statement( Effect=AWS.Allow, Action=[ LOGS.CreateLogGroup, LOGS.CreateLogStream, LOGS.PutLogEvents ], Resource=[account_arn(service_prefix=LOGS.prefix, resource="*")], ), AWS.Statement( Effect=AWS.Allow, Action=[S3.GetObject, S3.GetObjectVersion, S3.PutObject], Resource=[ Sub(f"${{{artifacts_bucket.title}}}/*"), Sub(f"${{{resources_bucket.title}}}/*") ], ), AWS.Statement(Effect=AWS.Allow, Action=[KMS.Encrypt, KMS.Decrypt, KMS.GenerateDataKey], Resource=[cmk.ref()]), ]) return iam.Role( resource_name(iam.Role, "CodeBuild"), AssumeRolePolicyDocument=assume_policy, Policies=[ iam.Policy(PolicyName=_policy_name("CodeBuild"), PolicyDocument=policy) ], )
def _assume_policy(service: str) -> AWS.PolicyDocument: return AWS.PolicyDocument(Statement=[ AWS.Statement( Principal=AWS.Principal("Service", make_service_domain_name( service)), Effect=AWS.Allow, Action=[STS.AssumeRole], ) ])
def _bind_role(self, t, r): r.Policies.append( iam.Policy('sqsall', PolicyName='sqsall', PolicyDocument=aws.Policy(Statement=[ aws.Statement(Action=[awacs.aws.Action("sqs", "*")], Effect=aws.Allow, Resource=["*"]) ])))
def _basic_lambda_statement() -> AWS.Statement: return AWS.Statement( Effect=AWS.Allow, Action=[LOGS.CreateLogGroup, LOGS.CreateLogStream, LOGS.PutLogEvents], Resource=[ Sub(f"arn:${{{AWS_PARTITION}}}:logs:${{{AWS_REGION}}}:${{{AWS_ACCOUNT_ID}}}:*" ) ], )
def _pipeline_role(buckets: Iterable[s3.Bucket]) -> iam.Role: """Build and return the IAM Role resource to be used by CodePipeline to run the pipeline.""" bucket_statements = [ AWS.Statement( Effect=AWS.Allow, Action=[S3.GetBucketVersioning, S3.PutBucketVersioning], Resource=[GetAtt(bucket, "Arn") for bucket in buckets], ), AWS.Statement( Effect=AWS.Allow, Action=[S3.GetObject, S3.PutObject], Resource=[ Sub("${{{bucket}.Arn}}/*".format(bucket=bucket.title)) for bucket in buckets ], ), ] policy = iam.Policy( "PipelinePolicy", PolicyName="PipelinePolicy", PolicyDocument=AWS.PolicyDocument(Statement=bucket_statements + [ AllowEverywhere(Action=[CLOUDWATCH.Action("*"), IAM.PassRole]), AllowEverywhere( Action=[LAMBDA.InvokeFunction, LAMBDA.ListFunctions]), AllowEverywhere(Action=[ CLOUDFORMATION.CreateStack, CLOUDFORMATION.DeleteStack, CLOUDFORMATION.DescribeStacks, CLOUDFORMATION.UpdateStack, CLOUDFORMATION.CreateChangeSet, CLOUDFORMATION.DeleteChangeSet, CLOUDFORMATION.DescribeChangeSet, CLOUDFORMATION.ExecuteChangeSet, CLOUDFORMATION.SetStackPolicy, CLOUDFORMATION.ValidateTemplate, ]), AllowEverywhere( Action=[CODEBUILD.BatchGetBuilds, CODEBUILD.StartBuild]), ]), ) return iam.Role("CodePipelinesRole", AssumeRolePolicyDocument=_service_assume_role( CODEPIPELINE.prefix), Policies=[policy])
def _cloudformation_role() -> iam.Role: """Construct a role for use by CloudFormation. :return: Constructed Role """ assume_policy = AWS.PolicyDocument(Statement=[ AWS.Statement( Principal=AWS.Principal( "Service", make_service_domain_name(CLOUDFORMATION.prefix)), Effect=AWS.Allow, Action=[STS.AssumeRole], ) ]) # TODO: Figure out how to scope this down without breaking IAM # IAM policies break if there is a * in certain fields, # so this does not work: # arn:PARTITION:*:REGION:ACCOUNT:* # # _desired_policy = AWS.PolicyDocument( # Statement=[ # AWS.Statement( # Effect=AWS.Allow, # Action=[AWS.Action("*")], # Resource=[ # account_arn(service_prefix="*", resource="*"), # account_arn(service_prefix=S3.prefix, resource="*"), # account_arn(service_prefix=IAM.prefix, resource="*"), # ], # ) # ] # ) policy = AWS.PolicyDocument(Statement=[ AWS.Statement( Effect=AWS.Allow, Action=[AWS.Action("*")], Resource=["*"]) ]) return iam.Role( resource_name(iam.Role, "CloudFormation"), AssumeRolePolicyDocument=assume_policy, Policies=[ iam.Policy(PolicyName=_policy_name("CloudFormation"), PolicyDocument=policy) ], )
def _bind_role(self, template, role): role.Policies.append( iam.Policy('ec2fullaccess', PolicyName='ec2fullaccess', PolicyDocument=aws.Policy(Statement=[ aws.Statement(Action=[awacs.aws.Action("ec2", "*")], Effect=aws.Allow, Resource=["*"]) ])))
def _service_assume_role(service: str) -> AWS.Policy: """Build and return the IAM AssumeRolePolicy for use in service roles.""" return AWS.Policy(Statement=[ AWS.Statement( Effect=AWS.Allow, Action=[STS.AssumeRole], Principal=AWS.Principal("Service", ["{}.amazonaws.com".format(service)]), ) ])
def _bind_role(self, t, r): brefs = [] for b in self.buckets: bn = b.output_bucket_name() if bn in t.parameters: brefs.append(t.parameter[bn]) else: brefs.append(t.add_parameter(Parameter(bn, Type='String'))) r.Policies.append( iam.Policy( 's3readaccess', PolicyName='s3readaccess', PolicyDocument=aws.Policy(Statement=[ aws.Statement( Effect=aws.Allow, Action=[ awacs.aws.Action('s3', 'GetObject*'), awacs.aws.Action('s3', 'ListAllMyBuckets'), awacs.aws.Action('s3', 'GetObject'), awacs.aws.Action('s3', 'ListBucket'), awacs.aws.Action('s3', 'ListBucketVersions'), ], Resource=[ Join("", ["arn:aws:s3:::", Ref(i), "/*"]) for i in brefs ]), aws.Statement( Effect=aws.Allow, Action=[ awacs.aws.Action('s3', 'GetObject*'), awacs.aws.Action('s3', 'ListAllMyBuckets'), awacs.aws.Action('s3', 'GetObject'), awacs.aws.Action('s3', 'ListBucket'), awacs.aws.Action('s3', 'ListBucketVersions'), ], Resource=[ Join("", ["arn:aws:s3:::", Ref(i), "*"]) for i in brefs ]) ])))
def _s3_object_statement(action: S3.Action, *prefixes: str) -> Iterable[AWS.Statement]: return [ AWS.Statement( Effect=AWS.Allow, Action=[action], Resource=[ Sub(f"arn:${{{AWS_PARTITION}}}:s3:::{pre}*") for pre in prefixes ], ) ]
def _bind_role(self, t, r): r.Policies.append( iam.Policy('cloudwatch', PolicyName='cloudwatch', PolicyDocument=aws.Policy(Statement=[ aws.Statement(Effect=aws.Allow, Resource=['*'], Action=[ aws.Action("logs", "*"), ]) ])))
def _bind_role(self, t, r): r.Policies.append( iam.Policy( 'DynamoScaleRolePolicy', PolicyName='DynamoScaleRolePolicy', PolicyDocument=aws.Policy(Statement=[ aws.Statement(Effect=aws.Allow, Action=[ aws.Action("dynamodb", "DescribeTable"), aws.Action("dynamodb", "UpdateTable"), ], Resource=["*"]), aws.Statement( Effect=aws.Allow, Action=[ aws.Action("cloudwatch", "PutMetricAlarm"), aws.Action("cloudwatch", "DescribeAlarms"), aws.Action("cloudwatch", "GetMetricStatistics"), aws.Action("cloudwatch", "SetAlarmState"), aws.Action("cloudwatch", "DeleteAlarms"), ], Resource=["*"]), ])))
def lambda_layer_permissions() -> Iterable[AWS.Statement]: return [ AWS.Statement( Effect=AWS.Allow, Action=[ AWSLAMBDA.PublishLayerVersion, AWSLAMBDA.AddLayerVersionPermission ], Resource=[ Sub(f"arn:${{{AWS_PARTITION}}}:lambda:${{{AWS_REGION}}}:${{{AWS_ACCOUNT_ID}}}:layer:*" ) ], ) ]
def events_trigger_stepfuntions_role( name: str, statemachine: stepfunctions.StateMachine) -> iam.Role: return iam.Role( name, AssumeRolePolicyDocument=_assume_policy(EVENTS.prefix), Policies=[ iam.Policy( PolicyName=f"{name}Policy", PolicyDocument=AWS.PolicyDocument(Statement=[ AWS.Statement(Effect=AWS.Allow, Action=[STATES.StartExecution], Resource=[statemachine.ref()]) ]), ) ], )
def allow(self, allowed): ''' Allow custom iam permissions to be added to policy Args: allowed (dict): Dict of "aws service" : "action" ''' actions = [] for service, action in allowed.items(): actions.append(aws.Action(service, action)) statement = aws.Statement(Effect=aws.Allow, Action=actions, Resource=['*']) self.add_statement(statement)
def generate_migrate_role_template( role_name: str, path: str, assuming_account_id: str, assuming_resource: str, ssm_parameter_prefix: str, ) -> troposphere.Template: return generate_role_template( "migrate", [ awacs_organizations.CreateOrganizationalUnit, awacs_organizations.UpdateOrganizationalUnit, awacs_organizations.MoveAccount, awacs_organizations.CreatePolicy, awacs_organizations.UpdatePolicy, awacs_organizations.AttachPolicy, awacs_organizations.ListPolicies, awacs_organizations.RegisterDelegatedAdministrator, awacs_organizations.DeregisterDelegatedAdministrator, ], role_name, path, assuming_account_id, assuming_resource, [ aws.Statement( Sid="2", Effect=aws.Allow, Action=[ awscs_ssm.GetParameter, awscs_ssm.PutParameter, awscs_ssm.AddTagsToResource, ], Resource=[ troposphere.Sub( awscs_ssm.ARN( resource= f"parameter{ssm_parameter_prefix}/migrations/*", account="${AWS::AccountId}", region="${AWS::Region}", )) ], ) ], )
def __init__(self, parameters, groups): """ :type parameters Parameters :type groups Groups """ super(RolesAndPolicies, self).__init__() self.EC2Baseline = iam.Role( "EC2Baseline", AssumeRolePolicyDocument=aws.Policy( Version="2012-10-17", Statement=[ aws.Statement(Action=[aws.Action("sts", "AssumeRole")], Effect=aws.Allow, Principal=aws.Principal( "Service", "ec2.amazonaws.com")) ], )) self.LambdaBasicExecution = iam.Role( "LambdaBasicExecution", AssumeRolePolicyDocument=aws.Policy( Version="2012-10-17", Statement=[ aws.Statement(Action=[aws.Action("sts", "AssumeRole")], Effect=aws.Allow, Principal=aws.Principal( "Service", "lambda.amazonaws.com")) ], ), ) self.ECSClusterServiceRole = iam.Role( "ECSClusterServiceRole", Policies=[ iam.Policy( PolicyName=Join("", [Ref(AWS_STACK_NAME), "-ecs-service"]), PolicyDocument=aws.Policy( Version="2012-10-17", Statement=[ aws.Statement( Action=[ aws.Action( "ec2", "AuthorizeSecurityGroupIngress"), aws.Action("ec2", "Describe*"), aws.Action( "elasticloadbalancing", "DeregisterInstancesFromLoadBalancer"), aws.Action("elasticloadbalancing", "Describe*"), aws.Action( "elasticloadbalancing", "RegisterInstancesWithLoadBalancer"), aws.Action("elasticloadbalancing", "DeregisterTargets"), aws.Action("elasticloadbalancing", "DescribeTargetGroups" ), # todo: remove aws.Action("elasticloadbalancing", "DescribeTargetHealth" ), # todo: remove aws.Action("elasticloadbalancing", "RegisterTargets"), ], Resource=["*"], Effect=aws.Allow) ])) ], AssumeRolePolicyDocument=aws.Policy( Version="2012-10-17", Statement=[ aws.Statement(Action=[aws.Action("sts", "AssumeRole")], Effect=aws.Allow, Principal=aws.Principal( "Service", "ecs.amazonaws.com")) ], )) self.ForceMFA = iam.ManagedPolicy( "ForceMFA", PolicyDocument=aws.Policy( Version="2012-10-17", Statement=[ aws.Statement(Sid="AllowAllUsersToListAccounts", Action=[ aws.Action("iam", "ListAccountAliases"), aws.Action("iam", "ListUsers"), aws.Action("iam", "GetAccountSummary"), ], Resource=["*"], Effect=aws.Allow), aws.Statement( Sid= "AllowIndividualUserToSeeAndManageOnlyTheirOwnAccountInformation", Action=[ aws.Action("iam", "ChangePassword"), aws.Action("iam", "CreateAccessKey"), aws.Action("iam", "CreateLoginProfile"), aws.Action("iam", "DeleteAccessKey"), aws.Action("iam", "DeleteLoginProfile"), aws.Action("iam", "GetAccountPasswordPolicy"), aws.Action("iam", "GetLoginProfile"), aws.Action("iam", "ListAccessKeys"), aws.Action("iam", "UpdateAccessKey"), aws.Action("iam", "UpdateLoginProfile"), aws.Action("iam", "ListSigningCertificates"), aws.Action("iam", "DeleteSigningCertificate"), aws.Action("iam", "UpdateSigningCertificate"), aws.Action("iam", "UploadSigningCertificate"), aws.Action("iam", "ListSSHPublicKeys"), aws.Action("iam", "GetSSHPublicKey"), aws.Action("iam", "DeleteSSHPublicKey"), aws.Action("iam", "UpdateSSHPublicKey"), aws.Action("iam", "UploadSSHPublicKey"), ], Resource=[ Join("", [ "arn:aws:iam::", AccountId, ":user/${aws:username}" ]) ], Effect=aws.Allow), aws.Statement( Sid="AllowIndividualUserToListOnlyTheirOwnMFA", Action=[ aws.Action("iam", "ListVirtualMFADevices"), aws.Action("iam", "ListMFADevices"), ], Resource=[ Join("", ["arn:aws:iam::", AccountId, ":mfa/*"]), Join("", [ "arn:aws:iam::", AccountId, ":user/${aws:username}" ]) ], Effect=aws.Allow), aws.Statement( Sid= "AllowIndividualUserToDeactivateOnlyTheirOwnMFAOnlyWhenUsingMFA", Action=[ aws.Action("iam", "DeactivateMFADevice"), ], Condition=aws.Condition( aws.Bool("aws:MultiFactorAuthPresent", True)), Resource=[ Join("", [ "arn:aws:iam::", AccountId, ":mfa/${aws:username}" ]), Join("", [ "arn:aws:iam::", AccountId, ":user/${aws:username}" ]) ], Effect=aws.Allow), aws.Statement( Sid="BlockAnyAccessOtherThanAboveUnlessSignedInWithMFA", Condition=aws.Condition( aws.BoolIfExists("aws:MultiFactorAuthPresent", False)), NotAction=[ aws.Action("iam", "*"), ], Resource=["*"], Effect=aws.Deny), ], ), Description="Forces MFA usage on all users in assigned groups", Groups=[ Ref(groups.AWSEngineers.title), Ref(groups.ReadOnlyUsers.title), ], ) self.FullAdministrator = iam.ManagedPolicy( "FullAdministrator", PolicyDocument=aws.Policy(Version="2012-10-17", Statement=[ aws.Statement( Action=[aws.Action("*")], Resource=["*"], Effect=aws.Allow) ]), Description="Allows full access to all AWS", Groups=[ Ref(groups.AWSEngineers.title), ], ) self.CIDeploymentPolicy = iam.ManagedPolicy( "CIDeploymentPolicy", PolicyDocument=aws.Policy( Version="2012-10-17", Statement=[ aws.Statement(Action=[ aws.Action("cloudformation", "DescribeStacks"), aws.Action("cloudformation", "DescribeStackEvents"), aws.Action("cloudformation", "DescribeStackResources"), aws.Action("cloudformation", "DescribeChangeSet"), aws.Action("cloudformation", "GetTemplate"), aws.Action("cloudformation", "GetTemplateSummary"), aws.Action("cloudformation", "List*"), aws.Action("cloudformation", "PreviewStackUpdate"), aws.Action("cloudformation", "CancelUpdateStack"), aws.Action("cloudformation", "ContinueUpdateRollback"), aws.Action("cloudformation", "CreateChangeSet"), aws.Action("cloudformation", "CreateStack"), aws.Action("cloudformation", "CreateUploadBucket"), aws.Action("cloudformation", "ExecuteChangeSet"), aws.Action("cloudformation", "SignalResource"), aws.Action("cloudformation", "UpdateStack"), aws.Action("cloudformation", "ValidateTemplate"), aws.Action("cloudformation", "SetStackPolicy"), aws.Action("ecs", "Describe*"), aws.Action("ecs", "RegisterTaskDefinition"), aws.Action("ecs", "UpdateService"), aws.Action("ecs", "List*"), aws.Action("ecs", "DeregisterTaskDefinition"), aws.Action("ecs", "DiscoverPollEndpoint"), aws.Action("ecs", "Poll"), aws.Action("ecr", "DescribeRepositories"), aws.Action("ecr", "ListImages"), aws.Action("ecr", "BatchCheckLayerAvailability"), aws.Action("ecr", "BatchGetImage"), aws.Action("ecr", "GetAuthorizationToken"), aws.Action("ecr", "GetDownloadUrlForLayer"), aws.Action("ecr", "GetRepositoryPolicy"), aws.Action("ecr", "CompleteLayerUpload"), aws.Action("ecr", "InitiateLayerUpload"), aws.Action("ecr", "PutImage"), aws.Action("ecr", "UploadLayerPart"), aws.Action("logs", "Describe*"), ], Resource=["*"], Effect=aws.Allow) ]), Description="Allows access to cloudformation for CircleCI", Groups=[ Ref(groups.CIDeploymentServices.title), ], ) self.S3Administrator = iam.ManagedPolicy( "S3Administrator", PolicyDocument=aws.Policy(Version="2012-10-17", Statement=[ aws.Statement(Action=[ aws.Action("s3", "*"), ], Resource=["*"], Effect=aws.Allow) ]), Description="Allows full management of S3", Groups=[Ref(groups.AWSEngineers.title)], Users=[], ) self.LoggingAndMonitoring = iam.ManagedPolicy( "LoggingAndMonitoring", PolicyDocument=aws.Policy( Version="2012-10-17", Statement=[ aws.Statement(Action=[ aws.Action("cloudwatch", "GetMetricStatistics"), aws.Action("cloudwatch", "ListMetrics"), aws.Action("cloudwatch", "PutMetricData"), aws.Action("ec2", "DescribeTags"), aws.Action("logs", "CreateLogGroup"), aws.Action("logs", "CreateLogStream"), aws.Action("logs", "DescribeLogGroups"), aws.Action("logs", "DescribeLogStreams"), aws.Action("logs", "PutLogEvents"), aws.Action("sns", "Publish"), ], Resource=["*"], Effect=aws.Allow) ]), Description= "Allows ingestion of logs and metrics into CloudWatch and publishing to SNS topics", Roles=[Ref(self.EC2Baseline)], )
def generate_codepipeline_template( codepipeline_role_name: str, codepipeline_role_path: str, codebuild_role_name: str, codebuild_role_path: str, ssm_parameter_prefix: str, scm_provider: str, scm_connection_arn: str, scm_full_repository_id: str, scm_branch_name: str, scm_bucket_name: str, scm_object_key: str, scm_skip_creation_of_repo: str, migrate_role_arn: str, ) -> troposphere.Template: version = pkg_resources.get_distribution("aws-organized").version t = troposphere.Template() t.set_description( "CICD template that runs aws organized migrate for the given branch of the given repo" ) project_name = "AWSOrganized-Migrate" bucket_name = scm_bucket_name if scm_provider.lower( ) == "codecommit" and scm_skip_creation_of_repo is False: t.add_resource( codecommit.Repository("Repository", RepositoryName=scm_full_repository_id)) if scm_provider.lower() == "s3" and scm_skip_creation_of_repo is False: bucket_name = ( scm_bucket_name if scm_bucket_name else troposphere.Sub("aws-organized-pipeline-source-${AWS::AccountId}")) t.add_resource( s3.Bucket( "Source", BucketName=bucket_name, VersioningConfiguration=s3.VersioningConfiguration( Status="Enabled"), BucketEncryption=s3.BucketEncryption( ServerSideEncryptionConfiguration=[ s3.ServerSideEncryptionRule( ServerSideEncryptionByDefault=s3. ServerSideEncryptionByDefault( SSEAlgorithm="AES256")) ]), )) artifact_store = t.add_resource( s3.Bucket( "ArtifactStore", VersioningConfiguration=s3.VersioningConfiguration( Status="Enabled"), BucketEncryption=s3.BucketEncryption( ServerSideEncryptionConfiguration=[ s3.ServerSideEncryptionRule( ServerSideEncryptionByDefault=s3. ServerSideEncryptionByDefault(SSEAlgorithm="AES256")) ]), )) codepipeline_role = t.add_resource( iam.Role( "CodePipelineRole", RoleName=codepipeline_role_name, Path=codepipeline_role_path, ManagedPolicyArns=["arn:aws:iam::aws:policy/AdministratorAccess"], AssumeRolePolicyDocument=aws.PolicyDocument( Version="2012-10-17", Statement=[ aws.Statement( Effect=aws.Allow, Action=[awacs_sts.AssumeRole], Principal=aws.Principal( "Service", ["codepipeline.amazonaws.com"]), ) ], ), )) codebuild_role = t.add_resource( iam.Role( "CodeBuildRole", RoleName=codebuild_role_name, Path=codebuild_role_path, ManagedPolicyArns=["arn:aws:iam::aws:policy/AdministratorAccess"], AssumeRolePolicyDocument=aws.PolicyDocument( Version="2012-10-17", Statement=[ aws.Statement( Effect=aws.Allow, Action=[awacs_sts.AssumeRole], Principal=aws.Principal("Service", ["codebuild.amazonaws.com"]), ) ], ), )) version_parameter = ssm.Parameter( "versionparameter", Name=f"{ssm_parameter_prefix}/version", Type="String", Value=version, ) t.add_resource(version_parameter) project = t.add_resource( codebuild.Project( "AWSOrganizedMigrate", Artifacts=codebuild.Artifacts(Type="CODEPIPELINE"), Environment=codebuild.Environment( ComputeType="BUILD_GENERAL1_SMALL", Image="aws/codebuild/standard:4.0", Type="LINUX_CONTAINER", EnvironmentVariables=[ { "Name": "MIGRATE_ROLE_ARN", "Type": "PLAINTEXT", "Value": migrate_role_arn, }, { "Name": "Version", "Type": "PARAMETER_STORE", "Value": troposphere.Ref(version_parameter), }, { "Name": "SSM_PARAMETER_PREFIX", "Type": "PLAINTEXT", "Value": ssm_parameter_prefix, }, ], ), Name=project_name, ServiceRole=troposphere.GetAtt(codebuild_role, "Arn"), Source=codebuild.Source( Type="CODEPIPELINE", BuildSpec=yaml.safe_dump( dict( version="0.2", phases=dict( install={ "runtime-versions": dict(python="3.8"), "commands": ["pip install aws-organized==${Version}"], }, build={ "commands": [ "aws-organized migrate --ssm-parameter-prefix $SSM_PARAMETER_PREFIX $MIGRATE_ROLE_ARN" ] }, ), artifacts=dict(files=["environment"]), )), ), )) source_actions = dict( codecommit=codepipeline.Actions( Name="SourceAction", ActionTypeId=codepipeline.ActionTypeId(Category="Source", Owner="AWS", Version="1", Provider="CodeCommit"), OutputArtifacts=[ codepipeline.OutputArtifacts(Name="SourceOutput") ], Configuration={ "RepositoryName": scm_full_repository_id, "BranchName": scm_branch_name, "PollForSourceChanges": "true", }, RunOrder="1", ), codestarsourceconnection=codepipeline.Actions( Name="SourceAction", ActionTypeId=codepipeline.ActionTypeId( Category="Source", Owner="AWS", Version="1", Provider="CodeStarSourceConnection", ), OutputArtifacts=[ codepipeline.OutputArtifacts(Name="SourceOutput") ], Configuration={ "ConnectionArn": scm_connection_arn, "FullRepositoryId": scm_full_repository_id, "BranchName": scm_branch_name, "OutputArtifactFormat": "CODE_ZIP", }, RunOrder="1", ), s3=codepipeline.Actions( Name="SourceAction", ActionTypeId=codepipeline.ActionTypeId(Category="Source", Owner="AWS", Version="1", Provider="S3"), OutputArtifacts=[ codepipeline.OutputArtifacts(Name="SourceOutput") ], Configuration={ "S3Bucket": bucket_name, "S3ObjectKey": scm_object_key, "PollForSourceChanges": True, }, RunOrder="1", ), ).get(scm_provider.lower()) t.add_resource( codepipeline.Pipeline( "Pipeline", RoleArn=troposphere.GetAtt(codepipeline_role, "Arn"), Stages=[ codepipeline.Stages(Name="Source", Actions=[source_actions]), codepipeline.Stages( Name="Migrate", Actions=[ codepipeline.Actions( Name="Migrate", InputArtifacts=[ codepipeline.InputArtifacts( Name="SourceOutput") ], ActionTypeId=codepipeline.ActionTypeId( Category="Build", Owner="AWS", Version="1", Provider="CodeBuild", ), Configuration={ "ProjectName": troposphere.Ref(project), "PrimarySource": "SourceAction", }, RunOrder="1", ) ], ), ], ArtifactStore=codepipeline.ArtifactStore( Type="S3", Location=troposphere.Ref(artifact_store)), )) return t
Description="Name of the bucket where lambda function sources is stored" )) param_lambda_file_name = template.add_parameter( Parameter( "LambdaFileName", Type="String", Description= "Name of the ZIP file with lambda function sources inside S3 bucket")) lambda_role = template.add_resource( iam.Role( "LambaRole", AssumeRolePolicyDocument=aws.Policy(Statement=[ aws.Statement(Effect=aws.Allow, Action=[sts.AssumeRole], Principal=aws.Principal("Service", ["lambda.amazonaws.com"])) ]), Policies=[ iam.Policy( PolicyName="LambdaPolicy", PolicyDocument=aws.Policy(Statement=[ aws.Statement(Effect=aws.Allow, Action=[ aws.Action("logs", "CreateLogGroup"), aws.Action("logs", "CreateLogStream"), aws.Action("logs", "PutLogEvents"), ], Resource=["arn:aws:logs:*:*:*"]) ])) ]))
def publish_statement_from_topics(*topics: sns.Topic) -> AWS.Statement: return AWS.Statement(Effect=AWS.Allow, Action=[SNS.Publish], Resource=[top.ref() for top in topics])