Description: Template for Transfer Family Workflow Blogpost
AWSTemplateFormatVersion: "2010-09-09"
Resources:
  uploadF00D9B70:
    Type: AWS::S3::Bucket
    Properties:
      BucketName:
        Fn::Join:
          - ""
          - - upload-
            - Ref: AWS::AccountId
            - "-"
            - Ref: AWS::Region
            - "-"
            - !Select [0 , !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]]
            - "-"
            - !Select [1 , !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]]
    UpdateReplacePolicy: Retain
    DeletionPolicy: Delete
  application9137406B:
    Type: AWS::S3::Bucket
    Properties:
      BucketName:
        Fn::Join:
          - ""
          - - application-
            - Ref: AWS::AccountId
            - "-"
            - Ref: AWS::Region
            - "-"
            - !Select [0 , !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]]
            - "-"
            - !Select [1 , !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]]
    UpdateReplacePolicy: Retain
    DeletionPolicy: Delete
  quarantineFD1B00D8:
    Type: AWS::S3::Bucket
    Properties:
      BucketName:
        Fn::Join:
          - ""
          - - quarantine-
            - Ref: AWS::AccountId
            - "-"
            - Ref: AWS::Region
            - "-"
            - !Select [0 , !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]]
            - "-"
            - !Select [1 , !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]]
    UpdateReplacePolicy: Retain
    DeletionPolicy: Delete
  NotifyUserPreference4DFB45DE:
    Type: AWS::DynamoDB::Table
    Properties:
      KeySchema:
        - AttributeName: user
          KeyType: HASH
      AttributeDefinitions:
        - AttributeName: user
          AttributeType: S
      ProvisionedThroughput:
        ReadCapacityUnits: 5
        WriteCapacityUnits: 5
    UpdateReplacePolicy: Delete
    DeletionPolicy: Delete
  awscustomuser2CustomResourcePolicyEF1E2B53:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action: dynamodb:PutItem
            Effect: Allow
            Resource: "*"
        Version: "2012-10-17"
      PolicyName: awscustomuser2CustomResourcePolicyEF1E2B53
      Roles:
        - Ref: AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2
  awscustomuser21C6432E4:
    Type: Custom::AWS
    Properties:
      ServiceToken:
        Fn::GetAtt:
          - AWS679f53fac002430cb0da5b7982bd22872D164C4C
          - Arn
      Create:
        Fn::Join:
          - ""
          - - '{"action":"putItem","service":"DynamoDB","parameters":{"TableName":"'
            - Ref: NotifyUserPreference4DFB45DE
            - '","Item":{"user":{"S":"user2"},"endpoint":{"S":"https://endpoint.example.com/receiveNotification"},"protocol":{"S":"https"}},"ConditionExpression":"attribute_not_exists(id)"},"physicalResourceId":{"id":"'
            - Ref: NotifyUserPreference4DFB45DE
            - _initialize"}}
      Update:
        Fn::Join:
          - ""
          - - '{"action":"putItem","service":"DynamoDB","parameters":{"TableName":"'
            - Ref: NotifyUserPreference4DFB45DE
            - '","Item":{"user":{"S":"user2"},"endpoint":{"S":"https://endpoint.example.com/receiveNotification"},"protocol":{"S":"https"}},"ConditionExpression":"attribute_not_exists(id)"},"physicalResourceId":{"id":"'
            - Ref: NotifyUserPreference4DFB45DE
            - _initialize"}}
      InstallLatestAwsSdk: true
    DependsOn:
      - awscustomuser2CustomResourcePolicyEF1E2B53
    UpdateReplacePolicy: Delete
    DeletionPolicy: Delete
  AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
        Version: "2012-10-17"
      ManagedPolicyArns:
        - Fn::Join:
            - ""
            - - "arn:"
              - Ref: AWS::Partition
              - :iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
  AWS679f53fac002430cb0da5b7982bd22872D164C4C:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        S3Bucket:
          Fn::Sub: awsstorageblogresources
        S3Key: SFTPworkflowsblog/4a575666d1c2c6412590d2a56f328e040a81ad1ef59aecee31ae9b393d05f659.zip
      Role:
        Fn::GetAtt:
          - AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2
          - Arn
      Handler: index.handler
      Runtime: nodejs12.x
      Timeout: 120
  awscustomuser1CustomResourcePolicy88CBEE9C:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action: dynamodb:PutItem
            Effect: Allow
            Resource: "*"
        Version: "2012-10-17"
      PolicyName: awscustomuser1CustomResourcePolicy88CBEE9C
      Roles:
        - Ref: AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2
  awscustomuser1B3E3B008:
    Type: Custom::AWS
    Properties:
      ServiceToken:
        Fn::GetAtt:
          - AWS679f53fac002430cb0da5b7982bd22872D164C4C
          - Arn
      Create:
        Fn::Join:
          - ""
          - - '{"action":"putItem","service":"DynamoDB","parameters":{"TableName":"'
            - Ref: NotifyUserPreference4DFB45DE
            - '","Item":{"user":{"S":"user1"},"endpoint":{"S":"john.doe@example.com"},"protocol":{"S":"email"}},"ConditionExpression":"attribute_not_exists(id)"},"physicalResourceId":{"id":"'
            - Ref: NotifyUserPreference4DFB45DE
            - _initialize"}}
      Update:
        Fn::Join:
          - ""
          - - '{"action":"putItem","service":"DynamoDB","parameters":{"TableName":"'
            - Ref: NotifyUserPreference4DFB45DE
            - '","Item":{"user":{"S":"user1"},"endpoint":{"S":"john.doe@example.com"},"protocol":{"S":"email"}},"ConditionExpression":"attribute_not_exists(id)"},"physicalResourceId":{"id":"'
            - Ref: NotifyUserPreference4DFB45DE
            - _initialize"}}
      InstallLatestAwsSdk: true
    DependsOn:
      - awscustomuser1CustomResourcePolicy88CBEE9C
    UpdateReplacePolicy: Delete
    DeletionPolicy: Delete
  awscustomuser3CustomResourcePolicy7E3E5474:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action: dynamodb:PutItem
            Effect: Allow
            Resource: "*"
        Version: "2012-10-17"
      PolicyName: awscustomuser3CustomResourcePolicy7E3E5474
      Roles:
        - Ref: AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2
  awscustomuser3D3F12A80:
    Type: Custom::AWS
    Properties:
      ServiceToken:
        Fn::GetAtt:
          - AWS679f53fac002430cb0da5b7982bd22872D164C4C
          - Arn
      Create:
        Fn::Join:
          - ""
          - - '{"action":"putItem","service":"DynamoDB","parameters":{"TableName":"'
            - Ref: NotifyUserPreference4DFB45DE
            - '","Item":{"user":{"S":"user3"},"endpoint":{"S":"++15550100"},"protocol":{"S":"sms"}},"ConditionExpression":"attribute_not_exists(id)"},"physicalResourceId":{"id":"'
            - Ref: NotifyUserPreference4DFB45DE
            - _initialize"}}
      Update:
        Fn::Join:
          - ""
          - - '{"action":"putItem","service":"DynamoDB","parameters":{"TableName":"'
            - Ref: NotifyUserPreference4DFB45DE
            - '","Item":{"user":{"S":"user3"},"endpoint":{"S":"+15550100"},"protocol":{"S":"sms"}},"ConditionExpression":"attribute_not_exists(id)"},"physicalResourceId":{"id":"'
            - Ref: NotifyUserPreference4DFB45DE
            - _initialize"}}
      InstallLatestAwsSdk: true
    DependsOn:
      - awscustomuser3CustomResourcePolicy7E3E5474
    UpdateReplacePolicy: Delete
    DeletionPolicy: Delete
  NotifyUsersTopic692F066B:
    Type: AWS::SNS::Topic
    Properties:
      DisplayName: Notify Users Topic
      TopicName: 
         Fn::Join:
          - '-'
          - - NotifyUsersTopic
            - !Select [1 , !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]]
  RoleforTransferFamilyUserToAccessS3E32BD729:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: transfer.amazonaws.com
        Version: "2012-10-17"
  TransferFamilyUserS3Access69D2206A:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action: s3:ListBucket
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - uploadF00D9B70
                - Arn
            Sid: AllowListingOfUserFolder
          - Action:
              - s3:PutObject
              - s3:GetObject
              - s3:DeleteObject
              - s3:DeleteObjectVersion
              - s3:GetObjectVersion
            Effect: Allow
            Resource:
              Fn::Join:
                - ""
                - - Fn::GetAtt:
                      - uploadF00D9B70
                      - Arn
                  - /*
            Sid: HomeDirObjectAccess
        Version: "2012-10-17"
      PolicyName: TransferFamilyUserS3Access69D2206A
      Roles:
        - Ref: RoleforTransferFamilyUserToAccessS3E32BD729
  LambdanotiofySenderExecutionRoleA29ECB9F:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
        Version: "2012-10-17"
      ManagedPolicyArns:
        - Fn::Join:
            - ""
            - - "arn:"
              - Ref: AWS::Partition
              - :iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
  AWSLambdaBasicExecutionRolePolicyA9C8849B:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action:
              - dynamodb:GetItem
              - sns:ListSubscriptionsByTopic
              - sns:Publish
              - sns:Subscribe
              - sns:SetSubscriptionAttributes
            Effect: Allow
            Resource:
              - Fn::GetAtt:
                  - NotifyUserPreference4DFB45DE
                  - Arn
              - Ref: NotifyUsersTopic692F066B
          - Action: transfer:SendWorkflowStepState
            Effect: Allow
            Resource: "*"
        Version: "2012-10-17"
      PolicyName: AWSLambdaBasicExecutionRolePolicyA9C8849B
      Roles:
        - Ref: LambdanotiofySenderExecutionRoleA29ECB9F
  NotifySenderB8CCB958:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        S3Bucket:
          Fn::Sub: awsstorageblogresources
        S3Key: SFTPworkflowsblog/e34c681b1b21f4373148556ba1d8652844c75ccdef4540574622c3b72c02d27c.zip
      Role:
        Fn::GetAtt:
          - LambdanotiofySenderExecutionRoleA29ECB9F
          - Arn
      Environment:
        Variables:
          TOPIC_ARN:
            Ref: NotifyUsersTopic692F066B
          TABLE_NAME:
            Ref: NotifyUserPreference4DFB45DE
      Handler: notifySender.lambda_handler
      Runtime: python3.9
  ManagedWorkflowRoleC5FB0BE1:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: transfer.amazonaws.com
        Version: "2012-10-17"
  AWSTransferFamilyManagedWorkFlowPolicy72F617F9:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action:
              - s3:GetObject
              - s3:GetObjectTagging
              - s3:PutObject
              - s3:PutObjectTagging
              - s3:PutObjectVersionTagging
              - s3:DeleteObject
            Effect: Allow
            Resource:
              - Fn::Join:
                  - ""
                  - - Fn::GetAtt:
                        - uploadF00D9B70
                        - Arn
                    - /*
              - Fn::Join:
                  - ""
                  - - Fn::GetAtt:
                        - application9137406B
                        - Arn
                    - /*
              - Fn::Join:
                  - ""
                  - - Fn::GetAtt:
                        - quarantineFD1B00D8
                        - Arn
                    - /*
          - Action: s3:ListBucket
            Effect: Allow
            Resource:
              - Fn::GetAtt:
                  - uploadF00D9B70
                  - Arn
              - Fn::GetAtt:
                  - application9137406B
                  - Arn
              - Fn::GetAtt:
                  - quarantineFD1B00D8
                  - Arn
          - Action: lambda:InvokeFunction
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - NotifySenderB8CCB958
                - Arn
        Version: "2012-10-17"
      PolicyName: AWSTransferFamilyManagedWorkFlowPolicy72F617F9
      Roles:
        - Ref: ManagedWorkflowRoleC5FB0BE1
  MyCfnWorkflow:
    Type: AWS::Transfer::Workflow
    Properties:
      Steps:
        - CustomStepDetails:
            Name: Lambda
            Target:
              Fn::GetAtt:
                - NotifySenderB8CCB958
                - Arn
            TimeoutSeconds: 60
            SourceFileLocation: ${previous.file}
          Type: CUSTOM
        - CopyStepDetails:
            Name: CopyFile
            DestinationFileLocation:
              S3FileLocation:
                Bucket:
                  Ref: application9137406B
                Key: ${transfer:UserName}/
            OverwriteExisting: "TRUE"
            SourceFileLocation: ${previous.file}
          Type: COPY
        - TagStepDetails:
            Name: TagFileNotified
            Tags:
              - Key: Notification
                Value: Successful
              - Key: Copied
                Value: Successful
            SourceFileLocation: ${previous.file}
          Type: TAG
        - DeleteStepDetails:
            Name: DeleteOriginalSourceFile
            SourceFileLocation: ${original.file}
          Type: DELETE
      Description: Workflow for blogpost
      OnExceptionSteps:
        - CopyStepDetails:
            Name: CopyFile
            DestinationFileLocation:
              S3FileLocation:
                Bucket:
                  Ref: quarantineFD1B00D8
                Key: ${transfer:UserName}/
            OverwriteExisting: "TRUE"
            SourceFileLocation: ${previous.file}
          Type: COPY
        - TagStepDetails:
            Name: TagFileFailure
            Tags:
              - Key: Failure
                Value: true
            SourceFileLocation: ${previous.file}
          Type: TAG
        - DeleteStepDetails:
            Name: DeleteOriginalSourceFile
            SourceFileLocation: ${original.file}
          Type: DELETE
Outputs:
  UploadBucketName:
    Description: The name of the upload s3 bucket
    Value:
      Ref: uploadF00D9B70
  ApplicationBucketName:
    Description: The name of the application s3 bucket
    Value:
      Ref: application9137406B
  QuarantineBucketName:
    Description: The name of the quarantine s3 bucket
    Value:
      Ref: quarantineFD1B00D8
  TableName:
    Description: DynamoDB table to set notification preference for users
    Value:
      Ref: NotifyUserPreference4DFB45DE
  transferServerUserS3AccessRole:
    Description: Role to be assigned to each user added to SFTP server
    Value:
      Fn::GetAtt:
        - RoleforTransferFamilyUserToAccessS3E32BD729
        - Arn
  managedWorkflowRole:
    Description: Role to be assigned to the managed workflow when associated with Transfer family server
    Value:
      Fn::GetAtt:
        - ManagedWorkflowRoleC5FB0BE1
        - Arn
  WorkFlowName:
    Description: The id of the workflow to be attached to Transfer Server
    Value:
      Ref: MyCfnWorkflow
