Cloudformation stuck in UPDATE_ROLLBACK_FAILEDAdd an unknown-sized list of security groups to an EC2 instanceCloudformation “AWS::EC2::SecurityGroup” object with the Reason “No default VPC for this user”CloudFormation, passing a List<AWS::EC2::Subnet::Id> parameter as a comma separated string?Can't send parameters from a child CloudFormation template to another child templateUpdate Stack w. “Replacement: Conditional”; will it replace?AWS CloudFormation is stuck on DELETED_FAILED statusCloudFormation - Using Conditions, Pseudo Parameters, and Intrinsic Functions Together to define a Single Resource PropertyAWS ELB cloudformation by conditonsfor both HTTPS & HTTPIdentityPoolRoleAttachment Resource cannot be updatedCloudformation stack stuck in UPDATE_IN_PROGRESS

How to stop the death waves in my city?

What is Weapon Handling?

Why is the Common Agricultural Policy unfavourable to the UK?

GPLv3 forces us to make code available, but to who?

Delete n lines skip 1 line script

Why, even after his imprisonment, people keep calling Hannibal Lecter "Doctor"?

How do we know neutrons have no charge?

Discrepancy regarding AoE point of origin between English and German PHB

rust-proof solution for attaching 2x4 to 4x4?

Why aren't faces sharp in my f/1.8 portraits even though I'm carefully using center-point autofocus?

I reverse the source code, you reverse the input!

Is there a list of world wide upcoming space events on the web?

Can I build a half bath without permits?

"until mine is on tight" is a idiom?

Avoiding dust scattering when you drill

Which altitudes are safest for VFR?

How to say "respectively" in German when listing (enumerating) things

Why would an airline put 15 passengers at once on standby?

Are the coefficients of certain product of Rogers-Ramanujan Continued Fraction non-negative?

Question about a degree 5 polynomial with no rational roots

After viewing logs with journalctl, how do I exit the screen that says "lines 1-2/2 (END)"?

How to prevent pickpocketing in busy bars?

LM324 - Issue with output in negative feedback

Why does my browser attempt to download pages from http://clhs.lisp.se instead of viewing them normally?



Cloudformation stuck in UPDATE_ROLLBACK_FAILED


Add an unknown-sized list of security groups to an EC2 instanceCloudformation “AWS::EC2::SecurityGroup” object with the Reason “No default VPC for this user”CloudFormation, passing a List<AWS::EC2::Subnet::Id> parameter as a comma separated string?Can't send parameters from a child CloudFormation template to another child templateUpdate Stack w. “Replacement: Conditional”; will it replace?AWS CloudFormation is stuck on DELETED_FAILED statusCloudFormation - Using Conditions, Pseudo Parameters, and Intrinsic Functions Together to define a Single Resource PropertyAWS ELB cloudformation by conditonsfor both HTTPS & HTTPIdentityPoolRoleAttachment Resource cannot be updatedCloudformation stack stuck in UPDATE_IN_PROGRESS






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








1















Please help get past this. I have to enter 3 logical ids to rollback my update, but the regex in cloudformation doesn't allow for that because the regex doesn't appear to allow commas. But the continue ROLLBACK instructions from AWS clearly state to use commas:




"To skip resources, type a list of comma-separated logical
resource IDs. Include only the resources that are blocking the
rollback."




But the commas are not allowed by the cloudformation regex???? What am I missing here? I can't go forward or back. My cloudformation stack is stuck.



My error on trying to roll back:




Failed to rollback: 1 validation
error detected: Value '[rRoute10,rRoute192,rRoute172]' at
'resourcesToSkip' failed to satisfy constraint: Member must satisfy
constraint: [Member must satisfy regular expression pattern:
[a-zA-Z0-9]+|[a-zA-Z][-a-zA-Z0-9]*.[a-zA-Z0-9]+]




My errors in cloudformation:




14:06:04 UTC-0400 UPDATE_FAILED AWS::EC2::Route rRoute192 The gateway
ID 'vgw-0e7d969e316a7b5d5' does not exist (Service: AmazonEC2; Status
Code: 400; Error Code: InvalidGatewayID.NotFound; Request ID:
6d4cdb5f-31c5-4cf3-8777-3e3eb361d594)



14:06:04 UTC-0400 UPDATE_FAILED AWS::EC2::Route rRoute10 The gateway
ID 'vgw-0e7d969e316a7b5d5' does not exist (Service: AmazonEC2; Status
Code: 400; Error Code: InvalidGatewayID.NotFound; Request ID:
315ecc3a-d70c-46b7-b1cd-05f4c6765edd)



14:06:04 UTC-0400 UPDATE_FAILED AWS::EC2::Route rRoute172 The gateway
ID 'vgw-0e7d969e316a7b5d5' does not exist (Service: AmazonEC2; Status
Code: 400; Error Code: InvalidGatewayID.NotFound; Request ID:
2a6e20f0-4d41-4647-85f0-ffbfc0326680)




For background, someone deleted our VPG and created a different gateway. They also manually updated the routes. Now, I am trying to get the stack in sync on the route tables. However, the stack failed to update and now it fails to roll back.



Screenshot:
enter image description here



AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
RDS

SAM Template for creating an RDS in a secure Fault-Tolerant fashion...

Parameters:
pDBName:
Default: MyDatabase
Description: The database name
Type: String
MinLength: '1'
MaxLength: '64'
AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
ConstraintDescription: must begin with a letter and contain only alphanumeric characters.
pDBUser:
NoEcho: 'true'
Description: The database admin account username
Type: String
MinLength: '1'
MaxLength: '16'
AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
ConstraintDescription: must begin with a letter and contain only alphanumeric
characters.
pDBPassword:
NoEcho: 'true'
Description: The database admin account password
Type: String
MinLength: '1'
MaxLength: '41'
AllowedPattern: '[a-zA-Z0-9]+'
ConstraintDescription: must contain only alphanumeric characters.
pDBAllocatedStorage:
Default: '20'
Description: The size of the database (Gb)
Type: Number
MinValue: '20'
MaxValue: '16384'
ConstraintDescription: must be between 5 and 1024Gb.
pDBInstanceClass:
Description: The database instance type
Type: String
Default: db.t2.micro
AllowedValues: [db.t1.micro, db.m1.small, db.m1.medium, db.m1.large, db.m1.xlarge,
db.m2.xlarge, db.m2.2xlarge, db.m2.4xlarge, db.m3.medium, db.m3.large, db.m3.xlarge,
db.m3.2xlarge, db.m4.large, db.m4.xlarge, db.m4.2xlarge, db.m4.4xlarge, db.m4.10xlarge,
db.r3.large, db.r3.xlarge, db.r3.2xlarge, db.r3.4xlarge, db.r3.8xlarge, db.m2.xlarge,
db.m2.2xlarge, db.m2.4xlarge, db.cr1.8xlarge, db.t2.micro, db.t2.small, db.t2.medium,
db.t2.large]
ConstraintDescription: must select a valid database instance type.

# TODO - Future DBEngine allowed values: [aurora-mysql, aurora-postgresql, mariadb, oracle-ee, oracle-se2, sqlserver-ee, sqlserver-se, sqlserver-ex, sqlserver-web]
pDBEngine:
Description: The database type to create
Type: String
Default: oracle-se2
AllowedValues: [aurora-mysql, oracle-ee, oracle-se2]
ConstraintDescription: must select a valid database engine
pDBEngineVersion:
Description: The version of database to create
Type: String
pMultiAZ:
Description: Multi-AZ master database
Type: String
Default: 'false'
AllowedValues: ['true', 'false']
ConstraintDescription: must be true or false.
pDatabaseDeletionProtection:
Description: Do we even allow a database to be deleted?
Type: String
Default: 'false'
AllowedValues: ['true', 'false']
ConstraintDescription: must be true or false.
pDatabaseLicenseModel:
Description: What licensing do we use?
Type: String
Default: "license-included"
AllowedValues: ["license-included", "bring-your-own-license", "general-public-license"]
ConstraintDescription: must be license-included or bring-your-own-license or general-public-license
pDBParameterGroupName:
Description: Use an existing parameter group in Amazon RDS - must match the database.
Type: String
Default: "default.aurora-mysql5.7"
pStorageType: # https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_CreateDBInstance.html
Description: The type of storage to be used by the database.
Type: String
Default: 'standard'
AllowedValues: ['standard', 'gp2', 'io1']
pRDSVPC:
Description: The vpc to use?
Type: AWS::EC2::VPC::Id
pCreateNewSubnets:
Description: Set to true if we want new subnets for our databases
Type: String
Default: "true"
AllowedValues: ['true', 'false']
ConstraintDescription: must be true or false.
pExistingSubnetId1:
Description: Use an id of an existing private subnet
Type: String
Default: "subnet-0455e1cfa66facd17"
pExistingSubnetId2:
Description: Use an id of a second existing private subnet
Type: String
Default: "subnet-0536176832ba42dfd"
pSubnetCIDR1:
Description: The cidrblock to use?
Type: String
pSubnetCIDR2:
Description: The cidrblock to use?
Type: String
pGatewayID:
Description: The virtual private gateway id for the vpc, to manage our databases.
Type: String
Default: "vgw-0e7d969e316a7b5d5"
pOperatorEMail:
Description: EMail address to notify if there are any operational issues
Type: String
AllowedPattern: >-
([a-zA-Z0-9_-.]+)@(([[0-9]1,3.[0-9]1,3.[0-9]1,3.)|(([a-zA-Z0-9-]+.)+))([a-zA-Z]2,4|[0-9]1,3)(]?)
ConstraintDescription: must be a valid email address.

# This next parameter is a hold-over from older pipelines. It must exist, or there will be a cloudformation error.
BuildBucket:
Description: Unused in this template
Type: String
Default: ""


# Warning, I haven't actually tested all these databases or these mappings - be ready to debug :-)
Mappings:
DBPortMap:
aurora-mysql:
port: 3306
aurora-postgresql:
port: 5432
mariadb:
port: 3306
mysql:
port: 3306
oracle-ee:
port: 1521
oracle-se2:
port: 1521
postgres:
port: 5432
sqlserver-ee:
port: 1433
sqlserver-se:
port: 1433
sqlserver-ex:
port: 1433
sqlserver-web:
port: 1433

Conditions:
CreateMultiAZ: !Equals [ !Ref pMultiAZ, "true" ]
CreateNewSubnets: !Equals [ !Ref pCreateNewSubnets, "true" ]
CreateAurora: !Or
- !Equals [ !Ref pDBEngine, "aurora-mysql" ]
- !Equals [ !Ref pDBEngine, "aurora-postgresql" ]
CreateNonAurora: !Not [Condition: CreateAurora ]
CreateAuroraMultiAZ: !And
- Condition: CreateAurora
- Condition: CreateMultiAZ

Resources:
# TODO - SECURE THE PASSWARD PARAMETERS IN AWS PARAMETER STORE
# See: https://github.com/aws-samples/aws-aurora-cloudformation-samples/blob/master/cftemplates/Aurora-Postgres-DB-Cluster.yml
# TODO - DBClusterParameterGroups and DBParameterGroups are not auto-created.


