aws-cloudformation / cloudformation-coverage-roadmap

The AWS CloudFormation Public Coverage Roadmap
https://aws.amazon.com/cloudformation/
Creative Commons Attribution Share Alike 4.0 International
1.11k stars 56 forks source link

(AWS::RDS::DBInstance) Cannot replace instance when using CACertificateIdentifier/CertificateRotationRestart #1742

Closed FarrOut closed 4 months ago

FarrOut commented 1 year ago

Name of the resource

AWS::RDS::DBInstance

Resource Name

No response

Issue Description

AWS::RDS::DBInstance cannot be modified with replacing updates when CACertificateIdentifier and CertificateRotationRestart properties are implemented.

For example: Modifying instance class fails with:

Resource handler returned message: "CACertificateIdentifier is required to use the NoCertificateRotationRestart option.

Expected Behavior

Replacing updates to AWS::RDS::DBInstance should succeed, even with CACertificateIdentifier and CertificateRotationRestart properties defined.

Observed Behavior

Resource handler returned message: "CACertificateIdentifier is required to use the NoCertificateRotationRestart option.

ModifyDBInstance

{
    "eventVersion": "1.08",
    "userIdentity": {
        "type": "IAMUser",
        "principalId": "xxxxxxxxxxxxxxx",
        "arn": "arn:aws:iam::000000000000:user/bob",
        "accountId": "000000000000",
        "accessKeyId": "xxxxxxxxxxxxxxx",
        "userName": "bob",
        "sessionContext": {
            "sessionIssuer": {},
            "webIdFederationData": {},
            "attributes": {
                "creationDate": "2023-07-10T06:22:39Z",
                "mfaAuthenticated": "false"
            }
        },
        "invokedBy": "cloudformation.amazonaws.com"
    },
    "eventTime": "2023-07-10T06:22:47Z",
    "eventSource": "rds.amazonaws.com",
    "eventName": "ModifyDBInstance",
    "awsRegion": "eu-west-1",
    "sourceIPAddress": "cloudformation.amazonaws.com",
    "userAgent": "cloudformation.amazonaws.com",
    "errorCode": "InvalidParameterCombinationException",
    "errorMessage": "CACertificateIdentifier is required to use the NoCertificateRotationRestart option.",
    "requestParameters": {
        "dBInstanceIdentifier": "rds-instancec1063a87-xxxxxxxxxxxxxxx",
        "dBInstanceClass": "db.t3.medium",
        "applyImmediately": true,
        "allowMajorVersionUpgrade": false,
        "certificateRotationRestart": false
    },
    "responseElements": null,
    "requestID": "8de0ba93-04ea-4704-ba60-xxxxxxxxxxxxxxx",
    "eventID": "3fc7aa35-91e7-4267-9df6-xxxxxxxxxxxxxxx",
    "readOnly": false,
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "000000000000",
    "eventCategory": "Management"
}

Test Cases

  1. Create stack
    
    # aws cloudformation deploy --stack-name rds --template-file template.yaml

Resources: ParameterGroup5E32DECB: Type: AWS::RDS::DBParameterGroup Properties: Description: Testing drift Family: postgres15 Parameters: shared_preload_libraries: pg_stat_statements track_activity_query_size: "4097" InstanceSubnetGroupF2CBA54F: Type: AWS::RDS::DBSubnetGroup Properties: DBSubnetGroupDescription: Subnet group for Instance database SubnetIds:


2. Change instance class.

```DBInstanceClass: db.t3.medium``` -> ```db.r5.large```

3. Update stack

BOOM.

### Other Details

### Workaround

1. Continue Rollback

First, we'll need to bring the stack out of the UPDATE_ROLLBACK_FAILED state and back into an actionable state. We do this by executing a continue-update-rollback command, skipping the RDS Instance resource. An example of what such command might look for you is as follows:

    aws cloudformation continue-update-rollback --stack-name rds-stack --resources-to-skip RdsInstance

2) Update instance class

We can now update the instance class once more. But to do so we will need to temporarily delete or comment-out the CACertificateIdentifier and CertificateRotationRestart properties! This allows the instance to modify its instance class, whilst avoiding the conflict that is currently blocking us. It is interesting to note that the actual Certificate authority value of the instance doesn't change during this process.

RdsInstance: Type: AWS::RDS::DBInstance Properties: AllocatedStorage: "100" CopyTagsToSnapshot: true DBInstanceClass: db.t3.medium

DBInstanceClass: db.r5.large <--- Change

  DBParameterGroupName:
    Ref: ParameterGroup5EXXX
  DBSubnetGroupName:
    Ref: InstanceSubnetGroupF2CXXXX
  Engine: postgres
  EngineVersion: "15.3"
  MasterUsername: syscdk
  # CertificateRotationRestart: false               <--- Remove
  # CACertificateIdentifier: "rds-ca-rsa2048-g1"    <--- Remove


3) Replace Certificate authority properties

Once the stack has updated the instance class, we will now perform another update to replace the CACertificateIdentifier and CertificateRotationRestart properties, bringing the stack into the desired state.
Onolisk commented 1 year ago

To add further context to this issue, the ModifyDBInstance API call made by CloudFormation is simply not inclining the required parameter CACertificateIdentifier when it should [1]. The DescribeDBInstance API call is made before ModifyDBInstance, and DescribeDBInstance does include the property CACertificateIdentifier so this likely just needs to be added into the logic.

    "errorCode": "InvalidParameterCombinationException",
    "errorMessage": "CACertificateIdentifier is required to use the NoCertificateRotationRestart option.",
    "requestParameters": {
        "dBInstanceIdentifier": "mydbInstanceIdentifer",
        "applyImmediately": true,
        "allowMajorVersionUpgrade": true,
        "autoMinorVersionUpgrade": true,
        "certificateRotationRestart": false
    },

[1] https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_ModifyDBInstance.html