AWSTemplateFormatVersion: "2010-09-09"
Description: "DDB Table and IAM Managed Policies/Role for DynamoDbEncryption testing"

Parameters:
  TableName:
    Type: String
    Description: Test Table Name
    Default: DynamoDbEncryptionInterceptorTestTable
  TableWithSimpleBeaconIndexName:
    Type: String
    Description: Simple Beacons Test Table Name
    Default: SimpleBeaconTestTable
  TableWithComplexBeaconIndexName:
    Type: String
    Description: Complex Beacons Test Table Name
    Default: ComplexBeaconTestTable
  KeystoreTableName:
    Type: String
    Description: Testing Keystore Table Name
    Default: CiKeystoreTestTable
  BasicTestJavaTableName:
    Type: String
    Description: Table Name for Basic Examples in Java
    Default: DynamoDbEncryptionInterceptorTestTable
  BasicTestDotNetTableName:
    Type: String
    Description: Table Name for Basic Examples in Dotnet
    Default: DynamoDbEncryptionInterceptorTestTableCS
  SearchTestJavaTableName:
    Type: String
    Description: Table Name for Search Examples in Java
    Default: UnitInspectionTestTable
  SearchTestDotnetTableName:
    Type: String
    Description: Table Name for Search Examples in Dotnet
    Default: UnitInspectionTestTableCS
  ProjectName:
    Type: String
    Description: A prefix that will be applied to any names
    Default: DDBEC-Dafny
  # This parameter is no longer used.
  # However removing it causes CloudFormation indigestion
  GitHubRepo:
    Type: String
    Description: GitHub Repo that invokes CI
    Default: aws/aws-database-encryption-sdk-dynamodb