# Subnets
#
# Create one subnet if pCreateNewSubnets is true
# Create two new subnets if both pCreateNewSubnets and pMultiAZ are true...
# Otherwise, the user better have specified existing subnet(s) in pExistingSubnetId1 and pExistingSubnetId2
#
# Note that this template assumes we use Availability Zones 0 and 1. Perhaps I should make those parameters?
#
rDBSubnet1:
Type: AWS::EC2::Subnet
Condition: CreateNewSubnets
Properties:
VpcId: !Ref 'pRDSVPC'
CidrBlock: !Ref 'pSubnetCIDR1'
AvailabilityZone: !Select
- 0
- !GetAZs
Ref: 'AWS::Region'
Tags:
- Key: "Name"
Value: !Join [ "-", [!Ref "AWS::StackName", !Ref "AWS::Region", "RDS-AZA-SUBNET"] ]

rDBSubnet2:
Type: AWS::EC2::Subnet
Condition: CreateNewSubnets
Properties:
VpcId: !Ref 'pRDSVPC'
CidrBlock: !Ref 'pSubnetCIDR2'
AvailabilityZone: !Select
- 1
- !GetAZs
Ref: 'AWS::Region'
Tags:
- Key: "Name"
Value: !Join [ "-", [!Ref "AWS::StackName", !Ref "AWS::Region", "RDS-AZB-SUBNET"] ]

# Route Table
#
# If we create new subnets, we need to use a route table. I thought about reusing the existing route table for the
# primary private subnet, but this is a different class of traffic. I feel it is best practice to create new route tables.
#
rCustomRouteTable:
Type: AWS::EC2::RouteTable
Condition: CreateNewSubnets
Properties:
VpcId: !Ref 'pRDSVPC'
Tags:
- Key: "Name"
Value: !Join [ "-", [!Ref "AWS::StackName", !Ref "AWS::Region", "RTB-RDS"] ]

rRoute10:
Type: AWS::EC2::Route
Condition: CreateNewSubnets
Properties:
RouteTableId: !Ref rCustomRouteTable
DestinationCidrBlock: 10.0.0.0/8
GatewayId: !Ref pGatewayID

rRoute172:
Type: AWS::EC2::Route
Condition: CreateNewSubnets
Properties:
RouteTableId: !Ref rCustomRouteTable
DestinationCidrBlock: 172.16.0.0/12
GatewayId: !Ref pGatewayID

rRoute192:
Type: AWS::EC2::Route
Condition: CreateNewSubnets
Properties:
RouteTableId: !Ref rCustomRouteTable
DestinationCidrBlock: 192.168.0.0/16
GatewayId: !Ref pGatewayID

# attach route tables to our previously created subnets.
rSubnetRouteTableAssociation1:
Type: AWS::EC2::SubnetRouteTableAssociation
Condition: CreateNewSubnets
Properties:
SubnetId: !Ref rDBSubnet1
RouteTableId: !Ref rCustomRouteTable

rSubnetRouteTableAssociation2:
Type: AWS::EC2::SubnetRouteTableAssociation
Condition: CreateNewSubnets
Properties:
SubnetId: !Ref rDBSubnet2
RouteTableId: !Ref rCustomRouteTable

# Security group.
#
# This is to make sure our databases only allow traffic on the correct port.
#
# Technically, we could be more specific than 0.0.0.0/0

rDBEC2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Open database for access
VpcId: !Ref pRDSVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: !FindInMap
- DBPortMap
- !Ref 'pDBEngine'
- port
ToPort: !FindInMap
- DBPortMap
- !Ref 'pDBEngine'
- port
CidrIp: 0.0.0.0/0
Description: !Ref 'pDBEngine'
Tags:
- Key: "Name"
Value: !Join [ "-", [!Ref "AWS::StackName", !Ref "AWS::Region", "RDS-SEC"] ]

# Subnet Groups
#
# Here is the deal. We don't attach subnets directly to databases. Rather, we group subnets and attach the group to the
# databases. So, here is the complex "if" logic to determine which subnets to put into our database subnet group.
rDBSubnetGroup:
Type: "AWS::RDS::DBSubnetGroup"
Properties:
DBSubnetGroupDescription: "description"
SubnetIds:
- !If [CreateNewSubnets, !Ref rDBSubnet1, !Ref pExistingSubnetId1 ]
- !If [CreateNewSubnets, !Ref rDBSubnet2, !Ref pExistingSubnetId2 ]

# Database Builds...
#
# Aurora builds... first
rDatabaseCluster:
Type: AWS::RDS::DBCluster
Condition: CreateAurora
Properties:
DatabaseName: !Ref 'pDBName'
Engine: !Ref 'pDBEngine'
EngineVersion: !Ref pDBEngineVersion
MasterUsername: !Ref 'pDBUser'
MasterUserPassword: !Ref 'pDBPassword'
DBSubnetGroupName: !Ref rDBSubnetGroup
DBClusterParameterGroupName: !Ref pDBParameterGroupName
DeletionProtection: !Ref 'pDatabaseDeletionProtection'
VpcSecurityGroupIds: [!GetAtt [rDBEC2SecurityGroup, GroupId]]

rAuroraDB1:
Type: AWS::RDS::DBInstance
Condition: CreateAurora
Properties:
CopyTagsToSnapshot: true
DBInstanceClass: !Ref 'pDBInstanceClass'
DBClusterIdentifier: !Ref rDatabaseCluster
DBSubnetGroupName: !Ref rDBSubnetGroup
Engine: !Ref 'pDBEngine'
EngineVersion: !Ref pDBEngineVersion
DBParameterGroupName: !Ref pDBParameterGroupName
PubliclyAccessible: false
LicenseModel: !Ref 'pDatabaseLicenseModel'

rAuroraDB2:
Type: AWS::RDS::DBInstance
Condition: CreateAuroraMultiAZ
Properties:
CopyTagsToSnapshot: true
DBInstanceClass: !Ref 'pDBInstanceClass'
DBClusterIdentifier: !Ref rDatabaseCluster
DBSubnetGroupName: !Ref rDBSubnetGroup
Engine: !Ref 'pDBEngine'
EngineVersion: !Ref pDBEngineVersion
DBParameterGroupName: !Ref pDBParameterGroupName
PubliclyAccessible: false
LicenseModel: !Ref 'pDatabaseLicenseModel'

# Now for the Non-Aurora builds...
rMasterDB:
Type: AWS::RDS::DBInstance
Condition: CreateNonAurora
Properties:
AllocatedStorage: !Ref 'pDBAllocatedStorage'
CopyTagsToSnapshot: true
DBInstanceClass: !Ref 'pDBInstanceClass'
DBName: !Ref 'pDBName'
DBSubnetGroupName: !Ref rDBSubnetGroup
Engine: !Ref 'pDBEngine'
EngineVersion: !Ref pDBEngineVersion
DBParameterGroupName: !Ref pDBParameterGroupName
MasterUsername: !Ref 'pDBUser'
MasterUserPassword: !Ref 'pDBPassword'
MultiAZ: !Ref 'pMultiAZ'
PubliclyAccessible: false
StorageType: !Ref 'pStorageType'
VPCSecurityGroups: [!GetAtt [rDBEC2SecurityGroup, GroupId]]
LicenseModel: !Ref 'pDatabaseLicenseModel'
DeletionProtection: !Ref 'pDatabaseDeletionProtection'

# Cloudwatch alarms
#
# Nothing too special here. I just make sure the DB is operational.
rAlarmTopic:
Type: 'AWS::SNS::Topic'
Properties:
Subscription:
- Endpoint: !Ref pOperatorEMail
Protocol: email

rCPUAlarmHighMasterDB:
Type: 'AWS::CloudWatch::Alarm'
Condition: CreateNonAurora
Properties:
EvaluationPeriods: 10
Statistic: Average
Threshold: 50
AlarmDescription: >-
Alarm if CPU too high or metric disappears indicating the RDS database
instance is having issues
Period: 60
Namespace: AWS/RDS
MetricName: CPUUtilization
Dimensions:
- Name: DBInstanceIdentifier
Value: !Ref rMasterDB
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref rAlarmTopic
InsufficientDataActions:
- !Ref rAlarmTopic

rCPUAlarmHighAuroraDB1:
Type: 'AWS::CloudWatch::Alarm'
Condition: CreateAurora
Properties:
EvaluationPeriods: 10
Statistic: Average
Threshold: 50
AlarmDescription: >-
Alarm if CPU too high or metric disappears indicating the RDS database
instance is having issues
Period: 60
Namespace: AWS/RDS
MetricName: CPUUtilization
Dimensions:
- Name: DBInstanceIdentifier
Value: !Ref rAuroraDB1
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref rAlarmTopic
InsufficientDataActions:
- !Ref rAlarmTopic

rCPUAlarmHighAuroraDB2:
Type: 'AWS::CloudWatch::Alarm'
Condition: CreateAuroraMultiAZ
Properties:
EvaluationPeriods: 10
Statistic: Average
Threshold: 50
AlarmDescription: >-
Alarm if CPU too high or metric disappears indicating the RDS database
instance is having issues
Period: 60
Namespace: AWS/RDS
MetricName: CPUUtilization
Dimensions:
- Name: DBInstanceIdentifier
Value: !Ref rAuroraDB2
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref rAlarmTopic
InsufficientDataActions:
- !Ref rAlarmTopic
#
# Consider adding JDBC string...
#
Outputs:
Name:
Description: Aurora Stack Name
Value: !Ref AWS::StackName
Export:
Name: !Sub $AWS::StackName-Name
RDSEndPointAddress:
Description: Database Endpoint Address
Value: !GetAtt [rMasterDB, Endpoint.Address]
Export:
Name: !Sub $AWS::StackName-RDSEndPointAddress
Condition: CreateNonAurora
RDSEndPointPort:
Description: Database Endpoint port
Value: !GetAtt [rMasterDB, Endpoint.Port]
Export:
Name: !Sub $AWS::StackName-RDSEndPointPort
Condition: CreateNonAurora
AuroraClusterId:
Description: Aurora Cluster ID
Value: !Ref rDatabaseCluster
Export:
Name: !Sub $AWS::StackName-AuroraClusterID
Condition: CreateAurora
AuroraEndPointAddress:
Description: Database Endpoint Address
Value: !GetAtt [rDatabaseCluster, Endpoint.Address]
Export:
Name: !Sub $AWS::StackName-AuroraDatabaseURL
Condition: CreateAurora
AuroraEndPointPort:
Description: Database Endpoint port
Value: !GetAtt [rDatabaseCluster, Endpoint.Port]
Export:
Name: !Sub $AWS::StackName-AuroraDatabasePort
Condition: CreateAurora
EndPointDBName:
Description: Database Name
Value: !Ref 'pDBName'
Export:
Name: !Sub $AWS::StackName-DBName
JDBCConnectionString:
Description: JDBC connection string for a mysql database
Value: !Join ['', ['jdbc:mysql://', !GetAtt [rDatabaseCluster, Endpoint.Address], ':', !GetAtt [
rDatabaseCluster, Endpoint.Port], /, !Ref 'pDBName']]
Export:
Name: !Sub $AWS::StackName-MySQLJDBCString
Condition: CreateAurora









