########################################################################
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0
########################################################################
AWSTemplateFormatVersion: 2010-09-09
Description:
  This template enables an AWS Organizations CloudTrail in the Control Tower Management account with a customer managed KMS key created in the Audit
  account sending the encrypted logs to an S3 bucket created within the Log Archive account. - 'cloudtrail_org' solution in the repo,
  https://github.com/aws-samples/aws-security-reference-architecture-examples (sra-1ssgnse0i)

Metadata:
  SRA:
    Version: 1.2
    Entry: Parameters for deploying solution resolving SSM parameters
    Order: 1
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: General Properties
        Parameters:
          - pSRASolutionName
          - pSRASolutionVersion
          - pSRAStagingS3BucketName
          - pAuditAccountId
          - pLogArchiveAccountId
          - pOrganizationId
      - Label:
          default: CloudTrail Logging & Encryption Properties
        Parameters:
          - pCreateCloudTrailLogGroup
          - pCloudTrailLogGroupRetention
          - pCloudTrailLogGroupKmsKey
          - pOrganizationCloudTrailKeyAlias
          - pBucketNamePrefix
      - Label:
          default: CloudTrail Properties
        Parameters:
          - pCloudTrailName
          - pEnableDataEventsOnly
          - pEnableLambdaDataEvents
          - pEnableS3DataEvents
      - Label:
          default: General Lambda Function Properties
        Parameters:
          - pCreateLambdaLogGroup
          - pLambdaLogGroupRetention
          - pLambdaLogGroupKmsKey
          - pLambdaLogLevel

    ParameterLabels:
      pAuditAccountId:
        default: Audit Account ID
      pBucketNamePrefix:
        default: S3 Log Bucket Name Prefix
      pCloudTrailLogGroupKmsKey:
        default: (Optional) CloudTrail CloudWatch Logs KMS Key
      pCloudTrailLogGroupRetention:
        default: CloudTrail Log Group Retention
      pCloudTrailName:
        default: CloudTrail Name
      pCreateCloudTrailLogGroup:
        default: Create CloudTrail CloudWatch Log Group
      pCreateLambdaLogGroup:
        default: Create Lambda Log Group
      pEnableDataEventsOnly:
        default: Enable Data Events Only
      pEnableLambdaDataEvents:
        default: Enable Lambda Data Events
      pEnableS3DataEvents:
        default: Enable S3 Data Events
      pLambdaLogGroupKmsKey:
        default: (Optional) Lambda Logs KMS Key
      pLambdaLogGroupRetention:
        default: Lambda Log Group Retention
      pLambdaLogLevel:
        default: Lambda Log Level
      pLogArchiveAccountId:
        default: Log Archive Account ID
      pOrganizationCloudTrailKeyAlias:
        default: Organization CloudTrail KMS Key Alias
      pOrganizationId:
        default: Organization ID
      pSRASolutionName:
        default: SRA Solution Name
      pSRASolutionVersion:
        default: SRA Solution Version
      pSRAStagingS3BucketName:
        default: SRA Staging S3 Bucket Name

