def _construct_role(self, resource, prefix=None, suffix=""): """Constructs the IAM Role resource allowing the event service to invoke the StartExecution API of the state machine resource it is associated with. :param model.stepfunctions.StepFunctionsStateMachine resource: The state machine resource associated with the event :param string prefix: Prefix to use for the logical ID of the IAM role :param string suffix: Suffix to add for the logical ID of the IAM role :returns: the IAM Role resource :rtype: model.iam.IAMRole """ role_logical_id = self._generate_logical_id(prefix=prefix, suffix=suffix, resource_type="Role") event_role = IAMRole( role_logical_id, attributes=resource.get_passthrough_resource_attributes()) event_role.AssumeRolePolicyDocument = IAMRolePolicies.construct_assume_role_policy_for_service_principal( self.principal) state_machine_arn = resource.get_runtime_attr("arn") event_role.Policies = [ IAMRolePolicies.step_functions_start_execution_role_policy( state_machine_arn, role_logical_id) ] return event_role
def _construct_role(self, managed_policy_map): """Constructs a Lambda execution role based on this SAM function's Policies property. :returns: the generated IAM Role :rtype: model.iam.IAMRole """ execution_role = IAMRole(self.logical_id + 'Role') execution_role.AssumeRolePolicyDocument = IAMRolePolicies.lambda_assume_role_policy() managed_policy_arns = [ArnGenerator.generate_aws_managed_policy_arn('service-role/AWSLambdaBasicExecutionRole')] if self.Tracing: managed_policy_arns.append(ArnGenerator.generate_aws_managed_policy_arn('AWSXrayWriteOnlyAccess')) function_policies = FunctionPolicies({"Policies": self.Policies}, # No support for policy templates in the "core" policy_template_processor=None) policy_documents = [] if self.DeadLetterQueue: policy_documents.append(IAMRolePolicies.dead_letter_queue_policy( self.dead_letter_queue_policy_actions[self.DeadLetterQueue['Type']], self.DeadLetterQueue['TargetArn'])) for index, policy_entry in enumerate(function_policies.get()): if policy_entry.type is PolicyTypes.POLICY_STATEMENT: policy_documents.append({ 'PolicyName': execution_role.logical_id + 'Policy' + str(index), 'PolicyDocument': policy_entry.data }) elif policy_entry.type is PolicyTypes.MANAGED_POLICY: # There are three options: # Managed Policy Name (string): Try to convert to Managed Policy ARN # Managed Policy Arn (string): Insert it directly into the list # Intrinsic Function (dict): Insert it directly into the list # # When you insert into managed_policy_arns list, de-dupe to prevent same ARN from showing up twice # policy_arn = policy_entry.data if isinstance(policy_entry.data, string_types) and policy_entry.data in managed_policy_map: policy_arn = managed_policy_map[policy_entry.data] # De-Duplicate managed policy arns before inserting. Mainly useful # when customer specifies a managed policy which is already inserted # by SAM, such as AWSLambdaBasicExecutionRole if policy_arn not in managed_policy_arns: managed_policy_arns.append(policy_arn) else: # Policy Templates are not supported here in the "core" raise InvalidResourceException( self.logical_id, "Policy at index {} in the 'Policies' property is not valid".format(index)) execution_role.ManagedPolicyArns = list(managed_policy_arns) execution_role.Policies = policy_documents or None return execution_role
def _construct_role(self): """ Constructs a State Machine execution role based on this SAM State Machine's Policies property. :returns: the generated IAM Role :rtype: model.iam.IAMRole """ policies = self.policies[:] if self.tracing and self.tracing.get("Enabled") is True: policies.append(get_xray_managed_policy_name()) state_machine_policies = ResourcePolicies( {"Policies": policies}, # No support for policy templates in the "core" policy_template_processor=None, ) execution_role = construct_role_for_resource( resource_logical_id=self.logical_id, attributes=self.passthrough_resource_attributes, managed_policy_map=self.managed_policy_map, assume_role_policy_document=IAMRolePolicies.stepfunctions_assume_role_policy(), resource_policies=state_machine_policies, tags=self._construct_tag_list(), permissions_boundary=self.permissions_boundary, ) return execution_role
def _construct_role(self): """ Constructs a State Machine execution role based on this SAM State Machine's Policies property. :returns: the generated IAM Role :rtype: model.iam.IAMRole """ state_machine_policies = ResourcePolicies( {"Policies": self.policies}, # No support for policy templates in the "core" policy_template_processor=None, ) execution_role = construct_role_for_resource( resource_logical_id=self.logical_id, attributes=self.passthrough_resource_attributes, managed_policy_map=self.managed_policy_map, assume_role_policy_document=IAMRolePolicies.stepfunctions_assume_role_policy(), resource_policies=state_machine_policies, tags=self._construct_tag_list(), ) return execution_role
def to_cloudformation(self, **kwargs): """Returns the Lambda EventSourceMapping to which this pull event corresponds. Adds the appropriate managed policy to the function's execution role, if such a role is provided. :param dict kwargs: a dict containing the execution role generated for the function :returns: a list of vanilla CloudFormation Resources, to which this pull event expands :rtype: list """ function = kwargs.get("function") if not function: raise TypeError("Missing required keyword argument: function") resources = [] lambda_eventsourcemapping = LambdaEventSourceMapping(self.logical_id) resources.append(lambda_eventsourcemapping) try: # Name will not be available for Alias resources function_name_or_arn = function.get_runtime_attr("name") except NotImplementedError: function_name_or_arn = function.get_runtime_attr("arn") if not self.Stream and not self.Queue: raise InvalidEventException( self.relative_id, "No Queue (for SQS) or Stream (for Kinesis or DynamoDB) provided." ) if self.Stream and not self.StartingPosition: raise InvalidEventException( self.relative_id, "StartingPosition is required for Kinesis and DynamoDB.") lambda_eventsourcemapping.FunctionName = function_name_or_arn lambda_eventsourcemapping.EventSourceArn = self.Stream or self.Queue lambda_eventsourcemapping.StartingPosition = self.StartingPosition lambda_eventsourcemapping.BatchSize = self.BatchSize lambda_eventsourcemapping.Enabled = self.Enabled lambda_eventsourcemapping.MaximumBatchingWindowInSeconds = self.MaximumBatchingWindowInSeconds lambda_eventsourcemapping.MaximumRetryAttempts = self.MaximumRetryAttempts lambda_eventsourcemapping.BisectBatchOnFunctionError = self.BisectBatchOnFunctionError lambda_eventsourcemapping.MaximumRecordAgeInSeconds = self.MaximumRecordAgeInSeconds lambda_eventsourcemapping.ParallelizationFactor = self.ParallelizationFactor destination_config_policy = None if self.DestinationConfig: # `Type` property is for sam to attach the right policies destination_type = self.DestinationConfig.get("OnFailure").get( "Type") # SAM attaches the policies for SQS or SNS only if 'Type' is given if destination_type: # delete this field as its used internally for SAM to determine the policy del self.DestinationConfig["OnFailure"]["Type"] # the values 'SQS' and 'SNS' are allowed. No intrinsics are allowed if destination_type not in ["SQS", "SNS"]: raise InvalidEventException( self.logical_id, "The only valid values for 'Type' are 'SQS' and 'SNS'") if self.DestinationConfig.get("OnFailure") is None: raise InvalidEventException( self.logical_id, "'OnFailure' is a required field for " "'DestinationConfig'") if destination_type == "SQS": queue_arn = self.DestinationConfig.get("OnFailure").get( "Destination") destination_config_policy = IAMRolePolicies( ).sqs_send_message_role_policy(queue_arn, self.logical_id) elif destination_type == "SNS": sns_topic_arn = self.DestinationConfig.get( "OnFailure").get("Destination") destination_config_policy = IAMRolePolicies( ).sns_publish_role_policy(sns_topic_arn, self.logical_id) lambda_eventsourcemapping.DestinationConfig = self.DestinationConfig if "Condition" in function.resource_attributes: lambda_eventsourcemapping.set_resource_attribute( "Condition", function.resource_attributes["Condition"]) if "role" in kwargs: self._link_policy(kwargs["role"], destination_config_policy) return resources