share|improve this question


























  • Can you please add a screenshot of the all the failed events listed under the Events tab?

    – Hassan Mussana
    Mar 28 at 21:59











  • Absolutely. Note that the order of events was as follows: 1) deployed a stack with routes that included VPG. 2) someone manually changed the VPG and manually altered the route tables. 3) updated stack to have correct route tables. 4) stack update failed (Reason: "Route did not stabilize in expected time") 5) stack went into "UPDATE_ROLLBACK_FAILED" 6) now, we can't get out of that status.

    – Paul Fowler
    Mar 28 at 22:23











  • Are you using nested stacks, can you post your CloudFormation yaml here (obfuscate any critical info)?

    – Hassan Mussana
    Mar 28 at 22:33











  • No nested stacks...

    – Paul Fowler
    Mar 28 at 22:45






  • 1





    Nope, it is not a bug I think. CLI just shows the programmatic way of doing it so that would be more accurate anyway. I think the console just takes the input without quotes and [ ]. I used the option a while ago so don't remember but will reproduce this and test it from the console as well.

    – Hassan Mussana
    Mar 29 at 9:54

















1















Please help get past this. I have to enter 3 logical ids to rollback my update, but the regex in cloudformation doesn't allow for that because the regex doesn't appear to allow commas. But the continue ROLLBACK instructions from AWS clearly state to use commas:




"To skip resources, type a list of comma-separated logical
resource IDs. Include only the resources that are blocking the
rollback."




But the commas are not allowed by the cloudformation regex???? What am I missing here? I can't go forward or back. My cloudformation stack is stuck.



My error on trying to roll back:




Failed to rollback: 1 validation
error detected: Value '[rRoute10,rRoute192,rRoute172]' at
'resourcesToSkip' failed to satisfy constraint: Member must satisfy
constraint: [Member must satisfy regular expression pattern:
[a-zA-Z0-9]+|[a-zA-Z][-a-zA-Z0-9]*.[a-zA-Z0-9]+]




My errors in cloudformation:




14:06:04 UTC-0400 UPDATE_FAILED AWS::EC2::Route rRoute192 The gateway
ID 'vgw-0e7d969e316a7b5d5' does not exist (Service: AmazonEC2; Status
Code: 400; Error Code: InvalidGatewayID.NotFound; Request ID:
6d4cdb5f-31c5-4cf3-8777-3e3eb361d594)



14:06:04 UTC-0400 UPDATE_FAILED AWS::EC2::Route rRoute10 The gateway
ID 'vgw-0e7d969e316a7b5d5' does not exist (Service: AmazonEC2; Status
Code: 400; Error Code: InvalidGatewayID.NotFound; Request ID:
315ecc3a-d70c-46b7-b1cd-05f4c6765edd)



14:06:04 UTC-0400 UPDATE_FAILED AWS::EC2::Route rRoute172 The gateway
ID 'vgw-0e7d969e316a7b5d5' does not exist (Service: AmazonEC2; Status
Code: 400; Error Code: InvalidGatewayID.NotFound; Request ID:
2a6e20f0-4d41-4647-85f0-ffbfc0326680)




For background, someone deleted our VPG and created a different gateway. They also manually updated the routes. Now, I am trying to get the stack in sync on the route tables. However, the stack failed to update and now it fails to roll back.



Screenshot:
enter image description here



AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
RDS

SAM Template for creating an RDS in a secure Fault-Tolerant fashion...

Parameters:
pDBName:
Default: MyDatabase
Description: The database name
Type: String
MinLength: '1'
MaxLength: '64'
AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
ConstraintDescription: must begin with a letter and contain only alphanumeric characters.
pDBUser:
NoEcho: 'true'
Description: The database admin account username
Type: String
MinLength: '1'
MaxLength: '16'
AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
ConstraintDescription: must begin with a letter and contain only alphanumeric
characters.
pDBPassword:
NoEcho: 'true'
Description: The database admin account password
Type: String
MinLength: '1'
MaxLength: '41'
AllowedPattern: '[a-zA-Z0-9]+'
ConstraintDescription: must contain only alphanumeric characters.
pDBAllocatedStorage:
Default: '20'
Description: The size of the database (Gb)
Type: Number
MinValue: '20'
MaxValue: '16384'
ConstraintDescription: must be between 5 and 1024Gb.
pDBInstanceClass:
Description: The database instance type
Type: String
Default: db.t2.micro
AllowedValues: [db.t1.micro, db.m1.small, db.m1.medium, db.m1.large, db.m1.xlarge,
db.m2.xlarge, db.m2.2xlarge, db.m2.4xlarge, db.m3.medium, db.m3.large, db.m3.xlarge,
db.m3.2xlarge, db.m4.large, db.m4.xlarge, db.m4.2xlarge, db.m4.4xlarge, db.m4.10xlarge,
db.r3.large, db.r3.xlarge, db.r3.2xlarge, db.r3.4xlarge, db.r3.8xlarge, db.m2.xlarge,
db.m2.2xlarge, db.m2.4xlarge, db.cr1.8xlarge, db.t2.micro, db.t2.small, db.t2.medium,
db.t2.large]
ConstraintDescription: must select a valid database instance type.

# TODO - Future DBEngine allowed values: [aurora-mysql, aurora-postgresql, mariadb, oracle-ee, oracle-se2, sqlserver-ee, sqlserver-se, sqlserver-ex, sqlserver-web]
pDBEngine:
Description: The database type to create
Type: String
Default: oracle-se2
AllowedValues: [aurora-mysql, oracle-ee, oracle-se2]
ConstraintDescription: must select a valid database engine
pDBEngineVersion:
Description: The version of database to create
Type: String
pMultiAZ:
Description: Multi-AZ master database
Type: String
Default: 'false'
AllowedValues: ['true', 'false']
ConstraintDescription: must be true or false.
pDatabaseDeletionProtection:
Description: Do we even allow a database to be deleted?
Type: String
Default: 'false'
AllowedValues: ['true', 'false']
ConstraintDescription: must be true or false.
pDatabaseLicenseModel:
Description: What licensing do we use?
Type: String
Default: "license-included"
AllowedValues: ["license-included", "bring-your-own-license", "general-public-license"]
ConstraintDescription: must be license-included or bring-your-own-license or general-public-license
pDBParameterGroupName:
Description: Use an existing parameter group in Amazon RDS - must match the database.
Type: String
Default: "default.aurora-mysql5.7"
pStorageType: # https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_CreateDBInstance.html
Description: The type of storage to be used by the database.
Type: String
Default: 'standard'
AllowedValues: ['standard', 'gp2', 'io1']
pRDSVPC:
Description: The vpc to use?
Type: AWS::EC2::VPC::Id
pCreateNewSubnets:
Description: Set to true if we want new subnets for our databases
Type: String
Default: "true"
AllowedValues: ['true', 'false']
ConstraintDescription: must be true or false.
pExistingSubnetId1:
Description: Use an id of an existing private subnet
Type: String
Default: "subnet-0455e1cfa66facd17"
pExistingSubnetId2:
Description: Use an id of a second existing private subnet
Type: String
Default: "subnet-0536176832ba42dfd"
pSubnetCIDR1:
Description: The cidrblock to use?
Type: String
pSubnetCIDR2:
Description: The cidrblock to use?
Type: String
pGatewayID:
Description: The virtual private gateway id for the vpc, to manage our databases.
Type: String
Default: "vgw-0e7d969e316a7b5d5"
pOperatorEMail:
Description: EMail address to notify if there are any operational issues
Type: String
AllowedPattern: >-
([a-zA-Z0-9_-.]+)@(([[0-9]1,3.[0-9]1,3.[0-9]1,3.)|(([a-zA-Z0-9-]+.)+))([a-zA-Z]2,4|[0-9]1,3)(]?)
ConstraintDescription: must be a valid email address.

# This next parameter is a hold-over from older pipelines. It must exist, or there will be a cloudformation error.
BuildBucket:
Description: Unused in this template
Type: String
Default: ""


# Warning, I haven't actually tested all these databases or these mappings - be ready to debug :-)
Mappings:
DBPortMap:
aurora-mysql:
port: 3306
aurora-postgresql:
port: 5432
mariadb:
port: 3306
mysql:
port: 3306
oracle-ee:
port: 1521
oracle-se2:
port: 1521
postgres:
port: 5432
sqlserver-ee:
port: 1433
sqlserver-se:
port: 1433
sqlserver-ex:
port: 1433
sqlserver-web:
port: 1433

Conditions:
CreateMultiAZ: !Equals [ !Ref pMultiAZ, "true" ]
CreateNewSubnets: !Equals [ !Ref pCreateNewSubnets, "true" ]
CreateAurora: !Or
- !Equals [ !Ref pDBEngine, "aurora-mysql" ]
- !Equals [ !Ref pDBEngine, "aurora-postgresql" ]
CreateNonAurora: !Not [Condition: CreateAurora ]
CreateAuroraMultiAZ: !And
- Condition: CreateAurora
- Condition: CreateMultiAZ

Resources:
# TODO - SECURE THE PASSWARD PARAMETERS IN AWS PARAMETER STORE
# See: https://github.com/aws-samples/aws-aurora-cloudformation-samples/blob/master/cftemplates/Aurora-Postgres-DB-Cluster.yml
# TODO - DBClusterParameterGroups and DBParameterGroups are not auto-created.


# Subnets
#
# Create one subnet if pCreateNewSubnets is true
# Create two new subnets if both pCreateNewSubnets and pMultiAZ are true...
# Otherwise, the user better have specified existing subnet(s) in pExistingSubnetId1 and pExistingSubnetId2
#
# Note that this template assumes we use Availability Zones 0 and 1. Perhaps I should make those parameters?
#
rDBSubnet1:
Type: AWS::EC2::Subnet
Condition: CreateNewSubnets
Properties:
VpcId: !Ref 'pRDSVPC'
CidrBlock: !Ref 'pSubnetCIDR1'
AvailabilityZone: !Select
- 0
- !GetAZs
Ref: 'AWS::Region'
Tags:
- Key: "Name"
Value: !Join [ "-", [!Ref "AWS::StackName", !Ref "AWS::Region", "RDS-AZA-SUBNET"] ]

rDBSubnet2:
Type: AWS::EC2::Subnet
Condition: CreateNewSubnets
Properties:
VpcId: !Ref 'pRDSVPC'
CidrBlock: !Ref 'pSubnetCIDR2'
AvailabilityZone: !Select
- 1
- !GetAZs
Ref: 'AWS::Region'
Tags:
- Key: "Name"
Value: !Join [ "-", [!Ref "AWS::StackName", !Ref "AWS::Region", "RDS-AZB-SUBNET"] ]

# Route Table
#
# If we create new subnets, we need to use a route table. I thought about reusing the existing route table for the
# primary private subnet, but this is a different class of traffic. I feel it is best practice to create new route tables.
#
rCustomRouteTable:
Type: AWS::EC2::RouteTable
Condition: CreateNewSubnets
Properties:
VpcId: !Ref 'pRDSVPC'
Tags:
- Key: "Name"
Value: !Join [ "-", [!Ref "AWS::StackName", !Ref "AWS::Region", "RTB-RDS"] ]