Resources:
  TestTable:
    Type: AWS::DynamoDB::Table
    Properties:
      AttributeDefinitions:
        - AttributeName: "partition_key"
          AttributeType: "S"
        - AttributeName: "sort_key"
          AttributeType: "N"
      KeySchema:
        - AttributeName: "partition_key"
          KeyType: "HASH"
        - AttributeName: "sort_key"
          KeyType: "RANGE"
      ProvisionedThroughput:
        ReadCapacityUnits: "5"
        WriteCapacityUnits: "5"
      TableName: !Ref TableName

  # These tables were manually created but not used in CI
  # If we have to start using them in CI we just have to add
  # them to the policy below.
  # BasicTestJavaTable:
  # BasicTestDotnetTable:
  # SearchTestJavaTable:
  # SearchTestDotnetTable:

  TestTableWithSimpleBeaconIndex:
    Type: AWS::DynamoDB::Table
    Properties:
      AttributeDefinitions:
        - AttributeName: "customer_id"
          AttributeType: "S"
        - AttributeName: "create_time"
          AttributeType: "N"
        - AttributeName: "aws_dbe_b_state"
          AttributeType: "S"
        - AttributeName: "aws_dbe_b_zip"
          AttributeType: "S"
        - AttributeName: "aws_dbe_b_location"
          AttributeType: "S"
        - AttributeName: "aws_dbe_b_stateAndHasSensitiveData"
          AttributeType: "S"
      GlobalSecondaryIndexes:
        - IndexName: "state-zip-index"
          KeySchema:
            - AttributeName: "aws_dbe_b_state"
              KeyType: "HASH"
            - AttributeName: "aws_dbe_b_zip"
              KeyType: "RANGE"
          Projection:
            ProjectionType: ALL
          ProvisionedThroughput:
            ReadCapacityUnits: "5"
            WriteCapacityUnits: "5"
        - IndexName: "location-index"
          KeySchema:
            - AttributeName: "aws_dbe_b_location"
              KeyType: "HASH"
          Projection:
            ProjectionType: ALL
          ProvisionedThroughput:
            ReadCapacityUnits: "5"
            WriteCapacityUnits: "5"
        - IndexName: "stateAndHasSensitiveData-index"
          KeySchema:
            - AttributeName: "aws_dbe_b_stateAndHasSensitiveData"
              KeyType: "HASH"
          Projection:
            ProjectionType: ALL
          ProvisionedThroughput:
            ReadCapacityUnits: "5"
            WriteCapacityUnits: "5"
      KeySchema:
        - AttributeName: "customer_id"
          KeyType: "HASH"
        - AttributeName: "create_time"
          KeyType: "RANGE"
      ProvisionedThroughput:
        ReadCapacityUnits: "5"
        WriteCapacityUnits: "5"
      TableName: !Ref TableWithSimpleBeaconIndexName

  # This schema is modeled off of
  # https://github.com/aws-samples/searchable-encryption-dynamodb-howto/blob/main/BeaconPOC/Demo.md
  # Under "Changes for Encryption".
  TestTableWithComplexBeaconIndex:
    Type: AWS::DynamoDB::Table
    Properties:
      AttributeDefinitions:
        - AttributeName: "partition_key"
          AttributeType: "S"
        - AttributeName: "aws_dbe_b_PK"
          AttributeType: "S"
        - AttributeName: "aws_dbe_b_SK"
          AttributeType: "S"
        - AttributeName: "aws_dbe_b_PK1"
          AttributeType: "S"
        - AttributeName: "aws_dbe_b_SK1"
          AttributeType: "S"
        - AttributeName: "aws_dbe_b_PK2"
          AttributeType: "S"
        - AttributeName: "aws_dbe_b_PK3"
          AttributeType: "S"
        - AttributeName: "aws_dbe_b_SK3"
          AttributeType: "S"
      GlobalSecondaryIndexes:
        - IndexName: "GSI-0"
          KeySchema:
            - AttributeName: "aws_dbe_b_PK"
              KeyType: "HASH"
            - AttributeName: "aws_dbe_b_SK"
              KeyType: "RANGE"
          Projection:
            ProjectionType: ALL
          ProvisionedThroughput:
            ReadCapacityUnits: "5"
            WriteCapacityUnits: "5"
        - IndexName: "GSI-1"
          KeySchema:
            - AttributeName: "aws_dbe_b_PK1"
              KeyType: "HASH"
            - AttributeName: "aws_dbe_b_SK1"
              KeyType: "RANGE"
          Projection:
            ProjectionType: ALL
          ProvisionedThroughput:
            ReadCapacityUnits: "5"
            WriteCapacityUnits: "5"
        - IndexName: "GSI-2"
          KeySchema:
            - AttributeName: "aws_dbe_b_PK2"
              KeyType: "HASH"
          Projection:
            ProjectionType: ALL
          ProvisionedThroughput:
            ReadCapacityUnits: "5"
            WriteCapacityUnits: "5"
        - IndexName: "GSI-3"
          KeySchema:
            - AttributeName: "aws_dbe_b_PK3"
              KeyType: "HASH"
            - AttributeName: "aws_dbe_b_SK3"
              KeyType: "RANGE"
          Projection:
            ProjectionType: ALL
          ProvisionedThroughput:
            ReadCapacityUnits: "5"
            WriteCapacityUnits: "5"
      KeySchema:
        - AttributeName: "partition_key"
          KeyType: "HASH"
      ProvisionedThroughput:
        ReadCapacityUnits: "5"
        WriteCapacityUnits: "5"
      TableName: !Ref TableWithComplexBeaconIndexName

  TestKeystoreTable:
    Type: AWS::DynamoDB::Table
    Properties:
      AttributeDefinitions:
        - AttributeName: "branch-key-id"
          AttributeType: "S"
        - AttributeName: "status"
          AttributeType: "S"
        - AttributeName: "type"
          AttributeType: "S"
      GlobalSecondaryIndexes:
        - IndexName: "Active-Keys"
          KeySchema:
            - AttributeName: "branch-key-id"
              KeyType: "HASH"
            - AttributeName: "status"
              KeyType: "RANGE"
          Projection:
            ProjectionType: ALL
          ProvisionedThroughput:
            ReadCapacityUnits: "5"
            WriteCapacityUnits: "5"
      KeySchema:
        - AttributeName: "branch-key-id"
          KeyType: "HASH"
        - AttributeName: "type"
          KeyType: "RANGE"
      ProvisionedThroughput:
        ReadCapacityUnits: "5"
        WriteCapacityUnits: "5"
      TableName: !Ref KeystoreTableName

  # This policy SHOULD be given to:
  #  - aws/aws-database-encryption-sdk-dynamodb-java
  #  - ToolsDevelopment
  DDBUsage:
    Type: "AWS::IAM::ManagedPolicy"
    Properties:
      Description: "Allow Read, Write, and Delete of Items in Test Tables"
      ManagedPolicyName: !Sub "${ProjectName}-DDB-ReadWriteDelete-Policy-${AWS::Region}"
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action:
              - dynamodb:BatchGetItem
              - dynamodb:BatchWriteItem
              - dynamodb:ConditionCheckItem
              - dynamodb:PutItem
              - dynamodb:DeleteItem
              - dynamodb:GetItem
              - dynamodb:Scan
              - dynamodb:Query
              - dynamodb:UpdateItem
            Resource:
              - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${TableName}"
              - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${TableName}/index/*"
              - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${TableWithSimpleBeaconIndexName}"
              - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${TableWithSimpleBeaconIndexName}/index/*"
              - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${TableWithComplexBeaconIndexName}"
              - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${TableWithComplexBeaconIndexName}/index/*"
              - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${KeystoreTableName}"
              - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${KeystoreTableName}/index/*"
              - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${BasicTestJavaTableName}"
              - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${BasicTestDotNetTableName}"
              - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${SearchTestJavaTableName}"
              - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${SearchTestJavaTableName}/index/*"
              - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${SearchTestDotnetTableName}"
              - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${SearchTestDotnetTableName}/index/*"

  KMSUsage:
    Type: "AWS::IAM::ManagedPolicy"
    Properties:
      ManagedPolicyName: !Sub "${ProjectName}-KMS-${AWS::Region}"
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action:
              - kms:Encrypt
              - kms:Decrypt
              - kms:GenerateDataKey
              - kms:GetPublicKey
            Resource:
              - !Sub "arn:aws:kms:*:658956600833:key/*"
              - !Sub "arn:aws:kms:*:658956600833:alias/*"

  KMSUsageOnlyUsEast1Keys:
    Type: "AWS::IAM::ManagedPolicy"
    Properties:
      ManagedPolicyName: !Sub "${ProjectName}-KMS-only-us-east-1"
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action:
              - kms:Encrypt
              - kms:Decrypt
              - kms:GenerateDataKey
              - kms:GetPublicKey
            Resource:
              - !Sub "arn:aws:kms:us-east-1:658956600833:key/*"
              - !Sub "arn:aws:kms:us-east-1:658956600833:alias/*"

  KMSUsageOnlyEuWest1Keys:
    Type: "AWS::IAM::ManagedPolicy"
    Properties:
      ManagedPolicyName: !Sub "${ProjectName}-KMS-only-eu-west-1"
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action:
              - kms:Encrypt
              - kms:Decrypt
              - kms:GenerateDataKey
              - kms:GetPublicKey
            Resource:
              - !Sub "arn:aws:kms:eu-west-1:658956600833:key/*"
              - !Sub "arn:aws:kms:eu-west-1:658956600833:alias/*"

  GitHubCIRole:
    Type: "AWS::IAM::Role"
    Properties:
      RoleName: !Sub "GitHub-CI-${ProjectName}-Role-${AWS::Region}"
      Description: "Access DDB, KMS, & CA Resources for CI from GitHub"
      ManagedPolicyArns:
        - Fn::ImportValue: "Polymorph-CA-GitHubCAReadPolicyArn"
        - "arn:aws:iam::370957321024:policy/ESDK-Dafny-DDB-ReadWriteDelete-us-west-2"
        - "arn:aws:iam::370957321024:policy/Hierarchical-GitHub-KMS-Key-Policy"
        - "arn:aws:iam::370957321024:policy/Github-ECDH-KMS"
        - !Ref KMSUsage
        - !Ref DDBUsage
      AssumeRolePolicyDocument: !Sub |
        {
          "Version": "2012-10-17",   
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": { "Federated": "arn:aws:iam::${AWS::AccountId}:oidc-provider/token.actions.githubusercontent.com" },
              "Action": "sts:AssumeRoleWithWebIdentity",
              "Condition": {
                "StringEquals": {
                  "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
                },
                "StringLike": {
                  "token.actions.githubusercontent.com:sub": [
                    "repo:aws/aws-database-encryption-sdk-dynamodb:*",
                    "repo:aws/private-aws-database-encryption-sdk-dynamodb-java-staging:*"
                  ]
                }
              }
            },
            {
              "Effect": "Allow",
              "Principal": {
                "AWS": "*"
              },
              "Action": "sts:AssumeRole",
              "Condition": {
                "StringEquals": {
                  "aws:PrincipalArn": [
                    "arn:aws:iam::587316601012:role/service-role/codebuild-AWS-DBESDK-DDB-Java-service-role-release",
                    "arn:aws:iam::587316601012:role/service-role/codebuild-AWS-DBESDK-DotNet-service-role-release",
                    "arn:aws:iam::${AWS::AccountId}:role/ToolsDevelopment"
                  ]
                }
              }
            }
          ]
        }

  GithubCIRoleOnlyUsEast1Keys:
    Type: "AWS::IAM::Role"
    Properties:
      RoleName: !Sub "GitHub-CI-${ProjectName}-Role-only-us-east-1-KMS-keys"
      Description: "Access DDB, KMS, & CA Resources for CI from GitHub. Only grants access to use keys in us-east-1 region. Created for use by CI while executing Custom Client Supplier Example."
      ManagedPolicyArns:
        - Fn::ImportValue: "Polymorph-CA-GitHubCAReadPolicyArn"
        - "arn:aws:iam::370957321024:policy/ESDK-Dafny-DDB-ReadWriteDelete-us-west-2"
        - "arn:aws:iam::370957321024:policy/Hierarchical-GitHub-KMS-Key-Policy"
        - !Ref KMSUsageOnlyUsEast1Keys
        - !Ref DDBUsage
      AssumeRolePolicyDocument: !Sub |
        {
          "Version": "2012-10-17",   
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": { "AWS": "arn:aws:iam::${AWS::AccountId}:role/GitHub-CI-DDBEC-Dafny-Role-us-west-2" },
              "Action": "sts:AssumeRole"
            },
            {
              "Effect": "Allow",
              "Principal": { "Federated": "arn:aws:iam::${AWS::AccountId}:oidc-provider/token.actions.githubusercontent.com" },
              "Action": "sts:AssumeRoleWithWebIdentity",
              "Condition": {
                "StringEquals": {
                  "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
                },
                "StringLike": {
                  "token.actions.githubusercontent.com:sub": [
                    "repo:aws/aws-database-encryption-sdk-dynamodb:*",
                    "repo:aws/private-aws-database-encryption-sdk-dynamodb-java-staging:*"
                  ]
                }
              }
            },
            {
              "Effect": "Allow",
              "Principal": {
                "AWS": "*"
              },
              "Action": "sts:AssumeRole",
              "Condition": {
                "StringEquals": {
                  "aws:PrincipalArn": [
                    "arn:aws:iam::587316601012:role/service-role/codebuild-AWS-DBESDK-DDB-Java-service-role-release",
                    "arn:aws:iam::587316601012:role/service-role/codebuild-AWS-DBESDK-DotNet-service-role-release",
                    "arn:aws:iam::${AWS::AccountId}:role/ToolsDevelopment"
                  ]
                }
              }
            }
          ]
        }

  GithubCIRoleOnlyEuWest1Keys:
    Type: "AWS::IAM::Role"
    Properties:
      RoleName: !Sub "GitHub-CI-${ProjectName}-Role-only-eu-west-1-KMS-keys"
      Description: "Access DDB, KMS, & CA Resources for CI from GitHub. Only grants access to use keys in eu-west-1 region. Created for use by CI while executing Custom Client Supplier Example."
      ManagedPolicyArns:
        - Fn::ImportValue: "Polymorph-CA-GitHubCAReadPolicyArn"
        - "arn:aws:iam::370957321024:policy/ESDK-Dafny-DDB-ReadWriteDelete-us-west-2"
        - "arn:aws:iam::370957321024:policy/Hierarchical-GitHub-KMS-Key-Policy"
        - !Ref KMSUsageOnlyEuWest1Keys
        - !Ref DDBUsage
      AssumeRolePolicyDocument: !Sub |
        {
          "Version": "2012-10-17",   
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": { "AWS": "arn:aws:iam::${AWS::AccountId}:role/GitHub-CI-DDBEC-Dafny-Role-us-west-2" },
              "Action": "sts:AssumeRole"
            },
            {
              "Effect": "Allow",
              "Principal": { "Federated": "arn:aws:iam::${AWS::AccountId}:oidc-provider/token.actions.githubusercontent.com" },
              "Action": "sts:AssumeRoleWithWebIdentity",
              "Condition": {
                "StringEquals": {
                  "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
                },
                "StringLike": {
                  "token.actions.githubusercontent.com:sub": [
                    "repo:aws/aws-database-encryption-sdk-dynamodb:*",
                    "repo:aws/private-aws-database-encryption-sdk-dynamodb-java-staging:*"
                  ]
                }
              }
            },
            {
              "Effect": "Allow",
              "Principal": {
                "AWS": "*"
              },
              "Action": "sts:AssumeRole",
              "Condition": {
                "StringEquals": {
                  "aws:PrincipalArn": [
                    "arn:aws:iam::587316601012:role/service-role/codebuild-AWS-DBESDK-DDB-Java-service-role-release",
                    "arn:aws:iam::587316601012:role/service-role/codebuild-AWS-DBESDK-DotNet-service-role-release",
                    "arn:aws:iam::${AWS::AccountId}:role/ToolsDevelopment"
                  ]
                }
              }
            }
          ]
        }
