Conditions:
  ActivateAccessAnalyzer: !Equals
    - Yes, Activate Access Analyzer
    - !Ref 'AccessAnalyzerActivation'
  ActivateMacie: !Equals
    - Yes, Activate Macie
    - !Ref 'MacieActivation'
  ActivateSecurityHub: !Equals
    - Yes, Activate Security Hub
    - !Ref 'SecurityHubActivation'
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: Application  Code
        Parameters:
          - SourceCodeBucket
          - SourceCodeBucketPath
      - Label:
          default: Service Activations
        Parameters:
          - MacieActivation
          - SecurityHubActivation
          - AccessAnalyzerActivation
      - Label:
          default: Logging & Monitoring
        Parameters:
          - LogRetentionInDays
          - AlertEmailAddress
    ParameterLabels:
      AccessAnalyzerActivation:
        default: IAM Access Analyzer
      AlertEmailAddress:
        default: Alert Email Address
      LogRetentionInDays:
        default: Log Retention
      MacieActivation:
        default: Amazon Macie
      SecurityHubActivation:
        default: AWS Security Hub
      SourceCodeBucket:
        default: S3 Bucket
      SourceCodeBucketPath:
        default: S3 Key
  Comments: JLT Access Analyzer with Macie
  CreatedBy: Carter Meyers
  Description: JLT Access Analyzer - v1.67
  LastUpdated: February 28, 2022
  Version: v1.67
Parameters:
  AccessAnalyzerActivation:
    AllowedValues:
      - Yes, Activate Access Analyzer
      - No, We've Already Activated Access Analyzer in This Account
    Default: Yes, Activate Access Analyzer
    Description: Should AWS IAM Access Analyzer be activated in this account?
    Type: String
  LogRetentionInDays:
    Default: 30
    Description: The number of days application logs should be retained.
    MaxValue: 3650
    MinValue: 1
    Type: Number
  MacieActivation:
    AllowedValues:
      - Yes, Activate Macie
      - No, We've Already Activated Macie in This Account
    Default: Yes, Activate Macie
    Description: Should Amazon Macie be activated in this account?
    Type: String
  SecurityHubActivation:
    AllowedValues:
      - Yes, Activate Security Hub
      - No, We've Already Activated Security Hub in This Account
    Default: Yes, Activate Security Hub
    Description: Should AWS Security Hub be activated in this account?
    Type: String
  SourceCodeBucket:
    Default: awsiammedia
    Description: The bucket containing the Lambda function code.
    Type: String
  SourceCodeBucketPath:
    Default: public/sample/936-correlating-aa-findings-macie/amazon-access-analyzer-with-amazon-macie-discovery.zip
    Description: The path (i.e., key) for the zip file containing the Lambda function
      code in the above bucket.
    Type: String