rRoute10:
Type: AWS::EC2::Route
Condition: CreateNewSubnets
Properties:
RouteTableId: !Ref rCustomRouteTable
DestinationCidrBlock: 10.0.0.0/8
GatewayId: !Ref pGatewayID

rRoute172:
Type: AWS::EC2::Route
Condition: CreateNewSubnets
Properties:
RouteTableId: !Ref rCustomRouteTable
DestinationCidrBlock: 172.16.0.0/12
GatewayId: !Ref pGatewayID

rRoute192:
Type: AWS::EC2::Route
Condition: CreateNewSubnets
Properties:
RouteTableId: !Ref rCustomRouteTable
DestinationCidrBlock: 192.168.0.0/16
GatewayId: !Ref pGatewayID

# attach route tables to our previously created subnets.
rSubnetRouteTableAssociation1:
Type: AWS::EC2::SubnetRouteTableAssociation
Condition: CreateNewSubnets
Properties:
SubnetId: !Ref rDBSubnet1
RouteTableId: !Ref rCustomRouteTable

rSubnetRouteTableAssociation2:
Type: AWS::EC2::SubnetRouteTableAssociation
Condition: CreateNewSubnets
Properties:
SubnetId: !Ref rDBSubnet2
RouteTableId: !Ref rCustomRouteTable

# Security group.
#
# This is to make sure our databases only allow traffic on the correct port.
#
# Technically, we could be more specific than 0.0.0.0/0

rDBEC2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Open database for access
VpcId: !Ref pRDSVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: !FindInMap
- DBPortMap
- !Ref 'pDBEngine'
- port
ToPort: !FindInMap
- DBPortMap
- !Ref 'pDBEngine'
- port
CidrIp: 0.0.0.0/0
Description: !Ref 'pDBEngine'
Tags:
- Key: "Name"
Value: !Join [ "-", [!Ref "AWS::StackName", !Ref "AWS::Region", "RDS-SEC"] ]

# Subnet Groups
#
# Here is the deal. We don't attach subnets directly to databases. Rather, we group subnets and attach the group to the
# databases. So, here is the complex "if" logic to determine which subnets to put into our database subnet group.
rDBSubnetGroup:
Type: "AWS::RDS::DBSubnetGroup"
Properties:
DBSubnetGroupDescription: "description"
SubnetIds:
- !If [CreateNewSubnets, !Ref rDBSubnet1, !Ref pExistingSubnetId1 ]
- !If [CreateNewSubnets, !Ref rDBSubnet2, !Ref pExistingSubnetId2 ]

# Database Builds...
#
# Aurora builds... first
rDatabaseCluster:
Type: AWS::RDS::DBCluster
Condition: CreateAurora
Properties:
DatabaseName: !Ref 'pDBName'
Engine: !Ref 'pDBEngine'
EngineVersion: !Ref pDBEngineVersion
MasterUsername: !Ref 'pDBUser'
MasterUserPassword: !Ref 'pDBPassword'
DBSubnetGroupName: !Ref rDBSubnetGroup
DBClusterParameterGroupName: !Ref pDBParameterGroupName
DeletionProtection: !Ref 'pDatabaseDeletionProtection'
VpcSecurityGroupIds: [!GetAtt [rDBEC2SecurityGroup, GroupId]]

rAuroraDB1:
Type: AWS::RDS::DBInstance
Condition: CreateAurora
Properties:
CopyTagsToSnapshot: true
DBInstanceClass: !Ref 'pDBInstanceClass'
DBClusterIdentifier: !Ref rDatabaseCluster
DBSubnetGroupName: !Ref rDBSubnetGroup
Engine: !Ref 'pDBEngine'
EngineVersion: !Ref pDBEngineVersion
DBParameterGroupName: !Ref pDBParameterGroupName
PubliclyAccessible: false
LicenseModel: !Ref 'pDatabaseLicenseModel'

rAuroraDB2:
Type: AWS::RDS::DBInstance
Condition: CreateAuroraMultiAZ
Properties:
CopyTagsToSnapshot: true
DBInstanceClass: !Ref 'pDBInstanceClass'
DBClusterIdentifier: !Ref rDatabaseCluster
DBSubnetGroupName: !Ref rDBSubnetGroup
Engine: !Ref 'pDBEngine'
EngineVersion: !Ref pDBEngineVersion
DBParameterGroupName: !Ref pDBParameterGroupName
PubliclyAccessible: false
LicenseModel: !Ref 'pDatabaseLicenseModel'

# Now for the Non-Aurora builds...
rMasterDB:
Type: AWS::RDS::DBInstance
Condition: CreateNonAurora
Properties:
AllocatedStorage: !Ref 'pDBAllocatedStorage'
CopyTagsToSnapshot: true
DBInstanceClass: !Ref 'pDBInstanceClass'
DBName: !Ref 'pDBName'
DBSubnetGroupName: !Ref rDBSubnetGroup
Engine: !Ref 'pDBEngine'
EngineVersion: !Ref pDBEngineVersion
DBParameterGroupName: !Ref pDBParameterGroupName
MasterUsername: !Ref 'pDBUser'
MasterUserPassword: !Ref 'pDBPassword'
MultiAZ: !Ref 'pMultiAZ'
PubliclyAccessible: false
StorageType: !Ref 'pStorageType'
VPCSecurityGroups: [!GetAtt [rDBEC2SecurityGroup, GroupId]]
LicenseModel: !Ref 'pDatabaseLicenseModel'
DeletionProtection: !Ref 'pDatabaseDeletionProtection'

# Cloudwatch alarms
#
# Nothing too special here. I just make sure the DB is operational.
rAlarmTopic:
Type: 'AWS::SNS::Topic'
Properties:
Subscription:
- Endpoint: !Ref pOperatorEMail
Protocol: email

rCPUAlarmHighMasterDB:
Type: 'AWS::CloudWatch::Alarm'
Condition: CreateNonAurora
Properties:
EvaluationPeriods: 10
Statistic: Average
Threshold: 50
AlarmDescription: >-
Alarm if CPU too high or metric disappears indicating the RDS database
instance is having issues
Period: 60
Namespace: AWS/RDS
MetricName: CPUUtilization
Dimensions:
- Name: DBInstanceIdentifier
Value: !Ref rMasterDB
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref rAlarmTopic
InsufficientDataActions:
- !Ref rAlarmTopic

rCPUAlarmHighAuroraDB1:
Type: 'AWS::CloudWatch::Alarm'
Condition: CreateAurora
Properties:
EvaluationPeriods: 10
Statistic: Average
Threshold: 50
AlarmDescription: >-
Alarm if CPU too high or metric disappears indicating the RDS database
instance is having issues
Period: 60
Namespace: AWS/RDS
MetricName: CPUUtilization
Dimensions:
- Name: DBInstanceIdentifier
Value: !Ref rAuroraDB1
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref rAlarmTopic
InsufficientDataActions:
- !Ref rAlarmTopic

rCPUAlarmHighAuroraDB2:
Type: 'AWS::CloudWatch::Alarm'
Condition: CreateAuroraMultiAZ
Properties:
EvaluationPeriods: 10
Statistic: Average
Threshold: 50
AlarmDescription: >-
Alarm if CPU too high or metric disappears indicating the RDS database
instance is having issues
Period: 60
Namespace: AWS/RDS
MetricName: CPUUtilization
Dimensions:
- Name: DBInstanceIdentifier
Value: !Ref rAuroraDB2
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref rAlarmTopic
InsufficientDataActions:
- !Ref rAlarmTopic
#
# Consider adding JDBC string...
#
Outputs:
Name:
Description: Aurora Stack Name
Value: !Ref AWS::StackName
Export:
Name: !Sub $AWS::StackName-Name
RDSEndPointAddress:
Description: Database Endpoint Address
Value: !GetAtt [rMasterDB, Endpoint.Address]
Export:
Name: !Sub $AWS::StackName-RDSEndPointAddress
Condition: CreateNonAurora
RDSEndPointPort:
Description: Database Endpoint port
Value: !GetAtt [rMasterDB, Endpoint.Port]
Export:
Name: !Sub $AWS::StackName-RDSEndPointPort
Condition: CreateNonAurora
AuroraClusterId:
Description: Aurora Cluster ID
Value: !Ref rDatabaseCluster
Export:
Name: !Sub $AWS::StackName-AuroraClusterID
Condition: CreateAurora
AuroraEndPointAddress:
Description: Database Endpoint Address
Value: !GetAtt [rDatabaseCluster, Endpoint.Address]
Export:
Name: !Sub $AWS::StackName-AuroraDatabaseURL
Condition: CreateAurora
AuroraEndPointPort:
Description: Database Endpoint port
Value: !GetAtt [rDatabaseCluster, Endpoint.Port]
Export:
Name: !Sub $AWS::StackName-AuroraDatabasePort
Condition: CreateAurora
EndPointDBName:
Description: Database Name
Value: !Ref 'pDBName'
Export:
Name: !Sub $AWS::StackName-DBName
JDBCConnectionString:
Description: JDBC connection string for a mysql database
Value: !Join ['', ['jdbc:mysql://', !GetAtt [rDatabaseCluster, Endpoint.Address], ':', !GetAtt [
rDatabaseCluster, Endpoint.Port], /, !Ref 'pDBName']]
Export:
Name: !Sub $AWS::StackName-MySQLJDBCString
Condition: CreateAurora









share|improve this question


























  • Can you please add a screenshot of the all the failed events listed under the Events tab?

    – Hassan Mussana
    Mar 28 at 21:59











  • Absolutely. Note that the order of events was as follows: 1) deployed a stack with routes that included VPG. 2) someone manually changed the VPG and manually altered the route tables. 3) updated stack to have correct route tables. 4) stack update failed (Reason: "Route did not stabilize in expected time") 5) stack went into "UPDATE_ROLLBACK_FAILED" 6) now, we can't get out of that status.

    – Paul Fowler
    Mar 28 at 22:23











  • Are you using nested stacks, can you post your CloudFormation yaml here (obfuscate any critical info)?

    – Hassan Mussana
    Mar 28 at 22:33











  • No nested stacks...

    – Paul Fowler
    Mar 28 at 22:45






  • 1





    Nope, it is not a bug I think. CLI just shows the programmatic way of doing it so that would be more accurate anyway. I think the console just takes the input without quotes and [ ]. I used the option a while ago so don't remember but will reproduce this and test it from the console as well.

    – Hassan Mussana
    Mar 29 at 9:54













1












1








1








Please help get past this. I have to enter 3 logical ids to rollback my update, but the regex in cloudformation doesn't allow for that because the regex doesn't appear to allow commas. But the continue ROLLBACK instructions from AWS clearly state to use commas:




"To skip resources, type a list of comma-separated logical
resource IDs. Include only the resources that are blocking the
rollback."




But the commas are not allowed by the cloudformation regex???? What am I missing here? I can't go forward or back. My cloudformation stack is stuck.



