--- # Based on https://github.com/aws-quickstart/quickstart-amazon-aurora-postgresql/blob/main/templates/aurora_postgres.template.yaml AWSTemplateFormatVersion: '2010-09-09' Description: "AWS Aurora Postgres, Do Not Remove Apache License Version 2.0 (qs-1pj6s43e3) July,23,2019" Metadata: QSLint: Exclusions: [W4002, E3012, E1001, E9101, W9006, W9002, W9003, ERDSDBInstancePubliclyAccessible, EIAMPolicyWildcardResource, ERDSStorageEncryptionEnabled] LICENSE: Apache License Version 2.0 AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Network configuration Parameters: - VPCID - Subnet1ID - Subnet2ID - CustomDBSecurityGroup - Label: default: Database configuration Parameters: - DBName - DBAutoMinorVersionUpgrade - DBBackupRetentionPeriod - DBEngineVersion - DBInstanceClass - DBMasterUsername - DBMasterUserPassword - DBPort - DBAccessCIDR - DBMultiAZ - DBAllocatedStorageEncrypted - DBExportLogToCloudwatch - EnableEventSubscription - NotificationList - Label: default: Database tags (optional) Parameters: - EnvironmentStage - Application - ApplicationVersion - ProjectCostCenter - Confidentiality - Compliance ParameterLabels: DBName: default: Database name DBEngineVersion: default: Database Engine Version DBAllocatedStorageEncrypted: default: Database encryption enabled DBExportLogToCloudwatch: default: Export Database Log to Cloudwatch DBAutoMinorVersionUpgrade: default: Database auto minor version upgrade DBBackupRetentionPeriod: default: Database backup retention period DBInstanceClass: default: Database instance class DBMasterUsername: default: Database master username DBMasterUserPassword: default: Database master password DBPort: default: Database port DBAccessCIDR: default: Database connection CIDR DBMultiAZ: default: Multi-AZ deployment Subnet1ID: default: Private subnet 1 ID Subnet2ID: default: Private subne 2 ID VPCID: default: VPC ID CustomDBSecurityGroup: default: Custom security group ID EnableEventSubscription: default: Enable Event Subscription NotificationList: default: SNS notification email EnvironmentStage: default: Environment stage Application: default: Application name ApplicationVersion: default: Application version Compliance: default: Compliance classifier Confidentiality: default: Confidentiality classifier ProjectCostCenter: default: Project cost center Mappings: DBFamilyMap: "9.6.16": "family": "aurora-postgresql9.6" "9.6.17": "family": "aurora-postgresql9.6" "9.6.18": "family": "aurora-postgresql9.6" "9.6.19": "family": "aurora-postgresql9.6" "10.11": "family": "aurora-postgresql10" "10.12": "family": "aurora-postgresql10" "10.13": "family": "aurora-postgresql10" "10.14": "family": "aurora-postgresql10" "11.6": "family": "aurora-postgresql11" "11.7": "family": "aurora-postgresql11" "11.8": "family": "aurora-postgresql11" "11.9": "family": "aurora-postgresql11" "12.4": "family": "aurora-postgresql12" Conditions: IsDBMultiAZ: !Equals - !Ref DBMultiAZ - 'true' EventSubscription: !Equals - !Ref EnableEventSubscription - 'true' DoCreateDatabase: !Not - !Equals - !Ref DBName - '' UseDatabaseEncryption: !Equals - !Ref DBAllocatedStorageEncrypted - "true" EnableDBLogExport: !Equals - !Ref DBExportLogToCloudwatch - "true" CreateSecurityGroup: !Equals - !Ref CustomDBSecurityGroup - '' Outputs: DBName: Description: "Amazon Aurora database name" Value: !Ref DBName DBMasterUsername: Description: "Amazon Aurora database master username" Value: !Ref DBMasterUsername RDSEndPointAddress: Description: "Amazon Aurora write endpoint" Value: !Sub ${AuroraDBCluster.Endpoint.Address} RDSReadEndPointAddress: Description: "Amazon Aurora read endpoint" Value: !Sub ${AuroraDBCluster.ReadEndpoint.Address} RDSEndPointPort: Description: "Amazon Aurora port" Value: !Sub ${AuroraDBCluster.Endpoint.Port} RDSEndPoints: Description: "Full Amazon Aurora write endpoint" Value: !Sub ${AuroraDBCluster.Endpoint.Address}:${AuroraDBCluster.Endpoint.Port}/${DBName} RDSEncryptionKey: Condition: UseDatabaseEncryption Description: The alias of the encryption key created for RDS Value: !Ref EncryptionKeyAlias Parameters: DBAllocatedStorageEncrypted: Default: "true" AllowedValues: - "true" - "false" Description: Whether or not to encrypt the database. Type: String DBExportLogToCloudwatch: Default: "true" AllowedValues: - "true" - "false" Description: Whether or not to export Database logs to Cloudwatch Type: String DBAutoMinorVersionUpgrade: AllowedValues: - true - false Default: true Description: "Select true to set up auto minor version upgrade." Type: String DBBackupRetentionPeriod: Default: "35" Description: "The number of days for which automatic database snapshots are retained." Type: String DBEngineVersion: Description: "Select Database Engine Version. (Warning: Amazon RDS for PostgreSQL 9.6 will reach end of life on January 31st, 2022. Deployments after this date should not be made using this version. If you wish to upgrade to a major version from 9 see: https://confluence.atlassian.com/x/1IRlQQ)" Type: String Default: 11.9 AllowedValues: - 9.6.16 - 9.6.17 - 9.6.18 - 9.6.19 - 10.11 - 10.12 - 10.13 - 10.14 - 11.6 - 11.7 - 11.8 - 11.9 - 12.4 DBInstanceClass: AllowedPattern: "db\\.[a-z0-9]*\\.[a-z0-9]*" ConstraintDescription: "Must select a valid database instance type." Default: db.r5.large Description: "The name of the compute and memory capacity class of the database instance." Type: String DBAccessCIDR: AllowedPattern: "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))$" ConstraintDescription: "CIDR block parameter must be in the form x.x.x.x/x" Description: "Allowed CIDR block for external access (use VPC CIDR)." Type: String Default: 10.0.0.0/16 DBMasterUserPassword: AllowedPattern: >- ^(?=^.{8,255}$)(?=.*[a-z])(?=.*[A-Z])(?=.*\d)((?=.*[^A-Za-z0-9])(?!.*[@/"'])).*$ ConstraintDescription: >- Min 8 chars. Must include 1 uppercase, 1 lowercase, 1 number, 1 (non / @ " ') symbol Description: "The database admin account password." MaxLength: "64" MinLength: "8" NoEcho: "True" Type: String DBMasterUsername: AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*" ConstraintDescription: "Must begin with a letter and contain only alphanumeric characters." Default: pgadmin Description: "The database admin account username." MaxLength: "16" MinLength: "1" Type: String DBPort: Default: 5432 Description: "The port the instance will listen for connections on." Type: Number ConstraintDescription: 'Must be in the range [1115-65535].' MinValue: 1150 MaxValue: 65535 DBMultiAZ: AllowedValues: - "true" - "false" Default: "true" Description: "Specifies if the database instance is a multiple Availability Zone deployment." Type: String DBName: AllowedPattern: "[a-zA-Z0-9]*" Description: "Name of the Amazon Aurora database." MaxLength: "64" MinLength: "0" Default: 'AuroraPostgresDB' Type: String CustomDBSecurityGroup: Description: "ID of the security group (e.g., sg-0234se). One will be created for you if left empty." Type: String Default: '' Subnet1ID: Description: The ID of the private subnet in Availability Zone 1. Type: 'AWS::EC2::Subnet::Id' Subnet2ID: Description: The ID of the private subnet in Availability Zone 2. Type: 'AWS::EC2::Subnet::Id' VPCID: Description: "ID of the VPC you are deploying Aurora into (e.g., vpc-0343606e)." Type: 'AWS::EC2::VPC::Id' Default: '' EnableEventSubscription: AllowedValues: - "true" - "false" Default: "true" Description: "Enables event subscription to Notification List" Type: String NotificationList: Type: String Default: 'db-ops@domain.com' Description: The email notification used to configure an SNS topic for sending CloudWatch alarm and RDS event notifications. AllowedPattern: '^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$' ConstraintDescription: Provide a valid email address. EnvironmentStage: Type: String Description: Designates the environment stage of the associated AWS resource. (Optional) AllowedValues: - dev - test - pre-prod - prod - none Default: none Application: Type: String Default: '' Description: Designates the application of the associated AWS resource. (Optional) ApplicationVersion: Type: String Description: Dsignates the specific version of the application. (Optional) Default: '' ProjectCostCenter: Type: String Default: '' Description: Designates the cost center associated with the project of the given AWS resource. (Optional) Confidentiality: Type: String Default: '' Description: Designates the confidentiality classification of the data that is associated with the resource. (Optional) AllowedValues: - public - private - confidential - pii/phi - '' Compliance: Type: String Default: '' Description: Designates the compliance level for the AWS resource. (Optional) AllowedValues: - hipaa - sox - fips - other - '' Resources: DBSNSTopic: Type: AWS::SNS::Topic Properties: Subscription: - Endpoint: !Ref NotificationList Protocol: email EncryptionKey: Condition: UseDatabaseEncryption DeletionPolicy: Retain UpdateReplacePolicy: Retain Type: AWS::KMS::Key Properties: KeyPolicy: Version: 2012-10-17 Id: !Ref AWS::StackName Statement: - Effect: Allow Principal: AWS: - !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:root" Action: - kms:CancelKeyDeletion - kms:ConnectCustomKeyStore - kms:CreateAlias - kms:CreateCustomKeyStore - kms:CreateGrant - kms:CreateKey - kms:Decrypt - kms:DeleteAlias - kms:DeleteCustomKeyStore - kms:DeleteImportedKeyMaterial - kms:DescribeCustomKeyStores - kms:DescribeKey - kms:DisableKey - kms:DisableKeyRotation - kms:DisconnectCustomKeyStore - kms:EnableKey - kms:EnableKeyRotation - kms:Encrypt - kms:GenerateDataKey - kms:GenerateDataKeyPair - kms:GenerateDataKeyPairWithoutPlaintext - kms:GenerateDataKeyWithoutPlaintext - kms:GenerateRandom - kms:GetKeyPolicy - kms:GetKeyRotationStatus - kms:GetParametersForImport - kms:GetPublicKey - kms:ImportKeyMaterial - kms:ListAliases - kms:ListGrants - kms:ListKeyPolicies - kms:ListKeys - kms:ListResourceTags - kms:ListRetirableGrants - kms:PutKeyPolicy - kms:ReEncryptFrom - kms:ReEncryptTo - kms:ReplicateKey - kms:RetireGrant - kms:RevokeGrant - kms:ScheduleKeyDeletion - kms:Sign - kms:SynchronizeMultiRegionKey - kms:TagResource - kms:UntagResource - kms:UpdateAlias - kms:UpdateCustomKeyStore - kms:UpdateKeyDescription - kms:UpdatePrimaryRegion - kms:Verify Resource: '*' Tags: - Key: Name Value: !Ref AWS::StackName EnableKeyRotation: true EncryptionKeyAlias: Condition: UseDatabaseEncryption Type: AWS::KMS::Alias Properties: AliasName: !Sub "alias/${AWS::StackName}" TargetKeyId: !Ref EncryptionKey AuroraDB1: Properties: AutoMinorVersionUpgrade: !Ref DBAutoMinorVersionUpgrade DBClusterIdentifier: !Ref AuroraDBCluster DBInstanceClass: !Ref DBInstanceClass Engine: aurora-postgresql EngineVersion: !Ref DBEngineVersion DBParameterGroupName: !Ref DBParamGroup PubliclyAccessible: false Tags: - Key: Name Value: !Sub AuroraDB-${AWS::StackName} - Key: EnvironmentStage Value: !Ref EnvironmentStage - Key: Application Value: !Ref Application - Key: ApplicationVersion Value: !Ref ApplicationVersion - Key: ProjectCostCenter Value: !Ref ProjectCostCenter - Key: Confidentiality Value: !Ref Confidentiality - Key: Compliance Value: !Ref Compliance Type: "AWS::RDS::DBInstance" AuroraDB2: Condition: IsDBMultiAZ Properties: AutoMinorVersionUpgrade: !Ref DBAutoMinorVersionUpgrade DBClusterIdentifier: !Ref AuroraDBCluster DBInstanceClass: !Ref DBInstanceClass Engine: aurora-postgresql EngineVersion: !Ref DBEngineVersion DBParameterGroupName: !Ref DBParamGroup PubliclyAccessible: false Tags: - Key: Name Value: !Sub AuroraDB-${AWS::StackName} - Key: EnvironmentStage Value: !Ref EnvironmentStage - Key: Application Value: !Ref Application - Key: ApplicationVersion Value: !Ref ApplicationVersion - Key: ProjectCostCenter Value: !Ref ProjectCostCenter - Key: Confidentiality Value: !Ref Confidentiality - Key: Compliance Value: !Ref Compliance Type: "AWS::RDS::DBInstance" AuroraDB3: Condition: IsDBMultiAZ Properties: AutoMinorVersionUpgrade: !Ref DBAutoMinorVersionUpgrade DBClusterIdentifier: !Ref AuroraDBCluster DBInstanceClass: !Ref DBInstanceClass Engine: aurora-postgresql EngineVersion: !Ref DBEngineVersion DBParameterGroupName: !Ref DBParamGroup PubliclyAccessible: false Tags: - Key: Name Value: !Sub AuroraDB-${AWS::StackName} - Key: EnvironmentStage Value: !Ref EnvironmentStage - Key: Application Value: !Ref Application - Key: ApplicationVersion Value: !Ref ApplicationVersion - Key: ProjectCostCenter Value: !Ref ProjectCostCenter - Key: Confidentiality Value: !Ref Confidentiality - Key: Compliance Value: !Ref Compliance Type: "AWS::RDS::DBInstance" DBParamGroup: Type: AWS::RDS::DBParameterGroup Properties: Description: !Join [ "- ", [ "Aurora PG Database Instance Parameter Group for Cloudformation Stack ", !Ref DBName ] ] Family: !FindInMap [DBFamilyMap, !Ref DBEngineVersion, "family"] Parameters: log_rotation_age: '1440' log_rotation_size: '102400' # The following are recommended to assist security scanning. log_statement: "ddl" log_min_duration_statement: "15000" RDSDBClusterParameterGroup: Type: AWS::RDS::DBClusterParameterGroup Properties: Description: !Join [ "- ", [ "Aurora PG Cluster Parameter Group for Cloudformation Stack ", !Ref DBName ] ] Family: !FindInMap [DBFamilyMap, !Ref DBEngineVersion, "family"] Parameters: rds.force_ssl: 0 # The following are recommended to assist security scanning. log_statement: "ddl" log_min_duration_statement: 15000 AuroraDBCluster: Type: "AWS::RDS::DBCluster" Properties: BackupRetentionPeriod: !Ref DBBackupRetentionPeriod DBClusterParameterGroupName: !Ref RDSDBClusterParameterGroup DBSubnetGroupName: !Ref AuroraDBSubnetGroup EnableCloudwatchLogsExports: - !If [EnableDBLogExport, postgresql, !Ref 'AWS::NoValue'] DatabaseName: !If - DoCreateDatabase - !Ref DBName - !Ref AWS::NoValue Engine: aurora-postgresql EngineVersion: !Ref DBEngineVersion KmsKeyId: !If [UseDatabaseEncryption, !GetAtt EncryptionKey.Arn, !Ref 'AWS::NoValue'] MasterUserPassword: !Ref DBMasterUserPassword MasterUsername: !Ref DBMasterUsername Port: !Ref DBPort StorageEncrypted: !If [UseDatabaseEncryption, !Ref DBAllocatedStorageEncrypted, !Ref 'AWS::NoValue'] Tags: - Key: Name Value: !Sub AuroraDB-${AWS::StackName} - Key: EnvironmentStage Value: !Ref EnvironmentStage - Key: Application Value: !Ref Application - Key: ApplicationVersion Value: !Ref ApplicationVersion - Key: ProjectCostCenter Value: !Ref ProjectCostCenter - Key: Confidentiality Value: !Ref Confidentiality - Key: Compliance Value: !Ref Compliance VpcSecurityGroupIds: !If - CreateSecurityGroup - [!Ref RDSSecurityGroup] - [!Ref CustomDBSecurityGroup] DeletionPolicy: Snapshot UpdateReplacePolicy: Snapshot AuroraDBSubnetGroup: Properties: DBSubnetGroupDescription: "Subnets available for the Amazon Aurora database instance" SubnetIds: - !Ref Subnet1ID - !Ref Subnet2ID Type: "AWS::RDS::DBSubnetGroup" RDSSecurityGroup: Condition: CreateSecurityGroup Properties: GroupDescription: "Allow access to database port" SecurityGroupEgress: - CidrIp: 0.0.0.0/0 FromPort: -1 IpProtocol: '-1' ToPort: -1 SecurityGroupIngress: - CidrIp: !Ref DBAccessCIDR FromPort: !Ref DBPort IpProtocol: tcp ToPort: !Ref DBPort VpcId: !Ref VPCID Tags: - Key: Name Value: !Sub RDSSecurityGroup-${AWS::StackName} Type: "AWS::EC2::SecurityGroup" RDSSecurityGroupIngress: Condition: CreateSecurityGroup Properties: GroupId: !GetAtt 'RDSSecurityGroup.GroupId' IpProtocol: '-1' SourceSecurityGroupId: !Ref RDSSecurityGroup Description: 'Self Reference' Type: 'AWS::EC2::SecurityGroupIngress' CPUUtilizationAlarm1: Type: "AWS::CloudWatch::Alarm" Properties: ActionsEnabled: true AlarmActions: - Ref: DBSNSTopic AlarmDescription: 'CPU_Utilization' Dimensions: - Name: DBInstanceIdentifier Value: Ref: AuroraDB1 MetricName: CPUUtilization Statistic: Maximum Namespace: 'AWS/RDS' Threshold: 80 Unit: Percent ComparisonOperator: 'GreaterThanOrEqualToThreshold' Period: 60 EvaluationPeriods: 5 TreatMissingData: 'notBreaching' CPUUtilizationAlarm2: Condition: IsDBMultiAZ Type: "AWS::CloudWatch::Alarm" Properties: ActionsEnabled: true AlarmActions: - Ref: DBSNSTopic AlarmDescription: 'CPU_Utilization' Dimensions: - Name: DBInstanceIdentifier Value: Ref: AuroraDB2 MetricName: CPUUtilization Statistic: Maximum Namespace: 'AWS/RDS' Threshold: 80 Unit: Percent ComparisonOperator: 'GreaterThanOrEqualToThreshold' Period: 60 EvaluationPeriods: 5 TreatMissingData: 'notBreaching' CPUUtilizationAlarm3: Condition: IsDBMultiAZ Type: "AWS::CloudWatch::Alarm" Properties: ActionsEnabled: true AlarmActions: - Ref: DBSNSTopic AlarmDescription: 'CPU_Utilization' Dimensions: - Name: DBInstanceIdentifier Value: Ref: AuroraDB3 MetricName: CPUUtilization Statistic: Maximum Namespace: 'AWS/RDS' Threshold: 80 Unit: Percent ComparisonOperator: 'GreaterThanOrEqualToThreshold' Period: 60 EvaluationPeriods: 5 TreatMissingData: 'notBreaching' MaxUsedTxIDsAlarm1: Type: "AWS::CloudWatch::Alarm" Properties: ActionsEnabled: true AlarmActions: - Ref: DBSNSTopic AlarmDescription: 'Maximum Used Transaction IDs' Dimensions: - Name: DBInstanceIdentifier Value: Ref: AuroraDB1 MetricName: 'MaximumUsedTransactionIDs' Statistic: Average Namespace: 'AWS/RDS' Threshold: 600000000 Unit: Count ComparisonOperator: 'GreaterThanOrEqualToThreshold' Period: 60 EvaluationPeriods: 5 TreatMissingData: 'notBreaching' MaxUsedTxIDsAlarm2: Condition: IsDBMultiAZ Type: "AWS::CloudWatch::Alarm" Properties: ActionsEnabled: true AlarmActions: - Ref: DBSNSTopic AlarmDescription: 'Maximum Used Transaction IDs' Dimensions: - Name: DBInstanceIdentifier Value: Ref: AuroraDB2 MetricName: 'MaximumUsedTransactionIDs' Statistic: Average Namespace: 'AWS/RDS' Threshold: 600000000 Unit: Count ComparisonOperator: 'GreaterThanOrEqualToThreshold' Period: 60 EvaluationPeriods: 5 TreatMissingData: 'notBreaching' MaxUsedTxIDsAlarm3: Condition: IsDBMultiAZ Type: "AWS::CloudWatch::Alarm" Properties: ActionsEnabled: true AlarmActions: - Ref: DBSNSTopic AlarmDescription: 'Maximum Used Transaction IDs' Dimensions: - Name: DBInstanceIdentifier Value: Ref: AuroraDB3 MetricName: 'MaximumUsedTransactionIDs' Statistic: Average Namespace: 'AWS/RDS' Threshold: 600000000 Unit: Count ComparisonOperator: 'GreaterThanOrEqualToThreshold' Period: 60 EvaluationPeriods: 5 TreatMissingData: 'notBreaching' FreeLocalStorageAlarm1: Type: "AWS::CloudWatch::Alarm" Properties: ActionsEnabled: true AlarmActions: - Ref: DBSNSTopic AlarmDescription: 'Free Local Storage' Dimensions: - Name: DBInstanceIdentifier Value: Ref: AuroraDB1 MetricName: 'FreeLocalStorage' Statistic: Average Namespace: 'AWS/RDS' Threshold: 5368709120 Unit: Bytes ComparisonOperator: 'LessThanOrEqualToThreshold' Period: 60 EvaluationPeriods: 5 TreatMissingData: 'notBreaching' FreeLocalStorageAlarm2: Condition: IsDBMultiAZ Type: "AWS::CloudWatch::Alarm" Properties: ActionsEnabled: true AlarmActions: - Ref: DBSNSTopic AlarmDescription: 'Free Local Storage' Dimensions: - Name: DBInstanceIdentifier Value: Ref: AuroraDB2 MetricName: 'FreeLocalStorage' Statistic: Average Namespace: 'AWS/RDS' Threshold: 5368709120 Unit: Bytes ComparisonOperator: 'LessThanOrEqualToThreshold' Period: 60 EvaluationPeriods: 5 TreatMissingData: 'notBreaching' FreeLocalStorageAlarm3: Condition: IsDBMultiAZ Type: "AWS::CloudWatch::Alarm" Properties: ActionsEnabled: true AlarmActions: - Ref: DBSNSTopic AlarmDescription: 'Free Local Storage' Dimensions: - Name: DBInstanceIdentifier Value: Ref: AuroraDB3 MetricName: 'FreeLocalStorage' Statistic: Average Namespace: 'AWS/RDS' Threshold: 5368709120 Unit: Bytes ComparisonOperator: 'LessThanOrEqualToThreshold' Period: 60 EvaluationPeriods: 5 TreatMissingData: 'notBreaching' DatabaseClusterEventSubscription: Condition: EventSubscription Type: 'AWS::RDS::EventSubscription' Properties: EventCategories: - failover - failure - notification SnsTopicArn: !Ref DBSNSTopic SourceIds: [!Ref AuroraDBCluster] SourceType: 'db-cluster' DatabaseInstanceEventSubscription: Condition: EventSubscription Type: 'AWS::RDS::EventSubscription' Properties: EventCategories: - availability - configuration change - deletion - failover - failure - maintenance - notification - recovery SnsTopicArn: !Ref DBSNSTopic SourceIds: - !Ref AuroraDB1 - !If [IsDBMultiAZ, !Ref AuroraDB2, !Ref "AWS::NoValue"] - !If [IsDBMultiAZ, !Ref AuroraDB3, !Ref "AWS::NoValue"] SourceType: 'db-instance' DBParameterGroupEventSubscription: Condition: EventSubscription Type: 'AWS::RDS::EventSubscription' Properties: EventCategories: - "configuration change" SnsTopicArn: !Ref DBSNSTopic SourceIds: - !Ref DBParamGroup SourceType: 'db-parameter-group'