Resources:
  AccessAnalyzer:
    Condition: ActivateAccessAnalyzer
    Properties:
      Type: ACCOUNT
    Type: AWS::AccessAnalyzer::Analyzer
  EventBridgeRole:
    DependsOn:
      - StateMachine
      - FindingsSaverFunction
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - events.amazonaws.com
      Policies:
        - PolicyDocument:
            Statement:
              - Action:
                  - states:StartExecution
                Effect: Allow
                Resource:
                  - !Ref 'StateMachine'
          PolicyName: primary-policy
    Type: AWS::IAM::Role
  FindingsSaverEventBridgeRule:
    DependsOn:
      - FindingsSaverFunction
    Properties:
      Description: !Join
        - ''
        - - Triggers findings saver function based on Access Analyzer finding event
      EventPattern:
        detail:
          resourceType:
            - AWS::S3::Bucket
          status:
            - ACTIVE
        detail-type:
          - Access Analyzer Finding
        source:
          - aws.access-analyzer
      State: ENABLED
      Targets:
        - Arn: !GetAtt 'FindingsSaverFunction.Arn'
          Id: FindingsSaver
    Type: AWS::Events::Rule
  FindingsSaverEventBridgeRulePermission:
    DependsOn:
      - FindingsSaverFunction
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !Ref 'FindingsSaverFunction'
      Principal: events.amazonaws.com
      SourceArn: !GetAtt 'FindingsSaverEventBridgeRule.Arn'
    Type: AWS::Lambda::Permission
  FindingsSaverFunction:
    Condition: ''
    DependsOn:
      - FindingsSaverRole
      - FindingsTable
      - LambdaCodeCopier
    Properties:
      Code:
        S3Bucket: !Ref 'TempCodeBucket'
        S3Key: lambda-code.zip
      Description: Saves IAM Access Analyzer findings to DynamoDB
      Environment:
        Variables:
          logLevel: info
          tableAaFindings: !Ref 'FindingsTable'
      Handler: scripts.sda-aa-save-findings.lambda_handler
      MemorySize: 128
      Role: !GetAtt 'FindingsSaverRole.Arn'
      Runtime: python3.8
      Timeout: 60
    Type: AWS::Lambda::Function
  FindingsSaverLogGroup:
    Condition: ''
    DeletionPolicy: Delete
    DependsOn:
      - FindingsSaverFunction
    Properties:
      LogGroupName: !Join
        - ''
        - - /aws/lambda/
          - !Ref 'FindingsSaverFunction'
      RetentionInDays: !Ref 'LogRetentionInDays'
    Type: AWS::Logs::LogGroup
  FindingsSaverRole:
    Condition: ''
    DependsOn:
      - FindingsTable
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Policies:
        - PolicyDocument:
            Statement:
              - Action:
                  - dynamodb:Scan
                  - dynamodb:Query
                  - dynamodb:GetItem
                  - dynamodb:PutItem
                  - dynamodb:UpdateItem
                  - dynamodb:BatchGetItem
                  - dynamodb:BatchWriteItem
                  - dynamodb:DescribeTable
                Effect: Allow
                Resource:
                  - !GetAtt 'FindingsTable.Arn'
          PolicyName: PrimaryPolicy
    Type: AWS::IAM::Role
  FindingsTable:
    Properties:
      AttributeDefinitions:
        - AttributeName: createDate
          AttributeType: N
        - AttributeName: aaFindingId
          AttributeType: S
      BillingMode: PAY_PER_REQUEST
      KeySchema:
        - AttributeName: createDate
          KeyType: HASH
        - AttributeName: aaFindingId
          KeyType: RANGE
      SSESpecification:
        SSEEnabled: true
    Type: AWS::DynamoDB::Table
  LambdaCodeCopier:
    DependsOn:
      - LambdaCodeManagerFunction
      - LambdaCodeManagerLogGroup
    Properties:
      ServiceToken: !GetAtt 'LambdaCodeManagerFunction.Arn'
      Type: Custom::CopyLambdaCode
      Version: '1.0'
    Type: AWS::CloudFormation::CustomResource
  LambdaCodeManagerFunction:
    Condition: ''
    DependsOn:
      - LambdaCodeManagerRole
      - TempCodeBucket
    Properties:
      Code:
        ZipFile: "import os\nimport json\nimport boto3\nimport logging\nimport urllib3\n\
          from botocore.exceptions import ClientError as boto3_client_error\n\nLOGGER\
          \ = logging.getLogger()\nLOGGER.setLevel(logging.INFO)\n\nhttp = urllib3.PoolManager()\n\
          \ntry:\n    from urllib2 import HTTPError, build_opener, HTTPHandler, Request\n\
          except ImportError:\n    from urllib.error import HTTPError\n    from urllib.request\
          \ import build_opener, HTTPHandler, Request\n    \ndef respond_to_cfn(event,\
          \ context, response_status, reason = None, response_data = None, physical_resource_id\
          \ = None):\n    \n    response_data = response_data or {}\n    \n    response_body\
          \ = json.dumps(\n        {\n            'Status': response_status,\n   \
          \         'Reason': reason or \"See the details in CloudWatch Log Stream:\
          \ \" + context.log_stream_name,\n            'PhysicalResourceId': physical_resource_id\
          \ or context.log_stream_name,\n            'StackId': event['StackId'],\n\
          \            'RequestId': event['RequestId'],\n            'LogicalResourceId':\
          \ event['LogicalResourceId'],\n            'Data': response_data\n     \
          \   }\n    )\n\n    opener = build_opener(HTTPHandler)\n    request = Request(event['ResponseURL'],\
          \ data = response_body.encode('utf-8'))\n    request.add_header('Content-Type',\
          \ '')\n    request.add_header('Content-Length', len(response_body))\n  \
          \  request.get_method = lambda: 'PUT'\n    try:\n        response = opener.open(request)\n\
          \        print(\"Status code: {}\".format(response.getcode()))\n       \
          \ print(\"Status message: {}\".format(response.msg))\n        return True\n\
          \    except HTTPError as exc:\n        print(\"Failed executing HTTP request:\
          \ {}\".format(exc.code))\n        return False\n        \ndef handler(event,\
          \ context):\n    \n    LOGGER.info('----- REQUEST RECEIVED -----')\n   \
          \ LOGGER.info(json.dumps(event))\n    \n    if event['RequestType'] in ['Create',\
          \ 'Update']:\n        \n        try:\n            \n            s3_copy_response\
          \ = boto3.client('s3').copy_object(\n                ACL = 'private',\n\
          \                Key = 'lambda-code.zip',\n                Bucket = os.environ['tempCodeBucketName'],\n\
          \                CopySource = {\n                    'Key': os.environ['sourceCodeBucketPath'],\n\
          \                    'Bucket': os.environ['sourceCodeBucketName'],\n   \
          \             },\n                StorageClass = 'STANDARD_IA'\n       \
          \     )\n            \n            if s3_copy_response['ResponseMetadata']['HTTPStatusCode']\
          \ != 200:\n                print(json.dumps(s3_copy_response))\n       \
          \         return respond_to_cfn(event, context, 'FAILED', 'Failed to Copy\
          \ Lambda Code from Specified Bucket')\n            \n            else:\n\
          \                return respond_to_cfn(event, context, 'SUCCESS')\n    \
          \    \n        except boto3_client_error as e:\n            print(e.response)\n\
          \            return respond_to_cfn(event, context, 'FAILED', 'Failed to\
          \ Copy Lambda Code from Specified Bucket')\n            \n    elif event['RequestType']\
          \ in ['Delete']:\n        return respond_to_cfn(event, context, 'SUCCESS')"
      Description: Copies Lambda code from source bucket to regional bucket
      Environment:
        Variables:
          logLevel: info
          sourceCodeBucketName: !Ref 'SourceCodeBucket'
          sourceCodeBucketPath: !Ref 'SourceCodeBucketPath'
          tempCodeBucketName: !Ref 'TempCodeBucket'
      Handler: index.handler
      MemorySize: 128
      Role: !GetAtt 'LambdaCodeManagerRole.Arn'
      Runtime: python3.8
      Timeout: 15
    Type: AWS::Lambda::Function
  LambdaCodeManagerLogGroup:
    Condition: ''
    DeletionPolicy: Delete
    DependsOn:
      - LambdaCodeManagerFunction
    Properties:
      LogGroupName: !Join
        - ''
        - - /aws/lambda/
          - !Ref 'LambdaCodeManagerFunction'
      RetentionInDays: !Ref 'LogRetentionInDays'
    Type: AWS::Logs::LogGroup
  LambdaCodeManagerRole:
    Condition: ''
    DependsOn:
      - TempCodeBucket
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Policies:
        - PolicyDocument:
            Statement:
              - Action:
                  - s3:GetObject
                  - s3:GetObjectAcl
                  - s3:PutObject
                  - s3:PutObjectAcl
                Effect: Allow
                Resource:
                  - !Join
                    - ''
                    - - 'arn:aws:s3:::'
                      - !Ref 'TempCodeBucket'
                      - /lambda-code.zip
                  - !Join
                    - ''
                    - - 'arn:aws:s3:::'
                      - !Ref 'SourceCodeBucket'
                      - /
                      - !Ref 'SourceCodeBucketPath'
          PolicyName: PrimaryPolicy
    Type: AWS::IAM::Role
  MacieScanSubmitterFunction:
    Condition: ''
    DependsOn:
      - MacieScanSubmitterRole
      - FindingsTable
      - ScanStatusTable
      - LambdaCodeCopier
    Properties:
      Code:
        S3Bucket: !Ref 'TempCodeBucket'
        S3Key: lambda-code.zip
      Description: Processes Access Analyzer findings and submits Macie classification
        jobs for each S3 bucket
      Environment:
        Variables:
          aaFindingPeriodOffset: 15
          bucketTagKey: ''
          bucketTagValue: ''
          logLevel: info
          macieScanPeriodOffset: 1440
          tableAaFindings: !Ref 'FindingsTable'
          tableMacieScanStatus: !Ref 'ScanStatusTable'
      Handler: scripts.sda-macie-submit-scan.lambda_handler
      MemorySize: 256
      Role: !GetAtt 'MacieScanSubmitterRole.Arn'
      Runtime: python3.8
      Timeout: 900
    Type: AWS::Lambda::Function
  MacieScanSubmitterLogGroup:
    Condition: ''
    DeletionPolicy: Delete
    DependsOn:
      - MacieScanSubmitterFunction
    Properties:
      LogGroupName: !Join
        - ''
        - - /aws/lambda/
          - !Ref 'MacieScanSubmitterFunction'
      RetentionInDays: !Ref 'LogRetentionInDays'
    Type: AWS::Logs::LogGroup
  MacieScanSubmitterRole:
    Condition: ''
    DependsOn:
      - FindingsTable
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Policies:
        - PolicyDocument:
            Statement:
              - Action:
                  - s3:GetBucketTagging
                Effect: Allow
                Resource:
                  - '*'
              - Action:
                  - dynamodb:Scan
                  - dynamodb:Query
                  - dynamodb:GetItem
                  - dynamodb:PutItem
                  - dynamodb:UpdateItem
                  - dynamodb:BatchGetItem
                  - dynamodb:BatchWriteItem
                  - dynamodb:DescribeTable
                Effect: Allow
                Resource:
                  - !GetAtt 'FindingsTable.Arn'
                  - !GetAtt 'ScanStatusTable.Arn'
              - Action:
                  - macie2:CreateClassificationJob
                Effect: Allow
                Resource:
                  - !Join
                    - ''
                    - - 'arn:aws:macie2:*:'
                      - !Ref 'AWS::AccountId'
                      - :classification-job/*
          PolicyName: PrimaryPolicy
    Type: AWS::IAM::Role
  MacieSession:
    Condition: ActivateMacie
    Properties:
      FindingPublishingFrequency: FIFTEEN_MINUTES
      Status: ENABLED
    Type: AWS::Macie::Session
  MacieStatusCheckerFunction:
    Condition: ''
    DependsOn:
      - MacieStatusCheckerRole
      - LambdaCodeCopier
    Properties:
      Code:
        S3Bucket: !Ref 'TempCodeBucket'
        S3Key: lambda-code.zip
      Description: Checks status of Macie classification jobs
      Environment:
        Variables:
          logLevel: info
      Handler: scripts.sda-macie-check-status.lambda_handler
      MemorySize: 128
      Role: !GetAtt 'MacieStatusCheckerRole.Arn'
      Runtime: python3.8
      Timeout: 300
    Type: AWS::Lambda::Function
  MacieStatusCheckerLogGroup:
    Condition: ''
    DeletionPolicy: Delete
    DependsOn:
      - MacieStatusCheckerFunction
    Properties:
      LogGroupName: !Join
        - ''
        - - /aws/lambda/
          - !Ref 'MacieStatusCheckerFunction'
      RetentionInDays: !Ref 'LogRetentionInDays'
    Type: AWS::Logs::LogGroup
  MacieStatusCheckerRole:
    Condition: ''
    DependsOn: []
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Policies:
        - PolicyDocument:
            Statement:
              - Action:
                  - macie2:GetFindingStatistics
                Effect: Allow
                Resource:
                  - '*'
              - Action:
                  - macie2:DescribeClassificationJob
                Effect: Allow
                Resource:
                  - !Join
                    - ''
                    - - 'arn:aws:macie2:*:'
                      - !Ref 'AWS::AccountId'
                      - :classification-job/*
          PolicyName: PrimaryPolicy
    Type: AWS::IAM::Role
  ScanStatusTable:
    Properties:
      AttributeDefinitions:
        - AttributeName: resourceName
          AttributeType: S
        - AttributeName: createdAt
          AttributeType: S
      BillingMode: PAY_PER_REQUEST
      KeySchema:
        - AttributeName: resourceName
          KeyType: HASH
        - AttributeName: createdAt
          KeyType: RANGE
      SSESpecification:
        SSEEnabled: true
    Type: AWS::DynamoDB::Table
  SecurityFindingsCreatorFunction:
    Condition: ''
    DependsOn:
      - SecurityFindingsCreatorRole
      - LambdaCodeCopier
    Properties:
      Code:
        S3Bucket: !Ref 'TempCodeBucket'
        S3Key: lambda-code.zip
      Description: Creates alerts in Security Hub
      Environment:
        Variables:
          logLevel: info
      Handler: scripts.sda-sh-create-findings.lambda_handler
      MemorySize: 128
      Role: !GetAtt 'SecurityFindingsCreatorRole.Arn'
      Runtime: python3.8
      Timeout: 300
    Type: AWS::Lambda::Function
  SecurityFindingsCreatorLogGroup:
    Condition: ''
    DeletionPolicy: Delete
    DependsOn:
      - SecurityFindingsCreatorFunction
    Properties:
      LogGroupName: !Join
        - ''
        - - /aws/lambda/
          - !Ref 'SecurityFindingsCreatorFunction'
      RetentionInDays: !Ref 'LogRetentionInDays'
    Type: AWS::Logs::LogGroup
  SecurityFindingsCreatorRole:
    Condition: ''
    DependsOn: []
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Policies:
        - PolicyDocument:
            Statement:
              - Action:
                  - dynamodb:Scan
                  - dynamodb:Query
                  - dynamodb:GetItem
                  - dynamodb:DescribeTable
                Effect: Allow
                Resource:
                  - !GetAtt 'FindingsTable.Arn'
              - Action:
                  - securityhub:BatchImportFindings
                Effect: Allow
                Resource:
                  - !Join
                    - ''
                    - - 'arn:aws:securityhub:'
                      - !Ref 'AWS::Region'
                      - ':'
                      - !Ref 'AWS::AccountId'
                      - :product/*/*
          PolicyName: PrimaryPolicy
    Type: AWS::IAM::Role
  SecurityHub:
    Condition: ActivateSecurityHub
    Type: AWS::SecurityHub::Hub
  StateMachine:
    DependsOn:
      - StateMachineRole
      - StateMachineLogGroup
      - MacieScanSubmitterFunction
      - MacieStatusCheckerFunction
      - SecurityFindingsCreatorFunction
    Properties:
      Definition:
        Comment: State machine for Sensitive Data Analyzer functions
        StartAt: sda-macie-submit-scan
        States:
          Done:
            End: true
            Result: Done
            Type: Pass
          IsAnyBucketToScan:
            Choices:
              - Next: Done
                StringEquals: No S3 bucket to process
                Variable: $.respSdaMacieSubmitScan
              - Next: wait_seconds
                Not:
                  StringEquals: No S3 bucket to process
                  Variable: $.respSdaMacieSubmitScan
            Type: Choice
          IsStatusComplete:
            Choices:
              - Next: wait_seconds
                StringEquals: In Progress
                Variable: $.respSdaMacieCheckStatus
              - Next: sda-sh-create-findings
                Not:
                  StringEquals: In Progress
                  Variable: $.respSdaMacieCheckStatus
            Type: Choice
          sda-macie-check-status:
            InputPath: $.respSdaMacieSubmitScan
            Next: IsStatusComplete
            Resource: !Join
              - ''
              - - !GetAtt 'MacieStatusCheckerFunction.Arn'
                - :$LATEST
            ResultPath: $.respSdaMacieCheckStatus
            Type: Task
          sda-macie-submit-scan:
            Next: IsAnyBucketToScan
            Resource: !Join
              - ''
              - - !GetAtt 'MacieScanSubmitterFunction.Arn'
                - :$LATEST
            ResultPath: $.respSdaMacieSubmitScan
            Type: Task
          sda-sh-create-findings:
            InputPath: $
            Next: Done
            Resource: !Join
              - ''
              - - !GetAtt 'SecurityFindingsCreatorFunction.Arn'
                - :$LATEST
            ResultPath: $.respSdaShCreateFindings
            Type: Task
          wait_seconds:
            Next: sda-macie-check-status
            Seconds: 600
            Type: Wait
      LoggingConfiguration:
        Destinations:
          - CloudWatchLogsLogGroup:
              LogGroupArn: !GetAtt 'StateMachineLogGroup.Arn'
        IncludeExecutionData: true
        Level: ERROR
      RoleArn: !GetAtt 'StateMachineRole.Arn'
      StateMachineType: STANDARD
    Type: AWS::StepFunctions::StateMachine
  StateMachineEventBridgeRule:
    DependsOn:
      - StateMachine
    Properties:
      Description: !Join
        - ''
        - - 'Triggers '
          - !Ref 'AWS::StackName'
          - ' Step Function every 15 minutes'
      ScheduleExpression: rate(15 minutes)
      State: ENABLED
      Targets:
        - Arn: !Ref 'StateMachine'
          Id: StateMachine
          RoleArn: !GetAtt 'EventBridgeRole.Arn'
    Type: AWS::Events::Rule
  StateMachineLogGroup:
    DeletionPolicy: Delete
    Properties:
      LogGroupName: !Join
        - ''
        - - /aws/step-functions/
          - !Ref 'AWS::StackName'
          - /state-machine
      RetentionInDays: !Ref 'LogRetentionInDays'
    Type: AWS::Logs::LogGroup
  StateMachineRole:
    DependsOn:
      - StateMachineLogGroup
      - FindingsSaverFunction
      - MacieScanSubmitterFunction
      - MacieStatusCheckerFunction
      - SecurityFindingsCreatorFunction
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - states.amazonaws.com
      Policies:
        - PolicyDocument:
            Statement:
              - Action:
                  - lambda:InvokeFunction
                Effect: Allow
                Resource:
                  - !GetAtt 'FindingsSaverFunction.Arn'
                  - !Join
                    - ''
                    - - !GetAtt 'FindingsSaverFunction.Arn'
                      - :$LATEST
                  - !GetAtt 'MacieScanSubmitterFunction.Arn'
                  - !Join
                    - ''
                    - - !GetAtt 'MacieScanSubmitterFunction.Arn'
                      - :$LATEST
                  - !GetAtt 'MacieStatusCheckerFunction.Arn'
                  - !Join
                    - ''
                    - - !GetAtt 'MacieStatusCheckerFunction.Arn'
                      - :$LATEST
                  - !GetAtt 'SecurityFindingsCreatorFunction.Arn'
                  - !Join
                    - ''
                    - - !GetAtt 'SecurityFindingsCreatorFunction.Arn'
                      - :$LATEST
              - Action:
                  - logs:GetLogEvents
                  - logs:PutLogEvents
                  - logs:GetLogDelivery
                  - logs:CreateLogStream
                  - logs:CreateLogDelivery
                  - logs:PutResourcePolicy
                  - logs:ListLogDeliveries
                  - logs:UpdateLogDelivery
                  - logs:DescribeLogGroups
                  - logs:DeleteLogDelivery
                  - logs:DescribeLogStreams
                  - logs:DescribeResourcePolicies
                Effect: Allow
                Resource:
                  - '*'
                  - !GetAtt 'StateMachineLogGroup.Arn'
                  - !Join
                    - ''
                    - - 'arn:aws:logs:'
                      - !Ref 'AWS::Region'
                      - ':'
                      - !Ref 'AWS::AccountId'
                      - ':log-group:'
                      - !Ref 'StateMachineLogGroup'
                  - !Join
                    - ''
                    - - 'arn:aws:logs:'
                      - !Ref 'AWS::Region'
                      - ':'
                      - !Ref 'AWS::AccountId'
                      - ':log-group:'
                      - !Ref 'StateMachineLogGroup'
                      - :log-stream:*
          PolicyName: primary-policy
    Type: AWS::IAM::Role
  TempCodeBucket:
    DeletionPolicy: Retain
    Type: AWS::S3::Bucket