My error on trying to roll back:




Failed to rollback: 1 validation
error detected: Value '[rRoute10,rRoute192,rRoute172]' at
'resourcesToSkip' failed to satisfy constraint: Member must satisfy
constraint: [Member must satisfy regular expression pattern:
[a-zA-Z0-9]+|[a-zA-Z][-a-zA-Z0-9]*.[a-zA-Z0-9]+]




My errors in cloudformation:




14:06:04 UTC-0400 UPDATE_FAILED AWS::EC2::Route rRoute192 The gateway
ID 'vgw-0e7d969e316a7b5d5' does not exist (Service: AmazonEC2; Status
Code: 400; Error Code: InvalidGatewayID.NotFound; Request ID:
6d4cdb5f-31c5-4cf3-8777-3e3eb361d594)



14:06:04 UTC-0400 UPDATE_FAILED AWS::EC2::Route rRoute10 The gateway
ID 'vgw-0e7d969e316a7b5d5' does not exist (Service: AmazonEC2; Status
Code: 400; Error Code: InvalidGatewayID.NotFound; Request ID:
315ecc3a-d70c-46b7-b1cd-05f4c6765edd)



14:06:04 UTC-0400 UPDATE_FAILED AWS::EC2::Route rRoute172 The gateway
ID 'vgw-0e7d969e316a7b5d5' does not exist (Service: AmazonEC2; Status
Code: 400; Error Code: InvalidGatewayID.NotFound; Request ID:
2a6e20f0-4d41-4647-85f0-ffbfc0326680)




For background, someone deleted our VPG and created a different gateway. They also manually updated the routes. Now, I am trying to get the stack in sync on the route tables. However, the stack failed to update and now it fails to roll back.



Screenshot:
enter image description here



AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
RDS

SAM Template for creating an RDS in a secure Fault-Tolerant fashion...

Parameters:
pDBName:
Default: MyDatabase
Description: The database name
Type: String
MinLength: '1'
MaxLength: '64'
AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
ConstraintDescription: must begin with a letter and contain only alphanumeric characters.
pDBUser:
NoEcho: 'true'
Description: The database admin account username
Type: String
MinLength: '1'
MaxLength: '16'
AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
ConstraintDescription: must begin with a letter and contain only alphanumeric
characters.
pDBPassword:
NoEcho: 'true'
Description: The database admin account password
Type: String
MinLength: '1'
MaxLength: '41'
AllowedPattern: '[a-zA-Z0-9]+'
ConstraintDescription: must contain only alphanumeric characters.
pDBAllocatedStorage:
Default: '20'
Description: The size of the database (Gb)
Type: Number
MinValue: '20'
MaxValue: '16384'
ConstraintDescription: must be between 5 and 1024Gb.
pDBInstanceClass:
Description: The database instance type
Type: String
Default: db.t2.micro
AllowedValues: [db.t1.micro, db.m1.small, db.m1.medium, db.m1.large, db.m1.xlarge,
db.m2.xlarge, db.m2.2xlarge, db.m2.4xlarge, db.m3.medium, db.m3.large, db.m3.xlarge,
db.m3.2xlarge, db.m4.large, db.m4.xlarge, db.m4.2xlarge, db.m4.4xlarge, db.m4.10xlarge,
db.r3.large, db.r3.xlarge, db.r3.2xlarge, db.r3.4xlarge, db.r3.8xlarge, db.m2.xlarge,
db.m2.2xlarge, db.m2.4xlarge, db.cr1.8xlarge, db.t2.micro, db.t2.small, db.t2.medium,
db.t2.large]
ConstraintDescription: must select a valid database instance type.

# TODO - Future DBEngine allowed values: [aurora-mysql, aurora-postgresql, mariadb, oracle-ee, oracle-se2, sqlserver-ee, sqlserver-se, sqlserver-ex, sqlserver-web]
pDBEngine:
Description: The database type to create
Type: String
Default: oracle-se2
AllowedValues: [aurora-mysql, oracle-ee, oracle-se2]
ConstraintDescription: must select a valid database engine
pDBEngineVersion:
Description: The version of database to create
Type: String
pMultiAZ:
Description: Multi-AZ master database
Type: String
Default: 'false'
AllowedValues: ['true', 'false']
ConstraintDescription: must be true or false.
pDatabaseDeletionProtection:
Description: Do we even allow a database to be deleted?
Type: String
Default: 'false'
AllowedValues: ['true', 'false']
ConstraintDescription: must be true or false.
pDatabaseLicenseModel:
Description: What licensing do we use?
Type: String
Default: "license-included"
AllowedValues: ["license-included", "bring-your-own-license", "general-public-license"]
ConstraintDescription: must be license-included or bring-your-own-license or general-public-license
pDBParameterGroupName:
Description: Use an existing parameter group in Amazon RDS - must match the database.
Type: String
Default: "default.aurora-mysql5.7"
pStorageType: # https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_CreateDBInstance.html
Description: The type of storage to be used by the database.
Type: String
Default: 'standard'
AllowedValues: ['standard', 'gp2', 'io1']
pRDSVPC:
Description: The vpc to use?
Type: AWS::EC2::VPC::Id
pCreateNewSubnets:
Description: Set to true if we want new subnets for our databases
Type: String
Default: "true"
AllowedValues: ['true', 'false']
ConstraintDescription: must be true or false.
pExistingSubnetId1:
Description: Use an id of an existing private subnet
Type: String
Default: "subnet-0455e1cfa66facd17"
pExistingSubnetId2:
Description: Use an id of a second existing private subnet
Type: String
Default: "subnet-0536176832ba42dfd"
pSubnetCIDR1:
Description: The cidrblock to use?
Type: String
pSubnetCIDR2:
Description: The cidrblock to use?
Type: String
pGatewayID:
Description: The virtual private gateway id for the vpc, to manage our databases.
Type: String
Default: "vgw-0e7d969e316a7b5d5"
pOperatorEMail:
Description: EMail address to notify if there are any operational issues
Type: String
AllowedPattern: >-
([a-zA-Z0-9_-.]+)@(([[0-9]1,3.[0-9]1,3.[0-9]1,3.)|(([a-zA-Z0-9-]+.)+))([a-zA-Z]2,4|[0-9]1,3)(]?)
ConstraintDescription: must be a valid email address.

# This next parameter is a hold-over from older pipelines. It must exist, or there will be a cloudformation error.
BuildBucket:
Description: Unused in this template
Type: String
Default: ""


# Warning, I haven't actually tested all these databases or these mappings - be ready to debug :-)
Mappings:
DBPortMap:
aurora-mysql:
port: 3306
aurora-postgresql:
port: 5432
mariadb:
port: 3306
mysql:
port: 3306
oracle-ee:
port: 1521
oracle-se2:
port: 1521
postgres:
port: 5432
sqlserver-ee:
port: 1433
sqlserver-se:
port: 1433
sqlserver-ex:
port: 1433
sqlserver-web:
port: 1433

Conditions:
CreateMultiAZ: !Equals [ !Ref pMultiAZ, "true" ]
CreateNewSubnets: !Equals [ !Ref pCreateNewSubnets, "true" ]
CreateAurora: !Or
- !Equals [ !Ref pDBEngine, "aurora-mysql" ]
- !Equals [ !Ref pDBEngine, "aurora-postgresql" ]
CreateNonAurora: !Not [Condition: CreateAurora ]
CreateAuroraMultiAZ: !And
- Condition: CreateAurora
- Condition: CreateMultiAZ

Resources:
# TODO - SECURE THE PASSWARD PARAMETERS IN AWS PARAMETER STORE
# See: https://github.com/aws-samples/aws-aurora-cloudformation-samples/blob/master/cftemplates/Aurora-Postgres-DB-Cluster.yml
# TODO - DBClusterParameterGroups and DBParameterGroups are not auto-created.


# Subnets
#
# Create one subnet if pCreateNewSubnets is true
# Create two new subnets if both pCreateNewSubnets and pMultiAZ are true...
# Otherwise, the user better have specified existing subnet(s) in pExistingSubnetId1 and pExistingSubnetId2
#
# Note that this template assumes we use Availability Zones 0 and 1. Perhaps I should make those parameters?
#
rDBSubnet1:
Type: AWS::EC2::Subnet
Condition: CreateNewSubnets
Properties:
VpcId: !Ref 'pRDSVPC'
CidrBlock: !Ref 'pSubnetCIDR1'
AvailabilityZone: !Select
- 0
- !GetAZs
Ref: 'AWS::Region'
Tags:
- Key: "Name"
Value: !Join [ "-", [!Ref "AWS::StackName", !Ref "AWS::Region", "RDS-AZA-SUBNET"] ]

rDBSubnet2:
Type: AWS::EC2::Subnet
Condition: CreateNewSubnets
Properties:
VpcId: !Ref 'pRDSVPC'
CidrBlock: !Ref 'pSubnetCIDR2'
AvailabilityZone: !Select
- 1
- !GetAZs
Ref: 'AWS::Region'
Tags:
- Key: "Name"
Value: !Join [ "-", [!Ref "AWS::StackName", !Ref "AWS::Region", "RDS-AZB-SUBNET"] ]

# Route Table
#
# If we create new subnets, we need to use a route table. I thought about reusing the existing route table for the
# primary private subnet, but this is a different class of traffic. I feel it is best practice to create new route tables.
#
rCustomRouteTable:
Type: AWS::EC2::RouteTable
Condition: CreateNewSubnets
Properties:
VpcId: !Ref 'pRDSVPC'
Tags:
- Key: "Name"
Value: !Join [ "-", [!Ref "AWS::StackName", !Ref "AWS::Region", "RTB-RDS"] ]

rRoute10:
Type: AWS::EC2::Route
Condition: CreateNewSubnets
Properties:
RouteTableId: !Ref rCustomRouteTable
DestinationCidrBlock: 10.0.0.0/8
GatewayId: !Ref pGatewayID

rRoute172:
Type: AWS::EC2::Route
Condition: CreateNewSubnets
Properties:
RouteTableId: !Ref rCustomRouteTable
DestinationCidrBlock: 172.16.0.0/12
GatewayId: !Ref pGatewayID

rRoute192:
Type: AWS::EC2::Route
Condition: CreateNewSubnets
Properties:
RouteTableId: !Ref rCustomRouteTable
DestinationCidrBlock: 192.168.0.0/16
GatewayId: !Ref pGatewayID

# attach route tables to our previously created subnets.
rSubnetRouteTableAssociation1:
Type: AWS::EC2::SubnetRouteTableAssociation
Condition: CreateNewSubnets
Properties:
SubnetId: !Ref rDBSubnet1
RouteTableId: !Ref rCustomRouteTable

rSubnetRouteTableAssociation2:
Type: AWS::EC2::SubnetRouteTableAssociation
Condition: CreateNewSubnets
Properties:
SubnetId: !Ref rDBSubnet2
RouteTableId: !Ref rCustomRouteTable

# Security group.
#
# This is to make sure our databases only allow traffic on the correct port.
#
# Technically, we could be more specific than 0.0.0.0/0

