aws-cloudformation / aws-cloudformation/cloudformation-coverage-roadmap
AWS::DMS::Endpoint - [BUG] - False-positive drift on KmsKeyId when the template uses the bare key ID
- Dominant language
- No language data
- Stars
- 1.1k
- Forks
- 62
- PR merge metrics
- No merged PRs in 30d
Description
### Name of the resource
AWS::DMS::Endpoint
### Resource Name
_No response_
### Issue Description
Drift detection reports a false-positive drift on the `KmsKeyId` property of `AWS::DMS::Endpoint` when the template specifies the KMS key as a bare key ID. On create, DMS stores the key as its full ARN, so drift detection compares the template value (key ID) against the stored value (ARN) and reports `NOT_EQUAL`, although both refer to the same key and nothing changed after deployment.
Specifying the same key by alias or by full ARN does not drift, and omitting the property does not drift either. So only the bare key ID form is affected.
We know drift detection on `KmsKeyId` is a documented limitation in general. We still raise it for `AWS::DMS::Endpoint` because a bare key ID is a natural template value, the property is documented only as a generic "KMS key identifier" (String) without stating which form to use, and a `NOT_EQUAL` on an encryption key always has to be triaged even when harmless.
The impact is made worse by the fact that `KmsKeyId` is `Update requires: Replacement` (see the [AWS::DMS::Endpoint docs](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dms-endpoint.html#cfn-dms-endpoint-kmskeyid)). Changing the template to the alias or ARN form just to silence the drift replaces the endpoint, and with it affects the replication tasks that depend on it. So normalizing `KmsKeyId` in drift detection is the better fix.
### Expected Behavior
An endpoint whose `KmsKeyId` refers to the same key as the template should stay `IN_SYNC`. Drift detection should treat a bare key ID and its corresponding ARN as equal, so specifying the key by ID does not produce drift (consistent with the alias and ARN forms, which already stay in sync).
### Observed Behavior
One stack with a dedicated KMS key and four source endpoints, one per `KmsKeyId` form. Drift result (us-east-1), no manual changes:
```
EndpointNoKey (KmsKeyId not set) -> IN_SYNC
EndpointKeyArn (KmsKeyId as full ARN) -> IN_SYNC
EndpointKeyAlias (KmsKeyId as alias/...) -> IN_SYNC
EndpointKeyId (KmsKeyId as bare key ID) -> MODIFIED
/KmsKeyId
ExpectedValue: f21703d5-abb2-4019-bc46-bdc10d14b1bd
ActualValue: arn:aws:kms:us-east-1::key/f21703d5-abb2-4019-bc46-bdc10d14b1bd
```
Only `EndpointKeyId` (bare key ID) is reported as drifted; the Actual value is simply the ARN of the same key.
This is confirmed by the DMS API: `describe-endpoints` returns the same key ARN for all three endpoints that point at this key (the ones created with the key ID, the alias, and the ARN). The actual state is identical in every case, so there is no real difference. CloudFormation clearly resolves an alias to its ARN (the alias endpoint stays `IN_SYNC`), but does not apply the same resolution to a bare key ID, which is why only that form is reported as drift.
```
describe-endpoints (same key f21703d5-...):
endpointkeyalias -> arn:aws:kms:us-east-1::key/f21703d5-...
endpointkeyarn -> arn:aws:kms:us-east-1::key/f21703d5-...
endpointkeyid -> arn:aws:kms:us-east-1::key/f21703d5-...
```
### Test Cases
Deploy this self-contained template (a dedicated KMS key, its alias, and four mysql source endpoints with placeholder hosts; endpoints are only created, never connected; no replication instance or database needed). The alias endpoint uses `DependsOn` so the alias exists before the endpoint is created. Then run drift detection and inspect each endpoint.
```yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: Repro - false-positive drift on DMS Endpoint KmsKeyId (bare key ID vs alias/ARN)
Resources:
DmsKey:
Type: AWS::KMS::Key
Properties:
Description: Repro key for DMS endpoint KmsKeyId drift test
KeyPolicy:
Version: '2012-10-17'
Statement:
- Sid: Enable IAM root permissions
Effect: Allow
Principal:
AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:root'
Action: 'kms:*'
Resource: '*'
DmsKeyAlias:
Type: AWS::KMS::Alias
Properties:
AliasName: alias/dms-drift-repro-key
TargetKeyId: !Ref DmsKey
EndpointNoKey:
Type: AWS::DMS::Endpoint
Properties:
EndpointType: source
EngineName: mysql
ServerName: a.example.invalid
Port: 3306
Username: repro
Password: ReproPlaceholder123
EndpointKeyId:
Type: AWS::DMS::Endpoint
Properties:
EndpointType: source
EngineName: mysql
ServerName: b.example.invalid
Port: 3306
Username: repro
Password: ReproPlaceholder123
KmsKeyId: !Ref DmsKey
EndpointKeyArn:
Type: AWS::DMS::Endpoint
Properties:
EndpointType: source
EngineName: mysql
ServerName: c.example.invalid
Port: 3306
Username: repro
Password: ReproPlaceholder123
KmsKeyId: !GetAtt DmsKey.Arn
EndpointKeyAlias:
Type: AWS::DMS::Endpoint
DependsOn: DmsKeyAlias
Properties:
EndpointType: source
EngineName: mysql
ServerName: d.example.invalid
Port: 3306
Username: repro
Password: ReproPlaceholder123
KmsKeyId: alias/dms-drift-repro-key
```
Steps:
1. Deploy the stack and wait for `CREATE_COMPLETE`.
2. Run drift detection (Console: Stack actions -> Detect drift, or CLI `detect-stack-drift`).
3. Inspect drift details per endpoint.
`EndpointKeyId` shows `MODIFIED` on `/KmsKeyId` (Expected key ID, Actual ARN), while `EndpointKeyArn`, `EndpointKeyAlias`, and `EndpointNoKey` stay `IN_SYNC`.
### Other Details
Verified in `us-east-1` with a freshly deployed stack; no manual changes were made before running drift detection. A practical workaround is to specify `KmsKeyId` as an alias or as the full ARN, both of which stay `IN_SYNC`; the alias form is convenient for a single template used across environments. AWS Support case 178853082300312 tracks this internally.
Contributor guide
Research direction
Start with the self-contained YAML reproduction in the issue, deploy it, and run CloudFormation drift detection with detect-stack-drift. Compare the four DMS endpoints and verify that the bare key ID case is treated like the alias and ARN cases, remaining IN_SYNC when the key is unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws
- Domain
- cloud, infrastructure
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100