######################################################################## # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: MIT-0 ######################################################################## AWSTemplateFormatVersion: 2010-09-09 Description: This template adds the Management account to the AWS Config Aggregator in the Control Tower Audit account. - 'config_management_account' solution in the repo, https://github.com/aws-samples/aws-security-reference-architecture-examples (sra-1ssgnse2s) Metadata: SRA: Version: 1.0 Order: 4 AWS::CloudFormation::Interface: ParameterGroups: - Label: default: General Properties Parameters: - pSRASolutionTagKey - pSRASolutionName - pSRAStagingS3BucketName - pAuditAccountId - pOrganizationId - Label: default: Config Update Aggregator - Lambda Function Properties Parameters: - pConfigUpdateAggregatorLambdaRoleName - pConfigUpdateAggregatorLambdaFunctionName - Label: default: Custom Resource Properties Parameters: - pConfigAggregatorName - pRoleToAssume - Label: default: General Lambda Function Properties Parameters: - pCreateLambdaLogGroup - pLambdaLogGroupRetention - pLambdaLogGroupKmsKey - pLambdaLogLevel ParameterLabels: pAuditAccountId: default: Audit Account ID pConfigAggregatorName: default: Config Aggregator Name pConfigUpdateAggregatorLambdaFunctionName: default: Config Update Aggregator - Lambda Function Name pConfigUpdateAggregatorLambdaRoleName: default: Config Update Aggregator - Lambda Role Name pLambdaLogGroupKmsKey: default: (Optional) Lambda Logs KMS Key pLambdaLogGroupRetention: default: Lambda Log Group Retention pLambdaLogLevel: default: Lambda Log Level pCreateLambdaLogGroup: default: Create Lambda Log Group pOrganizationId: default: AWS Organization ID pRoleToAssume: default: Role to Assume pSRASolutionName: default: SRA Solution Name pSRASolutionTagKey: default: SRA Solution Tag Key pSRAStagingS3BucketName: default: SRA Staging S3 Bucket Name Parameters: pAuditAccountId: AllowedPattern: '^\d{12}$' ConstraintDescription: Must be 12 digits. Description: AWS Account ID of the Control Tower Audit account. Type: String pConfigAggregatorName: AllowedValues: [aws-controltower-GuardrailsComplianceAggregator] Default: aws-controltower-GuardrailsComplianceAggregator Description: AWS Config Aggregator Name in the Control Tower Audit Account Type: String pConfigUpdateAggregatorLambdaFunctionName: AllowedPattern: '^[\w-]{1,64}$' ConstraintDescription: Max 64 alphanumeric characters. Also special characters supported [_, -] Default: sra-config-update-aggregator Description: Lambda function name for updating Config aggregator Type: String pConfigUpdateAggregatorLambdaRoleName: AllowedPattern: '^[\w+=,.@-]{1,64}$' ConstraintDescription: Max 64 alphanumeric characters. Also special characters supported [+, =, ., @, -]. Default: sra-config-update-aggregator-lambda Description: Lambda execution role for updating Config aggregator 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 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' 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 pOrganizationId: AllowedPattern: '^o-[a-z0-9]{10,32}$' ConstraintDescription: Must start with 'o-' followed by from 10 to 32 lowercase letters or digits. (e.g. o-abc1234567) Description: AWS Organizations ID Type: String pRoleToAssume: AllowedValues: [AWSControlTowerExecution] Default: AWSControlTowerExecution Description: Role name to assume for enabling AWS Config Aggregator Type: String pSRASolutionName: AllowedValues: [sra-config-management-account] Default: sra-config-management-account Description: The SRA solution name. The default value is the folder name of the solution Type: String pSRASolutionTagKey: AllowedValues: [sra-solution] Default: sra-solution Description: The SRA solution tag key applied to all resources created by the solution that support tagging. The value is the pSRASolutionName. Type: String pSRAStagingS3BucketName: AllowedPattern: '^(?=^.{3,63}$)(?!.*[.-]{2})(?!.*[--]{2})(?!^(?:(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(?!$)|$)){4}$)(^(([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])\.)*([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])$)' ConstraintDescription: SRA Staging S3 bucket name can include numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen (-). Description: 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: String Conditions: cUseKmsKey: !Not [!Equals [!Ref pLambdaLogGroupKmsKey, '']] cCreateLambdaLogGroup: !Equals [!Ref pCreateLambdaLogGroup, 'true'] cUseGraviton: !Or - !Equals [!Ref 'AWS::Region', ap-northeast-1] - !Equals [!Ref 'AWS::Region', ap-south-1] - !Equals [!Ref 'AWS::Region', ap-southeast-1] - !Equals [!Ref 'AWS::Region', ap-southeast-2] - !Equals [!Ref 'AWS::Region', eu-central-1] - !Equals [!Ref 'AWS::Region', eu-west-1] - !Equals [!Ref 'AWS::Region', eu-west-2] - !Equals [!Ref 'AWS::Region', us-east-1] - !Equals [!Ref 'AWS::Region', us-east-2] - !Equals [!Ref 'AWS::Region', us-west-2] Resources: rConfigUpdateAggregatorLambdaCustomResource: Type: Custom::LambdaCustomResource Version: '1.0' Properties: ServiceToken: !GetAtt rConfigUpdateAggregatorLambdaFunction.Arn AGGREGATOR_NAME: !Ref pConfigAggregatorName AUDIT_ACCOUNT_ID: !Ref pAuditAccountId ROLE_SESSION_NAME: 'ConfigUpdateAggregator' ROLE_TO_ASSUME: !Ref pRoleToAssume rConfigUpdateAggregatorLambdaFunction: Metadata: cfn_nag: rules_to_suppress: - id: W58 reason: Lambda role provides access to CloudWatch Logs - id: W89 reason: Lambda does not need to communicate with VPC resources. - id: W92 reason: Lambda does not need reserved concurrent executions. checkov: skip: - id: CKV_AWS_115 comment: Lambda does not need reserved concurrent executions. - id: CKV_AWS_116 comment: DLQ not needed, as Lambda function only triggered by CloudFormation events. - id: CKV_AWS_117 comment: Lambda does not need to communicate with VPC resources. - id: CKV_AWS_173 comment: Environment variables are not sensitive Type: AWS::Lambda::Function Properties: FunctionName: !Ref pConfigUpdateAggregatorLambdaFunctionName Description: Update Config Aggregator Accounts in the Control Tower audit account. Architectures: !If - cUseGraviton - [arm64] - !Ref AWS::NoValue Handler: app.lambda_handler Role: !GetAtt rConfigUpdateAggregatorLambdaRole.Arn Runtime: python3.9 Timeout: 300 Code: S3Bucket: !Ref pSRAStagingS3BucketName S3Key: !Sub ${pSRASolutionName}/lambda_code/${pSRASolutionName}.zip Environment: Variables: LOG_LEVEL: !Ref pLambdaLogLevel Tags: - Key: !Ref pSRASolutionTagKey Value: !Ref pSRASolutionName rConfigUpdateAggregatorLambdaLogGroup: Condition: cCreateLambdaLogGroup DeletionPolicy: Retain Type: AWS::Logs::LogGroup UpdateReplacePolicy: Retain Properties: LogGroupName: !Sub /aws/lambda/${pConfigUpdateAggregatorLambdaFunctionName} KmsKeyId: !If - cUseKmsKey - !Ref pLambdaLogGroupKmsKey - !Ref AWS::NoValue RetentionInDays: !Ref pLambdaLogGroupRetention rConfigUpdateAggregatorLambdaRole: Type: AWS::IAM::Role Metadata: cfn_nag: rules_to_suppress: - id: W28 reason: Explicit name provided Properties: RoleName: !Ref pConfigUpdateAggregatorLambdaRoleName Description: !Sub Role for '${pConfigUpdateAggregatorLambdaRoleName}' Lambda function AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: sts:AssumeRole Principal: Service: - lambda.amazonaws.com Tags: - Key: !Ref pSRASolutionTagKey Value: !Ref pSRASolutionName Policies: - PolicyName: AssumeRole PolicyDocument: Version: 2012-10-17 Statement: - Sid: AssumeRole Effect: Allow Action: sts:AssumeRole Resource: !Sub arn:${AWS::Partition}:iam::*:role/${pRoleToAssume} Condition: StringEquals: aws:PrincipalOrgId: !Ref pOrganizationId - PolicyName: CloudWatchLogGroup PolicyDocument: Version: 2012-10-17 Statement: - Sid: CloudWatchLogs Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${pConfigUpdateAggregatorLambdaFunctionName}:log-stream:* Outputs: oConfigUpdateAggregatorLambdaFunctionArn: Description: Config Update Aggregator Lambda Function ARN Value: !GetAtt rConfigUpdateAggregatorLambdaFunction.Arn oConfigUpdateAggregatorLambdaLogGroupArn: Condition: cCreateLambdaLogGroup Description: Config Update Aggregator Lambda Log Group ARN Value: !GetAtt rConfigUpdateAggregatorLambdaLogGroup.Arn oConfigUpdateAggregatorLambdaRoleArn: Description: Config Update Aggregator Lambda Role ARN Value: !GetAtt rConfigUpdateAggregatorLambdaRole.Arn