rDBEC2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Open database for access
VpcId: !Ref pRDSVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: !FindInMap
- DBPortMap
- !Ref 'pDBEngine'
- port
ToPort: !FindInMap
- DBPortMap
- !Ref 'pDBEngine'
- port
CidrIp: 0.0.0.0/0
Description: !Ref 'pDBEngine'
Tags:
- Key: "Name"
Value: !Join [ "-", [!Ref "AWS::StackName", !Ref "AWS::Region", "RDS-SEC"] ]

# Subnet Groups
#
# Here is the deal. We don't attach subnets directly to databases. Rather, we group subnets and attach the group to the
# databases. So, here is the complex "if" logic to determine which subnets to put into our database subnet group.
rDBSubnetGroup:
Type: "AWS::RDS::DBSubnetGroup"
Properties:
DBSubnetGroupDescription: "description"
SubnetIds:
- !If [CreateNewSubnets, !Ref rDBSubnet1, !Ref pExistingSubnetId1 ]
- !If [CreateNewSubnets, !Ref rDBSubnet2, !Ref pExistingSubnetId2 ]

# Database Builds...
#
# Aurora builds... first
rDatabaseCluster:
Type: AWS::RDS::DBCluster
Condition: CreateAurora
Properties:
DatabaseName: !Ref 'pDBName'
Engine: !Ref 'pDBEngine'
EngineVersion: !Ref pDBEngineVersion
MasterUsername: !Ref 'pDBUser'
MasterUserPassword: !Ref 'pDBPassword'
DBSubnetGroupName: !Ref rDBSubnetGroup
DBClusterParameterGroupName: !Ref pDBParameterGroupName
DeletionProtection: !Ref 'pDatabaseDeletionProtection'
VpcSecurityGroupIds: [!GetAtt [rDBEC2SecurityGroup, GroupId]]

rAuroraDB1:
Type: AWS::RDS::DBInstance
Condition: CreateAurora
Properties:
CopyTagsToSnapshot: true
DBInstanceClass: !Ref 'pDBInstanceClass'
DBClusterIdentifier: !Ref rDatabaseCluster
DBSubnetGroupName: !Ref rDBSubnetGroup
Engine: !Ref 'pDBEngine'
EngineVersion: !Ref pDBEngineVersion
DBParameterGroupName: !Ref pDBParameterGroupName
PubliclyAccessible: false
LicenseModel: !Ref 'pDatabaseLicenseModel'

rAuroraDB2:
Type: AWS::RDS::DBInstance
Condition: CreateAuroraMultiAZ
Properties:
CopyTagsToSnapshot: true
DBInstanceClass: !Ref 'pDBInstanceClass'
DBClusterIdentifier: !Ref rDatabaseCluster
DBSubnetGroupName: !Ref rDBSubnetGroup
Engine: !Ref 'pDBEngine'
EngineVersion: !Ref pDBEngineVersion
DBParameterGroupName: !Ref pDBParameterGroupName
PubliclyAccessible: false
LicenseModel: !Ref 'pDatabaseLicenseModel'

# Now for the Non-Aurora builds...
rMasterDB:
Type: AWS::RDS::DBInstance
Condition: CreateNonAurora
Properties:
AllocatedStorage: !Ref 'pDBAllocatedStorage'
CopyTagsToSnapshot: true
DBInstanceClass: !Ref 'pDBInstanceClass'
DBName: !Ref 'pDBName'
DBSubnetGroupName: !Ref rDBSubnetGroup
Engine: !Ref 'pDBEngine'
EngineVersion: !Ref pDBEngineVersion
DBParameterGroupName: !Ref pDBParameterGroupName
MasterUsername: !Ref 'pDBUser'
MasterUserPassword: !Ref 'pDBPassword'
MultiAZ: !Ref 'pMultiAZ'
PubliclyAccessible: false
StorageType: !Ref 'pStorageType'
VPCSecurityGroups: [!GetAtt [rDBEC2SecurityGroup, GroupId]]
LicenseModel: !Ref 'pDatabaseLicenseModel'
DeletionProtection: !Ref 'pDatabaseDeletionProtection'

# Cloudwatch alarms
#
# Nothing too special here. I just make sure the DB is operational.
rAlarmTopic:
Type: 'AWS::SNS::Topic'
Properties:
Subscription:
- Endpoint: !Ref pOperatorEMail
Protocol: email

rCPUAlarmHighMasterDB:
Type: 'AWS::CloudWatch::Alarm'
Condition: CreateNonAurora
Properties:
EvaluationPeriods: 10
Statistic: Average
Threshold: 50
AlarmDescription: >-
Alarm if CPU too high or metric disappears indicating the RDS database
instance is having issues
Period: 60
Namespace: AWS/RDS
MetricName: CPUUtilization
Dimensions:
- Name: DBInstanceIdentifier
Value: !Ref rMasterDB
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref rAlarmTopic
InsufficientDataActions:
- !Ref rAlarmTopic

rCPUAlarmHighAuroraDB1:
Type: 'AWS::CloudWatch::Alarm'
Condition: CreateAurora
Properties:
EvaluationPeriods: 10
Statistic: Average
Threshold: 50
AlarmDescription: >-
Alarm if CPU too high or metric disappears indicating the RDS database
instance is having issues
Period: 60
Namespace: AWS/RDS
MetricName: CPUUtilization
Dimensions:
- Name: DBInstanceIdentifier
Value: !Ref rAuroraDB1
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref rAlarmTopic
InsufficientDataActions:
- !Ref rAlarmTopic

rCPUAlarmHighAuroraDB2:
Type: 'AWS::CloudWatch::Alarm'
Condition: CreateAuroraMultiAZ
Properties:
EvaluationPeriods: 10
Statistic: Average
Threshold: 50
AlarmDescription: >-
Alarm if CPU too high or metric disappears indicating the RDS database
instance is having issues
Period: 60
Namespace: AWS/RDS
MetricName: CPUUtilization
Dimensions:
- Name: DBInstanceIdentifier
Value: !Ref rAuroraDB2
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref rAlarmTopic
InsufficientDataActions:
- !Ref rAlarmTopic
#
# Consider adding JDBC string...
#
Outputs:
Name:
Description: Aurora Stack Name
Value: !Ref AWS::StackName
Export:
Name: !Sub $AWS::StackName-Name
RDSEndPointAddress:
Description: Database Endpoint Address
Value: !GetAtt [rMasterDB, Endpoint.Address]
Export:
Name: !Sub $AWS::StackName-RDSEndPointAddress
Condition: CreateNonAurora
RDSEndPointPort:
Description: Database Endpoint port
Value: !GetAtt [rMasterDB, Endpoint.Port]
Export:
Name: !Sub $AWS::StackName-RDSEndPointPort
Condition: CreateNonAurora
AuroraClusterId:
Description: Aurora Cluster ID
Value: !Ref rDatabaseCluster
Export:
Name: !Sub $AWS::StackName-AuroraClusterID
Condition: CreateAurora
AuroraEndPointAddress:
Description: Database Endpoint Address
Value: !GetAtt [rDatabaseCluster, Endpoint.Address]
Export:
Name: !Sub $AWS::StackName-AuroraDatabaseURL
Condition: CreateAurora
AuroraEndPointPort:
Description: Database Endpoint port
Value: !GetAtt [rDatabaseCluster, Endpoint.Port]
Export:
Name: !Sub $AWS::StackName-AuroraDatabasePort
Condition: CreateAurora
EndPointDBName:
Description: Database Name
Value: !Ref 'pDBName'
Export:
Name: !Sub $AWS::StackName-DBName
JDBCConnectionString:
Description: JDBC connection string for a mysql database
Value: !Join ['', ['jdbc:mysql://', !GetAtt [rDatabaseCluster, Endpoint.Address], ':', !GetAtt [
rDatabaseCluster, Endpoint.Port], /, !Ref 'pDBName']]
Export:
Name: !Sub $AWS::StackName-MySQLJDBCString
Condition: CreateAurora









share|improve this question
















Please help get past this. I have to enter 3 logical ids to rollback my update, but the regex in cloudformation doesn't allow for that because the regex doesn't appear to allow commas. But the continue ROLLBACK instructions from AWS clearly state to use commas:




"To skip resources, type a list of comma-separated logical
resource IDs. Include only the resources that are blocking the
rollback."




But the commas are not allowed by the cloudformation regex???? What am I missing here? I can't go forward or back. My cloudformation stack is stuck.



My error on trying to roll back:




Failed to rollback: 1 validation
error detected: Value '[rRoute10,rRoute192,rRoute172]' at
'resourcesToSkip' failed to satisfy constraint: Member must satisfy
constraint: [Member must satisfy regular expression pattern:
[a-zA-Z0-9]+|[a-zA-Z][-a-zA-Z0-9]*.[a-zA-Z0-9]+]




My errors in cloudformation:




14:06:04 UTC-0400 UPDATE_FAILED AWS::EC2::Route rRoute192 The gateway
ID 'vgw-0e7d969e316a7b5d5' does not exist (Service: AmazonEC2; Status
Code: 400; Error Code: InvalidGatewayID.NotFound; Request ID:
6d4cdb5f-31c5-4cf3-8777-3e3eb361d594)



14:06:04 UTC-0400 UPDATE_FAILED AWS::EC2::Route rRoute10 The gateway
ID 'vgw-0e7d969e316a7b5d5' does not exist (Service: AmazonEC2; Status
Code: 400; Error Code: InvalidGatewayID.NotFound; Request ID:
315ecc3a-d70c-46b7-b1cd-05f4c6765edd)



14:06:04 UTC-0400 UPDATE_FAILED AWS::EC2::Route rRoute172 The gateway
ID 'vgw-0e7d969e316a7b5d5' does not exist (Service: AmazonEC2; Status
Code: 400; Error Code: InvalidGatewayID.NotFound; Request ID:
2a6e20f0-4d41-4647-85f0-ffbfc0326680)




For background, someone deleted our VPG and created a different gateway. They also manually updated the routes. Now, I am trying to get the stack in sync on the route tables. However, the stack failed to update and now it fails to roll back.



Screenshot:
enter image description here



AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
RDS

SAM Template for creating an RDS in a secure Fault-Tolerant fashion...

Parameters:
pDBName:
Default: MyDatabase
Description: The database name
Type: String
MinLength: '1'
MaxLength: '64'
AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
ConstraintDescription: must begin with a letter and contain only alphanumeric characters.
pDBUser:
NoEcho: 'true'
Description: The database admin account username
Type: String
MinLength: '1'
MaxLength: '16'
AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
ConstraintDescription: must begin with a letter and contain only alphanumeric
characters.
pDBPassword:
NoEcho: 'true'
Description: The database admin account password
Type: String
MinLength: '1'
MaxLength: '41'
AllowedPattern: '[a-zA-Z0-9]+'
ConstraintDescription: must contain only alphanumeric characters.
pDBAllocatedStorage:
Default: '20'
Description: The size of the database (Gb)
Type: Number
MinValue: '20'
MaxValue: '16384'
ConstraintDescription: must be between 5 and 1024Gb.
pDBInstanceClass:
Description: The database instance type
Type: String
Default: db.t2.micro
AllowedValues: [db.t1.micro, db.m1.small, db.m1.medium, db.m1.large, db.m1.xlarge,
db.m2.xlarge, db.m2.2xlarge, db.m2.4xlarge, db.m3.medium, db.m3.large, db.m3.xlarge,
db.m3.2xlarge, db.m4.large, db.m4.xlarge, db.m4.2xlarge, db.m4.4xlarge, db.m4.10xlarge,
db.r3.large, db.r3.xlarge, db.r3.2xlarge, db.r3.4xlarge, db.r3.8xlarge, db.m2.xlarge,
db.m2.2xlarge, db.m2.4xlarge, db.cr1.8xlarge, db.t2.micro, db.t2.small, db.t2.medium,
db.t2.large]
ConstraintDescription: must select a valid database instance type.

