AWSTemplateFormatVersion: "2010-09-09"
Metadata:
  License: Apache-2.0
Description: AWS CloudFormation Template to create a user, policy and bucket for SoDA to access
Parameters:
  SoDAUserName:
    Description: Name of the IAM user this template will create to access the bucket defined in "BucketName"
    Type: String
    Default: SoDAS3User
  BucketName:
    Description: Provide a globally unique name for your bucket
    Type: String
  BucketEncryption:
    Description: True sets the bucket default encryption to AES256, False leaves the data unencrypted
    Type: String
    Default: true
    AllowedValues: [true, false]
  RequireS3SSL:
    Description: Would you like to require SSL for s3 operations? True requires SSL and denies all non-SSL s3 traffic to the
      bucket, while false permits s3 operations regardless of SSL use
    Type: String
    Default: true
    AllowedValues: [true, false]
  BucketVersioning:
    Description: Enable bucket object versioning
    Type: String
    Default: Suspended
    AllowedValues: [Enabled, Suspended]
Conditions:
  SSLNotRequired: !Equals [!Ref RequireS3SSL, false]
  SSLRequired: !Equals [!Ref RequireS3SSL, true]
  DisableBucketEncryption: !Equals [!Ref BucketEncryption, false]
  EnableBucketEncryption: !Equals [!Ref BucketEncryption, true]
Resources:
  SoDAUser:
    Type: AWS::IAM::User
    DeletionPolicy: Delete
    Properties:
      UserName: !Ref "SoDAUserName"
  SoDAUserPolicies:
    Type: AWS::IAM::Policy
    DeletionPolicy: Delete
    Properties:
      PolicyName: !Join ["-", [!Ref "SoDAUser", !Ref BucketName, Access]]
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - !If
            - SSLNotRequired
            - Effect: Allow
              Sid: ListObjectsInBucket
              Action:
                - "s3:ListBucket"
                - "s3:*Object"
                - "s3:GetEncryptionConfiguration"
              Resource:
                - !Sub ["arn:aws:s3:::${Bucket}", {Bucket: !Ref BucketName}]
                - !Sub ["arn:aws:s3:::${Bucket}/*", {Bucket: !Ref BucketName}]
            - !Ref 'AWS::NoValue'
          - !If
            - SSLRequired
            - Effect: Deny
              Sid: DenyNonSSL
              Action:
                - "s3:ListBucket"
                - "s3:*Object"
              Resource:
                - !Sub ["arn:aws:s3:::${Bucket}", {Bucket: !Ref BucketName}]
                - !Sub ["arn:aws:s3:::${Bucket}/*", {Bucket: !Ref BucketName}]
              Condition:
                Bool:
                  'aws:SecureTransport': false
            - !Ref 'AWS::NoValue'
          - !If
            - SSLRequired
            - Effect: Allow
              Sid: PermitSSLoperationsSoDA
              Action:
                - "s3:ListBucket"
                - "s3:*Object*"
                - "s3:GetEncryptionConfiguration"
              Resource:
                - !Sub ["arn:aws:s3:::${Bucket}", {Bucket: !Ref BucketName}]
                - !Sub ["arn:aws:s3:::${Bucket}/*", {Bucket: !Ref BucketName}]
              Condition:
                Bool:
                  'aws:SecureTransport': true
            - !Ref 'AWS::NoValue'
      Users: [!Ref "SoDAUser"]
  SoDAKeys:
    Type: AWS::IAM::AccessKey
    DeletionPolicy: Delete
    Properties:
      UserName: !Ref "SoDAUser"
  SoDAS3Bucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Properties:
      BucketName: !Ref BucketName
      VersioningConfiguration:
        Status: !Ref BucketVersioning
    Condition: DisableBucketEncryption
  SoDAS3Bucket:
    Type: "AWS::S3::Bucket"
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Properties:
      BucketName: !Ref BucketName
      VersioningConfiguration:
        Status: !Ref BucketVersioning
      BucketEncryption: !If [EnableBucketEncryption, {ServerSideEncryptionConfiguration: [{ServerSideEncryptionByDefault: {
                SSEAlgorithm: 'AES256'}}]}, !Ref 'AWS::NoValue']
Outputs:
  AccessKey:
    Value: !Ref "SoDAKeys"
    Description: AWSAccessKeyId of new user
  SecretKey:
    Value: !GetAtt [SoDAKeys, SecretAccessKey]
    Description: AWSSecretAccessKey of new user
