def create_policy(self, name=None): statements = self.generate_policy_statements() if not statements: return t = self.template logical_name = "Policy" if name: logical_name = "{}Policy".format(name) policy_name = Sub("${AWS::StackName}-${Name}-policy", Name=name) else: policy_name = Sub("${AWS::StackName}-policy") policy = t.add_resource( iam.PolicyType( logical_name, PolicyName=policy_name, PolicyDocument=Policy( Statement=statements, ), Roles=[Ref(role) for role in self.roles], ) ) t.add_output( Output("PolicyName", Value=Ref(policy)) ) self.policies.append(policy) return policy
def get_codedeploy_assumerole_policy(): """ Helper function for building the AWS CodeDeploy AssumeRole Policy """ service = 'codedeploy.amazonaws.com' policy = Policy(Statement=[make_simple_assume_statement(service)]) return policy
def add_resources(self): """Create template (main function called by Stacker).""" template = self.template variables = self.get_variables() # Resources # build the CFN template with the specified permissions iam_statements = [] iam_statements.append( Statement( Sid='AllowReadAccessToS3Bucket', Action=[ awacs.s3.GetObject, awacs.s3.ListBucket ], Effect=Allow, Resource=[variables['S3BucketArn'].ref] ) ) template.add_resource( iam.PolicyType( 'IamInlinePolicy', PolicyDocument=Policy( Version='2012-10-17', Statement=iam_statements, ), PolicyName=Join('', [ 'S3AccessToBucket-', variables['S3BucketName'].ref ]), Roles=[variables['IamRoleName'].ref] ) )
def attach_ssm_policy(self, myrole): return super(NCTemplate, self).add_resource( iam.PolicyType( 'policyssm', PolicyName='ssmpolicy', PolicyDocument=Policy( Version='2012-10-17', Statement=[ Statement(Effect=Allow, Action=[Action("ssm", "DescribeParameters")], Resource=["*"]), Statement( Effect=Allow, Action=[Action("ssm", "GetParameters")], Resource=[ Join("", [ "arn:aws:ssm", ":", Ref("AWS::Region"), ":", Ref("AWS::AccountId"), ":", "parameter/", Ref("AWS::StackName"), "/*" ]), Join("", [ "arn:aws:ssm", ":", Ref("AWS::Region"), ":", Ref("AWS::AccountId"), ":", "parameter/", "globals", "/*" ]), ]), ]), Roles=[Ref(myrole)]))
def create_codebuild_project(template) -> cb.Project: from troposphere.codebuild import Project, Environment, Artifacts, Source environment = Environment( ComputeType='BUILD_GENERAL1_SMALL', Image='aws/codebuild/standard:3.0', Type='LINUX_CONTAINER', ) codebuild_role = template.add_resource( Role( "CodeBuildRole", AssumeRolePolicyDocument=Policy(Statement=[ Statement(Effect=Allow, Action=[AssumeRole], Principal=Principal("Service", ["codebuild.amazonaws.com"])) ]), ManagedPolicyArns=[ 'arn:aws:iam::aws:policy/AmazonS3FullAccess', 'arn:aws:iam::aws:policy/CloudWatchFullAccess', 'arn:aws:iam::aws:policy/AWSCodeBuildAdminAccess', ], )) # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codebuild-project-source.html return Project("ContinuousCodeBuild", Name="ContinuousCodeBuild", Description='Continous pipeline', Artifacts=Artifacts(Type='CODEPIPELINE'), Environment=environment, Source=Source(Type='CODEPIPELINE'), ServiceRole=Ref(codebuild_role))
def create_iam_policy(stack, policy_name, actions, groups=[], roles=[], users=[], resources=['*']): """Add IAM policy resource.""" return stack.stack.add_resource( ManagedPolicy( policy_name, ManagedPolicyName=policy_name, Groups=groups, Roles=roles, Users=users, PolicyDocument=Policy( Version='2012-10-17', Statement=[ Statement(Effect=Allow, Action=[ Action('{0}'.format(action.split(':')[0]), '{0}'.format(action.split(':')[1])) for action in actions ], Resource=resources) ])))
def create_iam_role(stack, role_name, managed_policies=(), instance_profile=False, service=['ec2.amazonaws.com']): """Add IAM role resource.""" managed_policy_arns = [ 'arn:aws:iam::aws:policy/{0}'.format(policy) for policy in managed_policies ] new_role = stack.stack.add_resource( Role('{0}Role'.format(role_name.replace('-', '')), RoleName=role_name, ManagedPolicyArns=managed_policy_arns, AssumeRolePolicyDocument=Policy(Statement=[ Statement(Effect=Allow, Action=[AssumeRole], Principal=Principal('Service', service)) ]))) if instance_profile: stack.stack.add_resource( InstanceProfile('{}instanceprofile'.format( role_name.replace('-', '')), InstanceProfileName=role_name, Roles=[(Ref(new_role))])) return new_role
def get_lambda_assumerole_policy(region=''): """ Helper function for building the AWS Lambda AssumeRole Policy """ service = 'lambda.amazonaws.com' policy = Policy(Statement=[make_simple_assume_statement(service)]) return policy
def add_bucket_policy(self, bucket): # type: (s3.Bucket) -> s3.BucketPolicy """Add a policy to the bucket if CloudFront is disabled. Ensure PublicRead. Args: bucket: The bucket resource to place the policy. Returns: The Bucket Policy Resource. """ return self.template.add_resource( s3.BucketPolicy( "BucketPolicy", Bucket=bucket.ref(), PolicyDocument=Policy( Version="2012-10-17", Statement=[ Statement( Effect=Allow, Principal=Principal("*"), Action=[Action("s3", "getObject")], Resource=[Join("", [bucket.get_att("Arn"), "/*"])], ) ], ), ) )
def build_role(self, name, policies=False): """ Generate role for IAM cloudformation template :param name: Name of role :param policies: List of policies to attach to this role (False = none) :return: Ref to new role """ # Build role template if policies: role = self.__template.add_resource( Role( self.name_strip(name), AssumeRolePolicyDocument=Policy( Version=self.VERSION_IAM, Statement=[ Statement( Effect=Allow, Principal=Principal("Service", self.__role_principals), Action=[AssumeRole], ) ]), Path=self.__role_path, ManagedPolicyArns=policies, )) # Add role to list for default policy self.__roles_list.append(troposphere.Ref(role)) else: role = self.__template.add_resource( Role( self.name_strip(name), AssumeRolePolicyDocument=Policy( Version=self.VERSION_IAM, Statement=[ Statement( Effect=Allow, Principal=Principal("Service", self.__role_principals), Action=[AssumeRole], ) ]), Path=self.__role_path, )) # Add role to list for default policy self.__roles_list.append(troposphere.Ref(role)) return role
def create_template(self): t = self.template bucket_arn = Sub("arn:aws:s3:::${StackerBucket}*") cloudformation_scope = Sub( "arn:aws:cloudformation:${AWS::Region}:${AWS::AccountId}:" "stack/${StackerNamespace}-*") changeset_scope = "*" # This represents the precise IAM permissions that stacker itself # needs. stacker_policy = iam.Policy( PolicyName="Stacker", PolicyDocument=Policy(Statement=[ Statement(Effect="Allow", Resource=[bucket_arn], Action=[ awacs.s3.ListBucket, awacs.s3.GetBucketLocation, awacs.s3.CreateBucket ]), Statement(Effect="Allow", Resource=[bucket_arn], Action=[ awacs.s3.GetObject, awacs.s3.GetObjectAcl, awacs.s3.PutObject, awacs.s3.PutObjectAcl ]), Statement(Effect="Allow", Resource=[changeset_scope], Action=[ awacs.cloudformation.DescribeChangeSet, awacs.cloudformation.ExecuteChangeSet, awacs.cloudformation.DeleteChangeSet, ]), Statement(Effect="Deny", Resource=[Ref("AWS::StackId")], Action=[awacs.cloudformation.Action("*")]), Statement( Effect="Allow", Resource=[cloudformation_scope], Action=[ awacs.cloudformation.GetTemplate, awacs.cloudformation. CreateChangeSet, awacs.cloudformation.DeleteChangeSet, awacs.cloudformation.DeleteStack, awacs.cloudformation. CreateStack, awacs.cloudformation.UpdateStack, awacs.cloudformation.DescribeStacks ]) ])) user = t.add_resource( iam.User("FunctionalTestUser", Policies=[stacker_policy])) key = t.add_resource( iam.AccessKey("FunctionalTestKey", Serial=1, UserName=Ref(user))) t.add_output(Output("User", Value=Ref(user))) t.add_output(Output("AccessKeyId", Value=Ref(key))) t.add_output( Output("SecretAccessKey", Value=GetAtt("FunctionalTestKey", "SecretAccessKey")))
def assume_role_policy_document(service_prinicpal): return Policy(Statement=[ Statement( Effect=Allow, Action=[sts.AssumeRole], Principal=Principal("Service", [service_prinicpal]), ) ])
def queue_policy(sns_arn, sqs_arns): return Policy(Statement=[ Statement(Effect="Allow", Principal=Principal("*"), Action=[awacs.sqs.SendMessage], Resource=sqs_arns, Condition=Condition(ArnEquals({"aws:SourceArn": sns_arn}))) ])
def get_default_group(self, params): """Generates JSON for a default group statement :param dict params: list of parameters """ return Policy(Statement=[ Statement(Effect=Allow, NotAction=['*'], Resource=['*']) ])
def _instance_iam_role(self): return Role("InstanceIamRole", AssumeRolePolicyDocument=Policy(Statement=[ Statement(Effect=Allow, Action=[AssumeRole], Principal=Principal("Service", ["ec2.amazonaws.com"])) ]), Path="/")
def sns_to_sqs_policy(topic): p = Policy(Statement=[ Statement(Effect=Allow, Principal=Principal('*'), Action=[sqs.SendMessage], Resource=["*"], Condition=Condition(ArnEquals(SourceArn, topic))) ]) return p
def add_cd_applications(self): cdapp_index = 0 for cdapp in self.aws['cd_application.names'].split(','): name, tags = self._name_tags('cd_application') cdapp_name = name + str(cdapp_index) self.cd_application = self.t.add_resource( codedeploy.Application( cdapp_name, ApplicationName=cdapp, # Doesn't support: Tags=Tags(**tags), )) cdapp_output_name = "CDApp" + str(cdapp_index) self.t.add_output(Output( cdapp_output_name, Value=Ref(self.cd_application) )) cd_role_name = cdapp + "CDRole" self.cd_role = self.t.add_resource( iam.Role( cd_role_name, AssumeRolePolicyDocument=Policy( Statement=[ Statement( Action=[awacs.sts.AssumeRole], Effect=Allow, Principal=Principal('Service', 'codedeploy.amazonaws.com'), Sid=cd_role_name, # redundant? ), ], ), ManagedPolicyArns=['arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole'], Path='/', )) cd_role_output_name = "CDRole" + str(cdapp_index) self.t.add_output(Output( cd_role_output_name, Value=Ref(self.cd_role) )) cd_iam_user_name = cdapp + "CDUser" self.cd_iam_user = self.t.add_resource( iam.User( cd_iam_user_name, # Can't attach policy here, # must create policy and attach to user from app stack # ManagedPolicyArns=[Ref(self.cd_iam_user_policy.name)] )) cd_iam_user_output_name = "CDUser" + str(cdapp_index) self.t.add_output(Output( cd_iam_user_output_name, Value=Ref(self.cd_iam_user) )) cdapp_index += 1
def sns_events_policy(topic_arn): p = Policy(Statement=[ Statement( Effect=Allow, Action=[sns.Publish], Resource=[topic_arn], ) ]) return p
def create_ecs_service_role(provider, context, **kwargs): """Create ecsServieRole, which has to be named exactly that currently. http://docs.aws.amazon.com/AmazonECS/latest/developerguide/IAM_policies.html#service_IAM_role Args: provider (:class:`runway.cfngin.providers.base.BaseProvider`): Provider instance. (passed in by CFNgin) context (:class:`runway.cfngin.context.Context`): Context instance. (passed in by CFNgin) Keyword Args: role_name (str): Name of the role to create. (*default: ecsServiceRole*) Returns: bool: Whether or not the hook succeeded. """ role_name = kwargs.get("role_name", "ecsServiceRole") client = get_session(provider.region).client("iam") try: client.create_role( RoleName=role_name, AssumeRolePolicyDocument=get_ecs_assumerole_policy().to_json(), ) except ClientError as err: if "already exists" in str(err): pass else: raise policy = Policy( Version="2012-10-17", Statement=[ Statement( Effect=Allow, Resource=["*"], Action=[ ecs.CreateCluster, ecs.DeregisterContainerInstance, ecs.DiscoverPollEndpoint, ecs.Poll, ecs.Action("Submit*"), ], ) ], ) client.put_role_policy( RoleName=role_name, PolicyName="AmazonEC2ContainerServiceRolePolicy", PolicyDocument=policy.to_json(), ) return True
def create_template(self): t = self.template t.add_description("Acceptance Tests for cumulus scaling groups") # TODO fix # instance = self.name + self.context.environment['env'] instance = "someinstance" # TODO: give to builder the_chain = chain.Chain() the_chain.add(ingress_rule.IngressRule( port_to_open="22", cidr="10.0.0.0/8" )) instance_profile_name = "InstanceProfile" + self.name the_chain.add(InstanceProfileRole( instance_profile_name=instance_profile_name, role=iam.Role( "SomeRoleName1", AssumeRolePolicyDocument=Policy( Statement=[ Statement( Effect=Allow, Action=[AssumeRole], Principal=Principal("Service", ["ec2.amazonaws.com", "s3.amazonaws.com"]) ) ] ), ))) launchConfigName = 'lc' + self.name the_chain.add(launch_config.LaunchConfig(asg_name=self.name, launch_config_name=launchConfigName, meta_data=self.get_metadata(), instance_profile_name=instance_profile_name), ) the_chain.add(block_device_data.BlockDeviceData(ec2.BlockDeviceMapping( DeviceName="/dev/xvda", Ebs=ec2.EBSBlockDevice( VolumeSize="40" )))) the_chain.add(scaling_group.ScalingGroup( launch_config_name=launchConfigName, )) chain_context = chaincontext.ChainContext( template=t, instance_name=instance ) the_chain.run(chain_context)
def kms_key_policy(): """ Creates a key policy for use of a KMS Key. """ statements = [] statements.extend(kms_key_root_statements()) return Policy( Version="2012-10-17", Id="root-account-access", Statement=statements )
def get_ec2_assume_role_policy(ec2_principal): return Policy( Statement=[ Statement( Effect=Allow, Action=[AssumeRole], Principal=Principal( "Service", [ec2_principal] ) ) ] )
def logs_policy(): statements = [ Statement( Effect=Allow, Action=[ awacs.logs.CreateLogStream, ], Resource=['*'], ), ] return Policy(Statement=statements)
def attach_policy(*, region, acct_id, bucket_arns): return Policy( Version='2012-10-17', Statement=list(chain.from_iterable([ stmts_logging(region, acct_id), stmts_lambda_invocation(), stmts_custom_domain(), stmts_vpc(), stmts_app(region, acct_id, bucket_arns), ])) )
def ecs_agent_policy(): p = Policy(Statement=[ Statement(Effect=Allow, Resource=["*"], Action=[ ecs.CreateCluster, ecs.RegisterContainerInstance, ecs. DeregisterContainerInstance, ecs.DiscoverPollEndpoint, ecs.ECSAction("Submit*"), ecs.Poll ]) ]) return p
def logs_write_policy(): statements = [ Statement( Effect=Allow, Action=[ awacs.logs.PutLogEvents, ], Resource=['*'], ), ] return Policy(Statement=statements)
def queue_policy(sns_arn, sqs_arns): stmts = [] for arn in sqs_arns: stmts.append( Statement(Effect="Allow", Principal=Principal("*"), Action=[awacs.sqs.SendMessage], Resource=[arn], Condition=Condition(ArnEquals({"aws:SourceArn": sns_arn})))) return Policy(Statement=stmts)
def logstream_policy(): """Policy needed for logspout -> kinesis log streaming.""" p = Policy(Statement=[ Statement(Effect=Allow, Resource=["*"], Action=[ kinesis.CreateStream, kinesis.DescribeStream, Action(kinesis.prefix, "AddTagsToStream"), Action(kinesis.prefix, "PutRecords") ]) ]) return p
def create_allow_policy(self, name, actions, resources): awacs_actions = [ Action(action.split(':')[0], action.split(':')[1]) for action in actions ] return Policy(Version='2012-10-17', Id='{0}{1}'.format(self.project, name), Statement=[ Statement(Effect=Allow, Action=awacs_actions, Resource=resources) ])
def attach_policy(*, region, acct_id, key_id, queue_name): return Policy(Version='2012-10-17', Statement=list( chain.from_iterable([ stmts_logging(region, acct_id), stmts_lambda_invocation(), stmts_custom_domain(), stmts_vpc(), stmts_custom_authorizer(region, acct_id, key_id), stmts_app_webhook_handler(region, acct_id, queue_name), ])))