# TODO - Future DBEngine allowed values: [aurora-mysql, aurora-postgresql, mariadb, oracle-ee, oracle-se2, sqlserver-ee, sqlserver-se, sqlserver-ex, sqlserver-web]
pDBEngine:
Description: The database type to create
Type: String
Default: oracle-se2
AllowedValues: [aurora-mysql, oracle-ee, oracle-se2]
ConstraintDescription: must select a valid database engine
pDBEngineVersion:
Description: The version of database to create
Type: String
pMultiAZ:
Description: Multi-AZ master database
Type: String
Default: 'false'
AllowedValues: ['true', 'false']
ConstraintDescription: must be true or false.
pDatabaseDeletionProtection:
Description: Do we even allow a database to be deleted?
Type: String
Default: 'false'
AllowedValues: ['true', 'false']
ConstraintDescription: must be true or false.
pDatabaseLicenseModel:
Description: What licensing do we use?
Type: String
Default: "license-included"
AllowedValues: ["license-included", "bring-your-own-license", "general-public-license"]
ConstraintDescription: must be license-included or bring-your-own-license or general-public-license
pDBParameterGroupName:
Description: Use an existing parameter group in Amazon RDS - must match the database.
Type: String
Default: "default.aurora-mysql5.7"
pStorageType: # https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_CreateDBInstance.html
Description: The type of storage to be used by the database.
Type: String
Default: 'standard'
AllowedValues: ['standard', 'gp2', 'io1']
pRDSVPC:
Description: The vpc to use?
Type: AWS::EC2::VPC::Id
pCreateNewSubnets:
Description: Set to true if we want new subnets for our databases
Type: String
Default: "true"
AllowedValues: ['true', 'false']
ConstraintDescription: must be true or false.
pExistingSubnetId1:
Description: Use an id of an existing private subnet
Type: String
Default: "subnet-0455e1cfa66facd17"
pExistingSubnetId2:
Description: Use an id of a second existing private subnet
Type: String
Default: "subnet-0536176832ba42dfd"
pSubnetCIDR1:
Description: The cidrblock to use?
Type: String
pSubnetCIDR2:
Description: The cidrblock to use?
Type: String
pGatewayID:
Description: The virtual private gateway id for the vpc, to manage our databases.
Type: String
Default: "vgw-0e7d969e316a7b5d5"
pOperatorEMail:
Description: EMail address to notify if there are any operational issues
Type: String
AllowedPattern: >-
([a-zA-Z0-9_-.]+)@(([[0-9]1,3.[0-9]1,3.[0-9]1,3.)|(([a-zA-Z0-9-]+.)+))([a-zA-Z]2,4|[0-9]1,3)(]?)
ConstraintDescription: must be a valid email address.

# This next parameter is a hold-over from older pipelines. It must exist, or there will be a cloudformation error.
BuildBucket:
Description: Unused in this template
Type: String
Default: ""


# Warning, I haven't actually tested all these databases or these mappings - be ready to debug :-)
Mappings:
DBPortMap:
aurora-mysql:
port: 3306
aurora-postgresql:
port: 5432
mariadb:
port: 3306
mysql:
port: 3306
oracle-ee:
port: 1521
oracle-se2:
port: 1521
postgres:
port: 5432
sqlserver-ee:
port: 1433
sqlserver-se:
port: 1433
sqlserver-ex:
port: 1433
sqlserver-web:
port: 1433

Conditions:
CreateMultiAZ: !Equals [ !Ref pMultiAZ, "true" ]
CreateNewSubnets: !Equals [ !Ref pCreateNewSubnets, "true" ]
CreateAurora: !Or
- !Equals [ !Ref pDBEngine, "aurora-mysql" ]
- !Equals [ !Ref pDBEngine, "aurora-postgresql" ]
CreateNonAurora: !Not [Condition: CreateAurora ]
CreateAuroraMultiAZ: !And
- Condition: CreateAurora
- Condition: CreateMultiAZ

Resources:
# TODO - SECURE THE PASSWARD PARAMETERS IN AWS PARAMETER STORE
# See: https://github.com/aws-samples/aws-aurora-cloudformation-samples/blob/master/cftemplates/Aurora-Postgres-DB-Cluster.yml
# TODO - DBClusterParameterGroups and DBParameterGroups are not auto-created.


# Subnets
#
# Create one subnet if pCreateNewSubnets is true
# Create two new subnets if both pCreateNewSubnets and pMultiAZ are true...
# Otherwise, the user better have specified existing subnet(s) in pExistingSubnetId1 and pExistingSubnetId2
#
# Note that this template assumes we use Availability Zones 0 and 1. Perhaps I should make those parameters?
#
rDBSubnet1:
Type: AWS::EC2::Subnet
Condition: CreateNewSubnets
Properties:
VpcId: !Ref 'pRDSVPC'
CidrBlock: !Ref 'pSubnetCIDR1'
AvailabilityZone: !Select
- 0
- !GetAZs
Ref: 'AWS::Region'
Tags:
- Key: "Name"
Value: !Join [ "-", [!Ref "AWS::StackName", !Ref "AWS::Region", "RDS-AZA-SUBNET"] ]

rDBSubnet2:
Type: AWS::EC2::Subnet
Condition: CreateNewSubnets
Properties:
VpcId: !Ref 'pRDSVPC'
CidrBlock: !Ref 'pSubnetCIDR2'
AvailabilityZone: !Select
- 1
- !GetAZs
Ref: 'AWS::Region'
Tags:
- Key: "Name"
Value: !Join [ "-", [!Ref "AWS::StackName", !Ref "AWS::Region", "RDS-AZB-SUBNET"] ]

# Route Table
#
# If we create new subnets, we need to use a route table. I thought about reusing the existing route table for the
# primary private subnet, but this is a different class of traffic. I feel it is best practice to create new route tables.
#
rCustomRouteTable:
Type: AWS::EC2::RouteTable
Condition: CreateNewSubnets
Properties:
VpcId: !Ref 'pRDSVPC'
Tags:
- Key: "Name"
Value: !Join [ "-", [!Ref "AWS::StackName", !Ref "AWS::Region", "RTB-RDS"] ]

rRoute10:
Type: AWS::EC2::Route
Condition: CreateNewSubnets
Properties:
RouteTableId: !Ref rCustomRouteTable
DestinationCidrBlock: 10.0.0.0/8
GatewayId: !Ref pGatewayID

rRoute172:
Type: AWS::EC2::Route
Condition: CreateNewSubnets
Properties:
RouteTableId: !Ref rCustomRouteTable
DestinationCidrBlock: 172.16.0.0/12
GatewayId: !Ref pGatewayID

rRoute192:
Type: AWS::EC2::Route
Condition: CreateNewSubnets
Properties:
RouteTableId: !Ref rCustomRouteTable
DestinationCidrBlock: 192.168.0.0/16
GatewayId: !Ref pGatewayID

# attach route tables to our previously created subnets.
rSubnetRouteTableAssociation1:
Type: AWS::EC2::SubnetRouteTableAssociation
Condition: CreateNewSubnets
Properties:
SubnetId: !Ref rDBSubnet1
RouteTableId: !Ref rCustomRouteTable

rSubnetRouteTableAssociation2:
Type: AWS::EC2::SubnetRouteTableAssociation
Condition: CreateNewSubnets
Properties:
SubnetId: !Ref rDBSubnet2
RouteTableId: !Ref rCustomRouteTable

# Security group.
#
# This is to make sure our databases only allow traffic on the correct port.
#
# Technically, we could be more specific than 0.0.0.0/0

rDBEC2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Open database for access
VpcId: !Ref pRDSVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: !FindInMap
- DBPortMap
- !Ref 'pDBEngine'
- port
ToPort: !FindInMap
- DBPortMap
- !Ref 'pDBEngine'
- port
CidrIp: 0.0.0.0/0
Description: !Ref 'pDBEngine'
Tags:
- Key: "Name"
Value: !Join [ "-", [!Ref "AWS::StackName", !Ref "AWS::Region", "RDS-SEC"] ]

# Subnet Groups
#
# Here is the deal. We don't attach subnets directly to databases. Rather, we group subnets and attach the group to the
# databases. So, here is the complex "if" logic to determine which subnets to put into our database subnet group.
rDBSubnetGroup:
Type: "AWS::RDS::DBSubnetGroup"
Properties:
DBSubnetGroupDescription: "description"
SubnetIds:
- !If [CreateNewSubnets, !Ref rDBSubnet1, !Ref pExistingSubnetId1 ]
- !If [CreateNewSubnets, !Ref rDBSubnet2, !Ref pExistingSubnetId2 ]

# Database Builds...
#
# Aurora builds... first
rDatabaseCluster:
Type: AWS::RDS::DBCluster
Condition: CreateAurora
Properties:
DatabaseName: !Ref 'pDBName'
Engine: !Ref 'pDBEngine'
EngineVersion: !Ref pDBEngineVersion
MasterUsername: !Ref 'pDBUser'
MasterUserPassword: !Ref 'pDBPassword'
DBSubnetGroupName: !Ref rDBSubnetGroup
DBClusterParameterGroupName: !Ref pDBParameterGroupName
DeletionProtection: !Ref 'pDatabaseDeletionProtection'
VpcSecurityGroupIds: [!GetAtt [rDBEC2SecurityGroup, GroupId]]

rAuroraDB1:
Type: AWS::RDS::DBInstance
Condition: CreateAurora
Properties:
CopyTagsToSnapshot: true
DBInstanceClass: !Ref 'pDBInstanceClass'
DBClusterIdentifier: !Ref rDatabaseCluster
DBSubnetGroupName: !Ref rDBSubnetGroup
Engine: !Ref 'pDBEngine'
EngineVersion: !Ref pDBEngineVersion
DBParameterGroupName: !Ref pDBParameterGroupName
PubliclyAccessible: false
LicenseModel: !Ref 'pDatabaseLicenseModel'

rAuroraDB2:
Type: AWS::RDS::DBInstance
Condition: CreateAuroraMultiAZ
Properties:
CopyTagsToSnapshot: true
DBInstanceClass: !Ref 'pDBInstanceClass'
DBClusterIdentifier: !Ref rDatabaseCluster
DBSubnetGroupName: !Ref rDBSubnetGroup
Engine: !Ref 'pDBEngine'
EngineVersion: !Ref pDBEngineVersion
DBParameterGroupName: !Ref pDBParameterGroupName
PubliclyAccessible: false
LicenseModel: !Ref 'pDatabaseLicenseModel'

