Hi I’m getting an error:
Transform AWS::Serverless-2016-10-31 failed with: Invalid Serverless Application Specification document. Number of errors found: 1. Structure of the SAM template is invalid. All 'Resources' must be Objects. If you're using YAML, this may be an indentation issue.
When trying to deploy a cloudformation template that creates an aurora database within an exisiting vpc with a password roatation lambda.
When running the cloudofmration, there is an error that indicates that there is an issue with the Serverless application indentation.
This is the template:
AWSTemplateFormatVersion: "2010-09-09"
Transform:
- AWS::Serverless-2016-10-31
- AWS::LanguageExtensions
Description: Deploys an Aurora cluster into an existing VPC
Parameters:
EnvironmentName:
Description: An environment name that will be prefixed.
Type: String
Default: dev
AllowedValues:
- dev
- test
- staging
- prod
DBClusterType:
Description: Aurora Cluster Type
Type: String
Default: AuroraClusterPostgreSQL
AllowedValues:
- AuroraClusterPostgreSQL
PropertiesUrl:
Type: String
Description: Name of bucket in which the environment-specific constants are stored
Default: s3://devops-deploy-us-east-1/services/test.yaml
MapName:
Type: String
Description: Configuration MapName.
Default: Properties
Mappings:
"Fn::Transform":
Name: "AWS::Include"
Parameters:
Location: !Ref PropertiesUrl
Conditions:
CreateSecondDBInstance: !Equals [!FindInMap [ !Ref MapName, !Ref DBClusterType, TwoInstancesInCluster ], 'true']
Resources:
# ################################################ Security Group ##########################################
DBSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Join
- "-"
- - !Ref EnvironmentName
- !FindInMap [ !Ref MapName, !Ref DBClusterType, ClusterName ]
- !FindInMap [ !Ref MapName, !Ref DBClusterType, DBEngine ]
- "sg"
GroupDescription: !Ref 'AWS::StackName'
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: !FindInMap [ !Ref MapName, !Ref DBClusterType, DBPort ]
ToPort: !FindInMap [ !Ref MapName, !Ref DBClusterType, DBPort ]
CidrIp: !Sub '{{resolve:ssm:/${EnvironmentName}/aws/vpc/cidr:1}}'
Description: 'VPC Access to DataBase'
- IpProtocol: tcp
FromPort: !FindInMap [ !Ref MapName, !Ref DBClusterType, DBPort ]
ToPort: !FindInMap [ !Ref MapName, !Ref DBClusterType, DBPort ]
SourceSecurityGroupId: !Sub '{{resolve:ssm:/${EnvironmentName}/aws/eks/cluster-nodes-security-group-id:1}}'
Description: Allows access to Aurora from EKS Node Groups
- IpProtocol: tcp
FromPort: !FindInMap [ !Ref MapName, !Ref DBClusterType, DBPort ]
ToPort: !FindInMap [ !Ref MapName, !Ref DBClusterType, DBPort ]
CidrIp: !Sub '{{resolve:ssm:/${EnvironmentName}/aws/office-network-cidr:1}}'
Description: Allows access to Aurora
- IpProtocol: tcp
FromPort: !FindInMap [ !Ref MapName, !Ref DBClusterType, DBPort ]
ToPort: !FindInMap [ !Ref MapName, !Ref DBClusterType, DBPort ]
CidrIp: !Sub '{{resolve:ssm:/${EnvironmentName}/aws/vpn-network-cidr:1}}'
Description: Allows access to Aurora from VPN CIDR
SecurityGroupEgress:
- CidrIp: 0.0.0.0/0
FromPort: -1
ToPort: -1
IpProtocol: '-1'
VpcId: !Sub '{{resolve:ssm:/${EnvironmentName}/aws/vpc/id:1}}'
Tags:
- Key: Name
Value: !Join
- "-"
- - !Ref EnvironmentName
- !FindInMap [ !Ref MapName, !Ref DBClusterType, ClusterName ]
- !FindInMap [ !Ref MapName, !Ref DBClusterType, DBEngine ]
- "sg"
- Key: Product
Value: !FindInMap [ !Ref MapName, Tags, Product ]
- Key: Service
Value: !FindInMap [ !Ref MapName, Tags, Service ]
- Key: Environment
Value: !Ref EnvironmentName
DBSecurityGroupIngress:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt DBSecurityGroup.GroupId
IpProtocol: tcp
FromPort: 0
ToPort: 65535
SourceSecurityGroupId: !Ref DBSecurityGroup
Description: 'Self Reference'
# ###################################################### Subnet Group ##########################################
DBSubnetGroup:
Type: AWS::RDS::DBSubnetGroup
Properties:
DBSubnetGroupName: !Join
- "-"
- - !Ref EnvironmentName
- !FindInMap [ !Ref MapName, !Ref DBClusterType, ClusterName ]
- !FindInMap [ !Ref MapName, !Ref DBClusterType, DBEngine ]
- "subnet-group"
DBSubnetGroupDescription: "Database Subnet Group"
SubnetIds:
- !Sub '{{resolve:ssm:/${EnvironmentName}/aws/vpc/private-db-subnet-a-id:1}}'
- !Sub '{{resolve:ssm:/${EnvironmentName}/aws/vpc/private-db-subnet-b-id:1}}'
- !Sub '{{resolve:ssm:/${EnvironmentName}/aws/vpc/private-db-subnet-c-id:1}}'
Tags:
- Key: Product
Value: !FindInMap [ !Ref MapName, Tags, Product ]
- Key: Service
Value: !FindInMap [ !Ref MapName, Tags, Service ]
- Key: Environment
Value: !Ref EnvironmentName
################################################# Aurora #############################################
DBCluster:
Type: AWS::RDS::DBCluster
DeletionPolicy: Snapshot
UpdateReplacePolicy: Snapshot
Properties:
Engine: !FindInMap [ !Ref MapName, !Ref DBClusterType, DBEngine ]
EngineVersion: !FindInMap [ !Ref MapName, !Ref DBClusterType, DBEngineVersion ]
DatabaseName: !FindInMap [ !Ref MapName, !Ref DBClusterType, DatabaseName ]
MasterUsername: !Join ['', ['{', '{', 'resolve:secretsmanager:', !Ref DBMasterSecret, ':SecretString:username', '}', '}' ]]
MasterUserPassword: !Join ['', ['{' ,'{', 'resolve:secretsmanager:', !Ref DBMasterSecret, ':SecretString:password', '}', '}' ]]
Port: !FindInMap [ !Ref MapName, !Ref DBClusterType, DBPort ]
DBClusterIdentifier: !Join
- "-"
- - !Ref EnvironmentName
- !FindInMap [ !Ref MapName, !Ref DBClusterType, ClusterName ]
- !FindInMap [ !Ref MapName, !Ref DBClusterType, DBEngine ]
# DBClusterParameterGroupName: !Ref DBClusterParameterGroup
#DBClusterParameterGroupName: !FindInMap [ !Ref MapName, !Ref DBClusterType, DBClusterParameterGroupName ]
BackupRetentionPeriod: !FindInMap [ !Ref MapName, !Ref DBClusterType, BackupRetentionPeriod]
PreferredBackupWindow: !FindInMap [ !Ref MapName, !Ref DBClusterType, PreferredBackupWindow ]
PreferredMaintenanceWindow: !FindInMap [ !Ref MapName, !Ref DBClusterType, PreferredMaintenanceWindow ]
DeletionProtection: false
StorageEncrypted: true
EnableHttpEndpoint: true
DBSubnetGroupName: !Ref DBSubnetGroup
VpcSecurityGroupIds:
- !Ref DBSecurityGroup
EnableCloudwatchLogsExports:
- audit
- error
- general
Tags:
- Key: Product
Value: !FindInMap [ !Ref MapName, Tags, Product ]
- Key: Service
Value: !FindInMap [ !Ref MapName, Tags, Service ]
- Key: Environment
Value: !Ref EnvironmentName
DBFirstInstance:
Type: AWS::RDS::DBInstance
Properties:
# CopyTagsToSnapshot: true
AvailabilityZone: !Select [ '0', { Fn::GetAZs: !Ref 'AWS::Region' } ]
DBInstanceClass: !FindInMap [ !Ref MapName, !Ref DBClusterType, DBInstanceClass ]
DBClusterIdentifier: !Ref DBCluster
DBInstanceIdentifier: !Join [ '-', [ !Ref DBCluster, !Select [ '0', { Fn::GetAZs: !Ref 'AWS::Region' } ]]]
Engine: !FindInMap [ !Ref MapName, !Ref DBClusterType, DBEngine ]
EngineVersion: !FindInMap [ !Ref MapName, !Ref DBClusterType, DBEngineVersion ]
AutoMinorVersionUpgrade: !FindInMap [ !Ref MapName, !Ref DBClusterType, AutoMinorVersionUpgrade ]
DBSubnetGroupName: !Ref DBSubnetGroup
PubliclyAccessible: false
EnablePerformanceInsights: false
#PerformanceInsightsRetentionPeriod: 7
Tags:
- Key: Product
Value: !FindInMap [ !Ref MapName, Tags, Product ]
- Key: Service
Value: !FindInMap [ !Ref MapName, Tags, Service ]
- Key: Environment
Value: !Ref EnvironmentName
DBSecondInstance:
Type: AWS::RDS::DBInstance
Condition: CreateSecondDBInstance
DependsOn:
- DBFirstInstance
Properties:
# CopyTagsToSnapshot: true
AvailabilityZone: !Select [ '1', { Fn::GetAZs: !Ref 'AWS::Region' } ]
DBInstanceClass: !FindInMap [ !Ref MapName, !Ref DBClusterType, DBInstanceClass ]
DBClusterIdentifier: !Ref DBCluster
DBInstanceIdentifier: !Join ['-', [ !Ref DBCluster, !Select [ '1', { Fn::GetAZs: !Ref 'AWS::Region' } ]]]
Engine: !FindInMap [ !Ref MapName, !Ref DBClusterType, DBEngine ]
EngineVersion: !FindInMap [ !Ref MapName, !Ref DBClusterType, DBEngineVersion ]
AutoMinorVersionUpgrade: !FindInMap [ !Ref MapName, !Ref DBClusterType, AutoMinorVersionUpgrade ]
DBSubnetGroupName: !Ref DBSubnetGroup
PubliclyAccessible: false
EnablePerformanceInsights: false
#PerformanceInsightsRetentionPeriod: 7
Tags:
- Key: Product
Value: !FindInMap [ !Ref MapName, Tags, Product ]
- Key: Service
Value: !FindInMap [ !Ref MapName, Tags, Service ]
- Key: Environment
Value: !Ref EnvironmentName
# ################################# Cluster Parameter Group ##########################################
# DBClusterParameterGroup:
# Type: AWS::RDS::DBClusterParameterGroup
# Properties:
# Description: DB Cluster Parameter Group
# Family: !FindInMap [ !Ref MapName, !Ref DBClusterType, DBFamily ]
# Parameters:
# time_zone: UTC
# Tags:
# - Key: Name
# Value: !Join
# - "-"
# - - !Sub ${EnvironmentName}
# - !FindInMap [ !Ref MapName, !Ref DBClusterType, ClusterName ]
# - !FindInMap [ !Ref MapName, !Ref DBClusterType, DBEngine ]
# - "parameter-group"
# - Key: Product
# Value: !FindInMap [ !Ref MapName, Tags, Product ]
# - Key: Service
# Value: !FindInMap [ !Ref MapName, Tags, Service ]
# - Key: Environment
# Value: !Ref EnvironmentName
# ###################################################### Route 53 ##########################################
# DBEndpointRoute53:
# Type: AWS::Route53::RecordSet
# Properties:
# HostedZoneName: !Join
# - "."
# - - !Ref EnvironmentName
# - !Sub '{{resolve:ssm:/${EnvironmentName}/aws/route53/internal-domain-private-hosted-zone-name:1}}'
# - ""
# Comment: Services DB DataBase DNS name.
# Name: !Join
# - "."
# - - !Ref DBCluster
# - !Ref EnvironmentName
# - !Sub '{{resolve:ssm:/${EnvironmentName}/aws/route53/internal-domain-private-hosted-zone-name:1}}'
# - ""
# Type: CNAME
# TTL: 300
# ResourceRecords:
# - !GetAtt DBCluster.Endpoint.Address
#
# ############################################# Event Subscription ##########################################
DBClusterEventSubscription:
Type: AWS::RDS::EventSubscription
Properties:
EventCategories:
- failover
- failure
- notification
SnsTopicArn: !Sub '{{resolve:ssm:/${EnvironmentName}/aws/sns/major-alert-topic:1}}'
SourceIds: [ !Ref DBCluster ]
SourceType: db-cluster
FirstDBInstanceEventSubscription:
Type: AWS::RDS::EventSubscription
Properties:
EventCategories:
- failover
- availability
- deletion
- low storage
- read replica
- recovery
- restoration
- failure
- notification
SnsTopicArn: !Sub '{{resolve:ssm:/${EnvironmentName}/aws/sns/major-alert-topic:1}}'
SourceIds:
- !Ref DBFirstInstance
SourceType: db-instance
SecondDBInstanceEventSubscription:
Condition: CreateSecondDBInstance
Type: AWS::RDS::EventSubscription
Properties:
EventCategories:
- failover
- availability
- deletion
- low storage
- read replica
- recovery
- restoration
- failure
- notification
SnsTopicArn: !Sub '{{resolve:ssm:/${EnvironmentName}/aws/sns/major-alert-topic:1}}'
SourceIds:
- !Ref DBSecondInstance
SourceType: db-instance
# ********************** Master Username ************************
#aws secretsmanager delete-secret --secret-id <secrets-arn> --force-delete-without-recovery --profile dev
DBMasterSecret:
Type: AWS::SecretsManager::Secret
# DeletionPolicy: Retain
UpdateReplacePolicy: Retain
Properties:
Name: !Join
- "-"
- - !Ref EnvironmentName
- !FindInMap [ !Ref MapName, !Ref DBClusterType, ClusterName ]
- !FindInMap [ !Ref MapName, !Ref DBClusterType, DBEngine ]
- !FindInMap [ !Ref MapName, !Ref DBClusterType, MasterUsername ]
Description: !Join
- "-"
- - "DB 'admin' User Secret"
- !Ref EnvironmentName
- !FindInMap [ !Ref MapName, !Ref DBClusterType, ClusterName ]
- !FindInMap [ !Ref MapName, !Ref DBClusterType, DBEngine ]
GenerateSecretString:
SecretStringTemplate: !Join
- ''
- - '{"username": "'
- !FindInMap [ !Ref MapName, !Ref DBClusterType, MasterUsername ]
- '", "ssl": "true", "dbname": ""}'
GenerateStringKey: "password"
ExcludeCharacters: '"@/'
#PasswordLength: 16
Tags:
- Key: Product
Value: !FindInMap [ !Ref MapName, Tags, Product ]
- Key: Service
Value: !FindInMap [ !Ref MapName, Tags, Service ]
- Key: Environment
Value: !Ref EnvironmentName
DBMasterSecretClusterAttachment:
Type: AWS::SecretsManager::SecretTargetAttachment
Properties:
SecretId: !Ref DBMasterSecret
TargetId: !Ref DBCluster
TargetType: AWS::RDS::DBCluster
DBMasterSecretRotationSchedule:
Type: AWS::SecretsManager::RotationSchedule
DependsOn: DBMasterSecretClusterAttachment
Properties:
SecretId: !Ref DBMasterSecret
RotateImmediatelyOnUpdate: !FindInMap [ !Ref MapName, !Ref DBClusterType, RotateImmediatelyOnUpdate ]
RotationLambdaARN: !GetAtt SecretsManagerRotationServerlessApp.Outputs.RotationLambdaARN
RotationRules:
AutomaticallyAfterDays: !FindInMap [ !Ref MapName, !Ref DBClusterType, PasswordRotationDays ]
SecretsManagerRotationServerlessApp:
Type: AWS::Serverless::Application
Properties:
Location:
ApplicationId: 'arn:aws:serverlessrepo:us-east-1:297356227824:applications/SecretsManagerRDSPostgreSQLRotationMultiUser'
SemanticVersion: 1.1.464
Parameters:
endpoint: !Sub 'https://secretsmanager.${AWS::Region}.amazonaws.com'
functionName: !Join
- "-"
- - !Ref EnvironmentName
- !FindInMap [ !Ref MapName, !Ref DBClusterType, ClusterName ]
- secret-manager-rotation-lambda
vpcSecurityGroupIds: !Ref DBSecurityGroup
vpcSubnetIds: !Join
- ","
- - !Sub '{{resolve:ssm:/${EnvironmentName}/aws/vpc/private-db-subnet-a-id:1}}'
- !Sub '{{resolve:ssm:/${EnvironmentName}/aws/vpc/private-db-subnet-b-id:1}}'
- !Sub '{{resolve:ssm:/${EnvironmentName}/aws/vpc/private-db-subnet-c-id:1}}'
# ******************* App Username ************************
Fn::ForEach::DBAppSecrets:
- Service
- !FindInMap [ !Ref MapName, !Ref DBClusterType, Services]
- 'dbAppSecret${Service}':
Type: AWS::SecretsManager::Secret
Properties:
Name: !Join
- "-"
- - !Ref EnvironmentName
- !FindInMap [ !Ref MapName, !Ref DBClusterType, ClusterName ]
- !FindInMap [ !Ref MapName, !Ref DBClusterType, DBEngine ]
- ${Service}
Description: !Join
- "-"
- - "DB User Secret for Service ${Service}"
- !Ref EnvironmentName
- !FindInMap [ !Ref MapName, !Ref DBClusterType, ClusterName ]
- !FindInMap [ !Ref MapName, !Ref DBClusterType, DBEngine ]
GenerateSecretString:
SecretStringTemplate: !Join
- ''
- - '{"username": "'
- ${Service}
- '", "ssl": "true", "masterarn": "'
- !Ref DBMasterSecret
- '", "dbname": ""}'
GenerateStringKey: "password"
ExcludeCharacters: '"@/'
#PasswordLength: 16
Tags:
- Key: Product
Value: !FindInMap [ !Ref MapName, Tags, Product ]
- Key: Service
Value: !FindInMap [ !Ref MapName, Tags, Service ]
- Key: Environment
Value: !Ref EnvironmentName
DependsOn:
- DBMasterSecret
Fn::ForEach::SecretTargetAttachment:
- Service
- !FindInMap [ !Ref MapName, !Ref DBClusterType, Services]
- 'secretTargetAttachment${Service}':
Type: AWS::SecretsManager::SecretTargetAttachment
Properties:
SecretId: !Sub 'dbAppSecret${Service}'
TargetId: !Ref DBCluster
TargetType: AWS::RDS::DBCluster
Fn::ForEach::RotationSchedule:
- Service
- !FindInMap [ !Ref MapName, !Ref DBClusterType, Services]
- 'rotationSchedule${Service}':
Type: AWS::SecretsManager::RotationSchedule
DependsOn: !Sub 'secretTargetAttachment${Service}'
Properties:
SecretId: !Sub 'dbAppSecret${Service}'
RotationLambdaARN: !GetAtt SecretsManagerRotationServerlessApp.Outputs.RotationLambdaARN
RotationRules:
AutomaticallyAfterDays: !FindInMap [ !Ref MapName, !Ref DBClusterType, PasswordRotationDays ]
# ******************* Alarms ************************
AlarmAuroraDbDeadlocksClusterMinor:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: !Join [ "-", [ !Ref EnvironmentName, !FindInMap [ !Ref MapName, !Ref DBClusterType, ClusterName ], "DBDeadlocks-alarm" ]]
MetricName: Deadlocks
Namespace: AWS/RDS
Dimensions:
- Name: DBClusterIdentifier
Value: !Ref DBCluster
AlarmDescription: !Sub "ENV : ${EnvironmentName}
ResourceMetric : Deadlocks.
Effect : Aurora deadlocks for DB instance threshold.
Reason : There is deadlock in DB
Severity : A minor alarm is raised when having even one deadlock in the DB. File an issue for developers to investigate the reason behind this failure.
Priority of the issue created is P3."
Statistic: Average
Threshold: 0
EvaluationPeriods: 1
DatapointsToAlarm: 1
ComparisonOperator: GreaterThanThreshold
Period: 300
AlarmActions:
- !Sub '{{resolve:ssm:/${EnvironmentName}/aws/sns/major-alert-topic:1}}'
OKActions:
- !Sub '{{resolve:ssm:/${EnvironmentName}/aws/sns/major-alert-topic:1}}'
TreatMissingData: ignore
AlarmAuroraDbConnectionsClusterMajor:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: !Join [ "-", [ !Ref EnvironmentName, !FindInMap [ !Ref MapName, !Ref DBClusterType, ClusterName ], "DBConnections-alarm" ]]
MetricName: DatabaseConnections
Namespace: AWS/RDS
Dimensions:
- Name: DBClusterIdentifier
Value: !Ref DBCluster
AlarmDescription: !Sub "ENV : ${EnvironmentName}
ResourceMetric : DatabaseConnections.
Effect : DB instance. The current number of connections to an DB instance. The max connection to the DB is 1000
Reason : High connection usage more than 80%
Severity : A major alarm raises when the number of connections exceeds 800. File an issue for developers to investigate the reason behind this failure.
Priority of the issue created is P2."
Statistic: Average
Threshold: 800
EvaluationPeriods: 1
DatapointsToAlarm: 1
ComparisonOperator: GreaterThanOrEqualToThreshold
Period: 300
AlarmActions:
- !Sub '{{resolve:ssm:/${EnvironmentName}/aws/sns/major-alert-topic:1}}'
OKActions:
- !Sub '{{resolve:ssm:/${EnvironmentName}/aws/sns/major-alert-topic:1}}'
TreatMissingData: ignore
AlarmAuroraFreeableMemoryClusterMajor:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: !Join [ "-", [ !Ref EnvironmentName, !FindInMap [ !Ref MapName, !Ref DBClusterType, ClusterName ], "FreeableMemory-alarm" ]]
MetricName: FreeableMemory
Namespace: AWS/RDS
Dimensions:
- Name: DBClusterIdentifier
Value: !Ref DBCluster
AlarmDescription: !Sub "ENV : ${EnvironmentName}
ResourceMetric : FreeableMemory.
Effect : DB instance, The amount of available random access memory. Freeable memory is low (1GB or lower). The amount of free memory available on the host.
This is derived from the RAM, buffers, and cache that the OS reports as freeable.
Monitor the freeable memory (FreeableMemory) metric to determine if your DB cluster is running out of available memory
Reason : High memory usage.
Severity : A major alarm that raises when Freeable memory is low 1GB. File an issue for developers to investigate the reason behind this failure.
Priority of the issue created is P2."
Statistic: Average
Threshold: 1000000000
EvaluationPeriods: 1
DatapointsToAlarm: 1
ComparisonOperator: LessThanOrEqualToThreshold
Period: 300
AlarmActions:
- !Sub '{{resolve:ssm:/${EnvironmentName}/aws/sns/major-alert-topic:1}}'
OKActions:
- !Sub '{{resolve:ssm:/${EnvironmentName}/aws/sns/major-alert-topic:1}}'
TreatMissingData: ignore
AlarmAuroraFreeLocalStorageClusterMajor:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: !Join [ "-", [ !Ref EnvironmentName, !FindInMap [ !Ref MapName, !Ref DBClusterType, ClusterName ], "FreeLocalStorage-alarm" ]]
MetricName: FreeLocalStorage
Namespace: AWS/RDS
Dimensions:
- Name: DBClusterIdentifier
Value: !Ref DBCluster
AlarmDescription: !Sub "ENV : ${EnvironmentName}
ResourceMetric : FreeLocalStorage .
Effect : DB instance, Free local storage for cluster breaches threshold.
Reason : High storage usage.
Severity : A major alarm is raised when the free local storage of the cluster is lower than 450MB. File an issue for developers
to investigate the reason behind this failure.
Priority of the issue created is P2."
Statistic: Average
Threshold: 450000000
EvaluationPeriods: 1
DatapointsToAlarm: 1
ComparisonOperator: LessThanOrEqualToThreshold
Period: 300
AlarmActions:
- !Sub '{{resolve:ssm:/${EnvironmentName}/aws/sns/major-alert-topic:1}}'
OKActions:
- !Sub '{{resolve:ssm:/${EnvironmentName}/aws/sns/major-alert-topic:1}}'
TreatMissingData: ignore
AlarmAuroraCpuUtilizationClusterMajor:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: !Join [ "-", [ !Ref EnvironmentName, !FindInMap [ !Ref MapName, !Ref DBClusterType, ClusterName ], "CPUUtilization-alarm" ]]
MetricName: CPUUtilization
Namespace: AWS/RDS
Dimensions:
- Name: DBClusterIdentifier
Value: !Ref DBCluster
AlarmDescription: !Sub "ENV : ${EnvironmentName}
ResourceMetric : CPUUtilization.
Effect : DB instance, The percentage of CPU used by an DB instance.
Reason : High cpu usage.
Severity : Major alarm that raises when the percentage of CPU used by DB is higher than 80%. File an issue for
developers to investigate the reason behind this failure.
Priority of the issue created is P2."
Statistic: Average
Threshold: 80
EvaluationPeriods: 1
DatapointsToAlarm: 1
ComparisonOperator: GreaterThanOrEqualToThreshold
Period: 300
AlarmActions:
- !Sub '{{resolve:ssm:/${EnvironmentName}/aws/sns/major-alert-topic:1}}'
OKActions:
- !Sub '{{resolve:ssm:/${EnvironmentName}/aws/sns/major-alert-topic:1}}'
TreatMissingData: ignore
DBMasterSecretArnParameter:
Type: AWS::SSM::Parameter
Properties:
Name: !Sub /${EnvironmentName}/aws/secret/${DBClusterType}/admin
Type: String
Value: !Ref DBMasterSecret
Description: SSM Parameter for Aurora DB Secret Arn
Tags:
Product: !FindInMap [ !Ref MapName, Tags, Product ]
Service: !FindInMap [ !Ref MapName, Tags, Service ]
Environment: !Ref EnvironmentName
Fn::ForEach::DBAppSecretsParam:
- Service
- !FindInMap [ !Ref MapName, !Ref DBClusterType, Services]
- 'dbAppSecretParamArn${Service}':
Type: AWS::SSM::Parameter
Properties:
Name: !Sub /${EnvironmentName}/aws/secret/${Service}-app
Type: String
Value: !Sub 'dbAppSecret${Service}'
Description: SSM Parameter for Aurora DB Secret Arn
Tags:
Product: !FindInMap [ !Ref MapName, Tags, Product ]
Service: !FindInMap [ !Ref MapName, Tags, Service ]
Environment: !Ref EnvironmentName
Outputs:
DBWriterEndpoint:
Description: Services Aurora DB DataBase Writer Endpoint URL
Value: !GetAtt DBFirstInstance.Endpoint.Address
DBReaderEndpoint:
Condition: CreateSecondDBInstance
Description: Services Aurora DB DataBase Reader Endpoint URL
Value: !GetAtt DBSecondInstance.Endpoint.Address
DBName:
Description: Services Aurora DB DataBase Name
Value: !FindInMap [ !Ref MapName, !Ref DBClusterType, DatabaseName ]
DBVpcSecurityGroupId:
Description: Services Aurora DB DataBase VPC Security Group ID
Value: !GetAtt DBSecurityGroup.GroupId
DBMasterSecretArn:
Value: !Ref DBMasterSecret
Description: SSM Parameter for Aurora DB Master Secret Arn
I don’t see any indentation issues within the Serverless Applicaiton. What is the issue?