Parameters:
  pAuditAccountId:
    AllowedPattern: ^([\w.-]{1,900})$|^(\/[\w.-]{1,900})*[\w.-]{1,900}$
    ConstraintDescription:
      Must be alphanumeric or special characters [., _, -]. In addition, the slash character ( / ) used to delineate hierarchies in parameter names.
    Default: /sra/control-tower/audit-account-id
    Description: SSM Parameter for AWS Account ID of the Control Tower Audit account.
    Type: AWS::SSM::Parameter::Value<String>
  pBucketNamePrefix:
    AllowedPattern: ^$|^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$
    ConstraintDescription:
      S3 bucket name can include numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen (-).
    Default: sra-org-trail-logs
    Description: S3 bucket prefix. The account and region will get added to the end. e.g. bucket-prefix-123456789012-us-east-1
    Type: String
  pCloudTrailLogGroupKmsKey:
    AllowedPattern: ^$|^arn:(aws[a-zA-Z-]*){1}:kms:[a-z0-9-]+:\d{12}:key\/[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$
    ConstraintDescription: 'Key ARN example:  arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'
    Default: ''
    Description:
      (Optional) KMS Key ARN to use for encrypting the CloudTrail log group data. If empty, encryption is enabled with CloudWatch Logs managing the
      server-side encryption keys.
    Type: String
  pCloudTrailLogGroupRetention:
    AllowedValues: [1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 3653]
    Default: 400
    Description: Specifies the number of days you want to retain log events
    Type: String
  pCloudTrailName:
    AllowedPattern: ^[A-Za-z0-9][a-zA-Z0-9-\-_.]{2,127}$
    ConstraintDescription:
      Contain only ASCII letters (a-z, A-Z), numbers (0-9), periods (.), underscores (_), or dashes (-) Start with a letter or number, and end with a
      letter or number Be between 3 and 128 characters Have no adjacent periods, underscores or dashes. Names like my-_namespace and my--namespace are
      invalid. Not be in IP address format (for example, 192.168.5.4)
    Default: sra-org-trail
    Description: CloudTrail name
    Type: String
  pCreateCloudTrailLogGroup:
    AllowedValues: ['true', 'false']
    Default: 'true'
    Description:
      Indicates whether a CloudWatch Log Group should be created for the CloudTrail, to allow for setting a Log Retention and/or KMS Key for
      encryption.
    Type: String
  pCreateLambdaLogGroup:
    AllowedValues: ['true', 'false']
    Default: 'false'
    Description:
      Indicates whether a CloudWatch Log Group should be explicitly created for the Lambda function, to allow for setting a Log Retention and/or KMS
      Key for encryption.
    Type: String
  pEnableDataEventsOnly:
    AllowedValues: ['true', 'false']
    Default: 'true'
    Description: Only Enable Cloud Trail Data Events
    Type: String
  pEnableLambdaDataEvents:
    AllowedValues: ['true', 'false']
    Default: 'true'
    Description: Enable Cloud Trail Data Events for all Lambda functions
    Type: String
  pEnableS3DataEvents:
    AllowedValues: ['true', 'false']
    Default: 'true'
    Description: Enable Cloud Trail S3 Data Events for all buckets
    Type: String
  pLambdaLogGroupKmsKey:
    AllowedPattern: ^$|^arn:(aws[a-zA-Z-]*){1}:kms:[a-z0-9-]+:\d{12}:key\/[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$
    ConstraintDescription: 'Key ARN example:  arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'
    Default: ''
    Description:
      (Optional) KMS Key ARN to use for encrypting the Lambda logs data. If empty, encryption is enabled with CloudWatch Logs managing the server-side
      encryption keys.
    Type: String
  pLambdaLogGroupRetention:
    AllowedValues: [1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 3653]
    Default: 14
    Description: Specifies the number of days you want to retain log events
    Type: String
  pLambdaLogLevel:
    AllowedValues: [INFO, ERROR, DEBUG]
    Default: INFO
    Description: Lambda Function Logging Level
    Type: String
  pLogArchiveAccountId:
    AllowedPattern: ^([\w.-]{1,900})$|^(\/[\w.-]{1,900})*[\w.-]{1,900}$
    ConstraintDescription:
      Must be alphanumeric or special characters [., _, -]. In addition, the slash character ( / ) used to delineate hierarchies in parameter names.
    Default: /sra/control-tower/log-archive-account-id
    Description: SSM Parameter for AWS Account ID of the Control Tower Log Archive account.
    Type: AWS::SSM::Parameter::Value<String>
  pOrganizationCloudTrailKeyAlias:
    Default: sra-cloudtrail-org-key
    Description: Organization CloudTrail KMS Key Alias
    Type: String
  pOrganizationId:
    AllowedPattern: '^([\w.-]{1,900})$|^(\/[\w.-]{1,900})*[\w.-]{1,900}$'
    ConstraintDescription:
      Must be alphanumeric or special characters [., _, -]. In addition, the slash character ( / ) used to delineate hierarchies in parameter names.
    Default: /sra/control-tower/organization-id
    Description: SSM Parameter for AWS Organizations ID
    Type: AWS::SSM::Parameter::Value<String>
  pSRASolutionName:
    AllowedValues: [sra-cloudtrail-org]
    Default: sra-cloudtrail-org
    Description: The SRA solution name. The default value is the folder name of the solution
    Type: String
  pSRASolutionVersion:
    AllowedValues: [v1.2]
    Default: v1.2
    Description: The SRA solution version. Used to trigger updates on the nested StackSets.
    Type: String
  pSRAStagingS3BucketName:
    AllowedPattern: '^([\w.-]{1,900})$|^(\/[\w.-]{1,900})*[\w.-]{1,900}$'
    ConstraintDescription:
      Must be alphanumeric or special characters [., _, -]. In addition, the slash character ( / ) used to delineate hierarchies in parameter names.
    Default: /sra/staging-s3-bucket-name
    Description:
      SSM Parameter for SRA Staging S3 bucket name for the artifacts relevant to solution. (e.g., lambda zips, CloudFormation templates) S3 bucket
      name can include numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen (-).
    Type: AWS::SSM::Parameter::Value<String>
Resources:
  rCloudTrailKMSStackSet:
    Type: AWS::CloudFormation::StackSet
    Properties:
      StackSetName: sra-cloudtrail-org-kms
      AdministrationRoleARN: !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/service-role/AWSControlTowerStackSetRole
      CallAs: SELF
      Description: !Sub ${pSRASolutionVersion} - Creates a KMS key within the Audit account for encrypting CloudTrail logs.
      ExecutionRoleName: AWSControlTowerExecution
      ManagedExecution:
        Active: true
      OperationPreferences:
        FailureTolerancePercentage: 0
        MaxConcurrentPercentage: 100
        RegionConcurrencyType: PARALLEL
      PermissionModel: SELF_MANAGED
      StackInstancesGroup:
        - DeploymentTargets:
            Accounts:
              - !Ref pAuditAccountId
          Regions:
            - !Ref AWS::Region
      TemplateURL: !Sub https://${pSRAStagingS3BucketName}.s3.${AWS::Region}.${AWS::URLSuffix}/${pSRASolutionName}/templates/sra-cloudtrail-org-kms.yaml
      Tags:
        - Key: sra-solution
          Value: !Ref pSRASolutionName
      Parameters:
        - ParameterKey: pOrganizationCloudTrailKeyAlias
          ParameterValue: !Ref pOrganizationCloudTrailKeyAlias
        - ParameterKey: pManagementAccountId
          ParameterValue: !Ref AWS::AccountId
        - ParameterKey: pLogArchiveAccountId
          ParameterValue: !Ref pLogArchiveAccountId
        - ParameterKey: pSRASecretsKeyAliasArn
          ParameterValue: !Sub arn:${AWS::Partition}:kms:${AWS::Region}:${pAuditAccountId}:alias/sra-secrets-key

  rCloudTrailS3StackSet:
    DependsOn: rCloudTrailKMSStackSet
    Type: AWS::CloudFormation::StackSet
    Properties:
      StackSetName: sra-cloudtrail-org-bucket
      AdministrationRoleARN: !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/service-role/AWSControlTowerStackSetRole
      CallAs: SELF
      Description: !Sub ${pSRASolutionVersion} - Creates a S3 bucket within the Log Archive account for storing CloudTrail logs.
      ExecutionRoleName: AWSControlTowerExecution
      ManagedExecution:
        Active: true
      OperationPreferences:
        FailureTolerancePercentage: 0
        MaxConcurrentPercentage: 100
        RegionConcurrencyType: PARALLEL
      PermissionModel: SELF_MANAGED
      StackInstancesGroup:
        - DeploymentTargets:
            Accounts:
              - !Ref pLogArchiveAccountId
          Regions:
            - !Ref AWS::Region
      TemplateURL: !Sub https://${pSRAStagingS3BucketName}.s3.${AWS::Region}.${AWS::URLSuffix}/${pSRASolutionName}/templates/sra-cloudtrail-org-bucket.yaml
      Tags:
        - Key: sra-solution
          Value: !Ref pSRASolutionName
      Parameters:
        - ParameterKey: pBucketNamePrefix
          ParameterValue: !Ref pBucketNamePrefix
        - ParameterKey: pCloudTrailName
          ParameterValue: !Ref pCloudTrailName
        - ParameterKey: pManagementAccountId
          ParameterValue: !Ref AWS::AccountId
        - ParameterKey: pOrganizationCloudTrailKMSKeyId
          ParameterValue: !Sub '{{resolve:secretsmanager:arn:${AWS::Partition}:secretsmanager:${AWS::Region}:${pAuditAccountId}:secret:sra/cloudtrail_org_key_arn:SecretString:OrganizationCloudTrailKeyArn:AWSCURRENT}}'
        - ParameterKey: pOrganizationId
          ParameterValue: !Ref pOrganizationId
        - ParameterKey: pSRASecretsKeyAliasArn
          ParameterValue: !Sub arn:${AWS::Partition}:kms:${AWS::Region}:${pAuditAccountId}:alias/sra-secrets-key

  rCloudTrailStack:
    Type: AWS::CloudFormation::Stack
    DeletionPolicy: Delete
    DependsOn: rCloudTrailS3StackSet
    UpdateReplacePolicy: Delete
    Properties:
      TemplateURL: !Sub https://${pSRAStagingS3BucketName}.s3.${AWS::Region}.${AWS::URLSuffix}/${pSRASolutionName}/templates/sra-cloudtrail-org.yaml
      Tags:
        - Key: sra-solution
          Value: !Ref pSRASolutionName
      Parameters:
        pCloudTrailLogGroupKmsKey: !Ref pCloudTrailLogGroupKmsKey
        pCloudTrailLogGroupRetention: !Ref pCloudTrailLogGroupRetention
        pCloudTrailName: !Ref pCloudTrailName
        pCloudTrailS3BucketName: !Sub '{{resolve:secretsmanager:arn:${AWS::Partition}:secretsmanager:${AWS::Region}:${pLogArchiveAccountId}:secret:sra/cloudtrail_org_s3_bucket:SecretString:OrganizationCloudTrailS3Bucket:AWSCURRENT}}'
        pCreateCloudTrailLogGroup: !Ref pCreateCloudTrailLogGroup
        pCreateLambdaLogGroup: !Ref pCreateLambdaLogGroup
        pEnableDataEventsOnly: !Ref pEnableDataEventsOnly
        pEnableLambdaDataEvents: !Ref pEnableLambdaDataEvents
        pEnableS3DataEvents: !Ref pEnableS3DataEvents
        pLambdaLogGroupKmsKey: !Ref pLambdaLogGroupKmsKey
        pLambdaLogGroupRetention: !Ref pLambdaLogGroupRetention
        pLambdaLogLevel: !Ref pLambdaLogLevel
        pOrganizationCloudTrailKMSKeyId: !Sub '{{resolve:secretsmanager:arn:${AWS::Partition}:secretsmanager:${AWS::Region}:${pAuditAccountId}:secret:sra/cloudtrail_org_key_arn:SecretString:OrganizationCloudTrailKeyArn:AWSCURRENT}}'
        pSRAStagingS3BucketName: !Ref pSRAStagingS3BucketName