# Now for the Non-Aurora builds...
rMasterDB:
Type: AWS::RDS::DBInstance
Condition: CreateNonAurora
Properties:
AllocatedStorage: !Ref 'pDBAllocatedStorage'
CopyTagsToSnapshot: true
DBInstanceClass: !Ref 'pDBInstanceClass'
DBName: !Ref 'pDBName'
DBSubnetGroupName: !Ref rDBSubnetGroup
Engine: !Ref 'pDBEngine'
EngineVersion: !Ref pDBEngineVersion
DBParameterGroupName: !Ref pDBParameterGroupName
MasterUsername: !Ref 'pDBUser'
MasterUserPassword: !Ref 'pDBPassword'
MultiAZ: !Ref 'pMultiAZ'
PubliclyAccessible: false
StorageType: !Ref 'pStorageType'
VPCSecurityGroups: [!GetAtt [rDBEC2SecurityGroup, GroupId]]
LicenseModel: !Ref 'pDatabaseLicenseModel'
DeletionProtection: !Ref 'pDatabaseDeletionProtection'

# Cloudwatch alarms
#
# Nothing too special here. I just make sure the DB is operational.
rAlarmTopic:
Type: 'AWS::SNS::Topic'
Properties:
Subscription:
- Endpoint: !Ref pOperatorEMail
Protocol: email

rCPUAlarmHighMasterDB:
Type: 'AWS::CloudWatch::Alarm'
Condition: CreateNonAurora
Properties:
EvaluationPeriods: 10
Statistic: Average
Threshold: 50
AlarmDescription: >-
Alarm if CPU too high or metric disappears indicating the RDS database
instance is having issues
Period: 60
Namespace: AWS/RDS
MetricName: CPUUtilization
Dimensions:
- Name: DBInstanceIdentifier
Value: !Ref rMasterDB
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref rAlarmTopic
InsufficientDataActions:
- !Ref rAlarmTopic

rCPUAlarmHighAuroraDB1:
Type: 'AWS::CloudWatch::Alarm'
Condition: CreateAurora
Properties:
EvaluationPeriods: 10
Statistic: Average
Threshold: 50
AlarmDescription: >-
Alarm if CPU too high or metric disappears indicating the RDS database
instance is having issues
Period: 60
Namespace: AWS/RDS
MetricName: CPUUtilization
Dimensions:
- Name: DBInstanceIdentifier
Value: !Ref rAuroraDB1
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref rAlarmTopic
InsufficientDataActions:
- !Ref rAlarmTopic

rCPUAlarmHighAuroraDB2:
Type: 'AWS::CloudWatch::Alarm'
Condition: CreateAuroraMultiAZ
Properties:
EvaluationPeriods: 10
Statistic: Average
Threshold: 50
AlarmDescription: >-
Alarm if CPU too high or metric disappears indicating the RDS database
instance is having issues
Period: 60
Namespace: AWS/RDS
MetricName: CPUUtilization
Dimensions:
- Name: DBInstanceIdentifier
Value: !Ref rAuroraDB2
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref rAlarmTopic
InsufficientDataActions:
- !Ref rAlarmTopic
#
# Consider adding JDBC string...
#
Outputs:
Name:
Description: Aurora Stack Name
Value: !Ref AWS::StackName
Export:
Name: !Sub $AWS::StackName-Name
RDSEndPointAddress:
Description: Database Endpoint Address
Value: !GetAtt [rMasterDB, Endpoint.Address]
Export:
Name: !Sub $AWS::StackName-RDSEndPointAddress
Condition: CreateNonAurora
RDSEndPointPort:
Description: Database Endpoint port
Value: !GetAtt [rMasterDB, Endpoint.Port]
Export:
Name: !Sub $AWS::StackName-RDSEndPointPort
Condition: CreateNonAurora
AuroraClusterId:
Description: Aurora Cluster ID
Value: !Ref rDatabaseCluster
Export:
Name: !Sub $AWS::StackName-AuroraClusterID
Condition: CreateAurora
AuroraEndPointAddress:
Description: Database Endpoint Address
Value: !GetAtt [rDatabaseCluster, Endpoint.Address]
Export:
Name: !Sub $AWS::StackName-AuroraDatabaseURL
Condition: CreateAurora
AuroraEndPointPort:
Description: Database Endpoint port
Value: !GetAtt [rDatabaseCluster, Endpoint.Port]
Export:
Name: !Sub $AWS::StackName-AuroraDatabasePort
Condition: CreateAurora
EndPointDBName:
Description: Database Name
Value: !Ref 'pDBName'
Export:
Name: !Sub $AWS::StackName-DBName
JDBCConnectionString:
Description: JDBC connection string for a mysql database
Value: !Join ['', ['jdbc:mysql://', !GetAtt [rDatabaseCluster, Endpoint.Address], ':', !GetAtt [
rDatabaseCluster, Endpoint.Port], /, !Ref 'pDBName']]
Export:
Name: !Sub $AWS::StackName-MySQLJDBCString
Condition: CreateAurora






amazon-cloudformation






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 28 at 22:50







Paul Fowler

















asked Mar 28 at 19:22









Paul FowlerPaul Fowler

256 bronze badges




256 bronze badges















  • Can you please add a screenshot of the all the failed events listed under the Events tab?

    – Hassan Mussana
    Mar 28 at 21:59











  • Absolutely. Note that the order of events was as follows: 1) deployed a stack with routes that included VPG. 2) someone manually changed the VPG and manually altered the route tables. 3) updated stack to have correct route tables. 4) stack update failed (Reason: "Route did not stabilize in expected time") 5) stack went into "UPDATE_ROLLBACK_FAILED" 6) now, we can't get out of that status.

    – Paul Fowler
    Mar 28 at 22:23











  • Are you using nested stacks, can you post your CloudFormation yaml here (obfuscate any critical info)?

    – Hassan Mussana
    Mar 28 at 22:33











  • No nested stacks...

    – Paul Fowler
    Mar 28 at 22:45






  • 1





    Nope, it is not a bug I think. CLI just shows the programmatic way of doing it so that would be more accurate anyway. I think the console just takes the input without quotes and [ ]. I used the option a while ago so don't remember but will reproduce this and test it from the console as well.

    – Hassan Mussana
    Mar 29 at 9:54

















  • Can you please add a screenshot of the all the failed events listed under the Events tab?

    – Hassan Mussana
    Mar 28 at 21:59











  • Absolutely. Note that the order of events was as follows: 1) deployed a stack with routes that included VPG. 2) someone manually changed the VPG and manually altered the route tables. 3) updated stack to have correct route tables. 4) stack update failed (Reason: "Route did not stabilize in expected time") 5) stack went into "UPDATE_ROLLBACK_FAILED" 6) now, we can't get out of that status.

    – Paul Fowler
    Mar 28 at 22:23











  • Are you using nested stacks, can you post your CloudFormation yaml here (obfuscate any critical info)?

    – Hassan Mussana
    Mar 28 at 22:33











  • No nested stacks...

    – Paul Fowler
    Mar 28 at 22:45






  • 1





    Nope, it is not a bug I think. CLI just shows the programmatic way of doing it so that would be more accurate anyway. I think the console just takes the input without quotes and [ ]. I used the option a while ago so don't remember but will reproduce this and test it from the console as well.

    – Hassan Mussana
    Mar 29 at 9:54
















Can you please add a screenshot of the all the failed events listed under the Events tab?

– Hassan Mussana
Mar 28 at 21:59





Can you please add a screenshot of the all the failed events listed under the Events tab?

– Hassan Mussana
Mar 28 at 21:59













Absolutely. Note that the order of events was as follows: 1) deployed a stack with routes that included VPG. 2) someone manually changed the VPG and manually altered the route tables. 3) updated stack to have correct route tables. 4) stack update failed (Reason: "Route did not stabilize in expected time") 5) stack went into "UPDATE_ROLLBACK_FAILED" 6) now, we can't get out of that status.

– Paul Fowler
Mar 28 at 22:23





Absolutely. Note that the order of events was as follows: 1) deployed a stack with routes that included VPG. 2) someone manually changed the VPG and manually altered the route tables. 3) updated stack to have correct route tables. 4) stack update failed (Reason: "Route did not stabilize in expected time") 5) stack went into "UPDATE_ROLLBACK_FAILED" 6) now, we can't get out of that status.

– Paul Fowler
Mar 28 at 22:23













Are you using nested stacks, can you post your CloudFormation yaml here (obfuscate any critical info)?

– Hassan Mussana
Mar 28 at 22:33





Are you using nested stacks, can you post your CloudFormation yaml here (obfuscate any critical info)?

– Hassan Mussana
Mar 28 at 22:33













No nested stacks...

– Paul Fowler
Mar 28 at 22:45





No nested stacks...

– Paul Fowler
Mar 28 at 22:45




1




1





Nope, it is not a bug I think. CLI just shows the programmatic way of doing it so that would be more accurate anyway. I think the console just takes the input without quotes and [ ]. I used the option a while ago so don't remember but will reproduce this and test it from the console as well.

– Hassan Mussana
Mar 29 at 9:54





Nope, it is not a bug I think. CLI just shows the programmatic way of doing it so that would be more accurate anyway. I think the console just takes the input without quotes and [ ]. I used the option a while ago so don't remember but will reproduce this and test it from the console as well.

– Hassan Mussana
Mar 29 at 9:54












1 Answer
1






active

oldest

votes


















2
















So after a little bit of digging, this seems to be the best way to do it.

AWS CLI documentation is a bit more clear on this and expects syntax for logical IDs in this format as per the link above: "string" "string" ... with continue-update-rollback operation.






share|improve this answer



























    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );














    draft saved

    draft discarded
















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55405405%2fcloudformation-stuck-in-update-rollback-failed%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2
















    So after a little bit of digging, this seems to be the best way to do it.

    AWS CLI documentation is a bit more clear on this and expects syntax for logical IDs in this format as per the link above: "string" "string" ... with continue-update-rollback operation.






    share|improve this answer





























      2
















      So after a little bit of digging, this seems to be the best way to do it.

      AWS CLI documentation is a bit more clear on this and expects syntax for logical IDs in this format as per the link above: "string" "string" ... with continue-update-rollback operation.






      share|improve this answer



























        2














        2










        2









        So after a little bit of digging, this seems to be the best way to do it.

        AWS CLI documentation is a bit more clear on this and expects syntax for logical IDs in this format as per the link above: "string" "string" ... with continue-update-rollback operation.






        share|improve this answer













        So after a little bit of digging, this seems to be the best way to do it.

        AWS CLI documentation is a bit more clear on this and expects syntax for logical IDs in this format as per the link above: "string" "string" ... with continue-update-rollback operation.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Mar 28 at 22:51









        Hassan MussanaHassan Mussana

        3292 silver badges11 bronze badges




        3292 silver badges11 bronze badges

































            draft saved

            draft discarded















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55405405%2fcloudformation-stuck-in-update-rollback-failed%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

            Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

            Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript