aws-cloudformation / aws-cloudformation/cloudformation-coverage-roadmap

AWS::ElasticLoadBalancingV2::Listener - [BUG] - Removing ELB Trust store does not actually disaccociated underlying resource when using mTLS

Open
#2,497 2 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
No language data
Stars
1.1k
Forks
62
PR merge metrics
No merged PRs in 30d

Description

### Name of the resource

AWS::ElasticLoadBalancingV2::Listener

### Resource Name

_No response_

### Issue Description

Removing https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-elasticloadbalancingv2-listener-mutualauthentication.html has no effect.

When changing an ALB Listener definition from something like:
```yml
TestAlbHttpsListenerXXXX:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
Certificates:
- CertificateArn:
Ref: TestCertCertificateXXX
DefaultActions:
- FixedResponseConfig:
ContentType: text/plain
MessageBody: OK
StatusCode: "200"
Type: fixed-response
LoadBalancerArn:
Ref: TestAlbXXX
MutualAuthentication:
IgnoreClientCertificateExpiry: true
Mode: verify
TrustStoreArn:
Fn::GetAtt:
- MtlsAuthTrustStoreXXX
- TrustStoreArn
Port: 443
Protocol: HTTPS
```

To

```yml
TestAlbHttpsListenerXXX:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
Certificates:
- CertificateArn:
Ref: TestCertCertificateXX
DefaultActions:
- FixedResponseConfig:
ContentType: text/plain
MessageBody: OK
StatusCode: "200"
Type: fixed-response
LoadBalancerArn:
Ref: TestAlbXXX
Port: 443
Protocol: HTTPS
```
The trust store does not actually disassociate from the listener.

Post removing the attribute the mTLS verification is still attached to the listener with no error and the deployment marked as complete but the mTLS is still applied to the listener with **no** changes.

Image

### Expected Behavior

An error of it is not possible to disassociate the trust store from the listener or for the trust store to be disassociated from the listener altogether

### Observed Behavior

Nothing happens when removing the `MutualAuthentication` key config in the underlying AWS infrastructure. The deployment passes as normal and the CF state successfully updates leading to unexpected drift.

### Test Cases

Here is an example stack based on the one causing this issue.
This is Slop from Opus4.6 given cannot share the stack this is actually a part of unfortunately but the setup is pretty much as given here.

Just remember to delete the the trust store association after to recreate the desync:
```yml
AWSTemplateFormatVersion: "2010-09-09"
Description: Minimal example demonstrating ALB with mTLS trust store association

Parameters:
HostedZoneId:
Type: String
Description: The Route53 hosted zone ID for DNS validation
DomainName:
Type: String
Default: mtls-example.demo.example.com
Description: Domain name for the ALB

Resources:
# VPC with two public subnets
Vpc:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: true
EnableDnsSupport: true

PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref Vpc
AvailabilityZone: !Select [0, !GetAZs ""]
CidrBlock: 10.0.0.0/24
MapPublicIpOnLaunch: true

PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref Vpc
AvailabilityZone: !Select [1, !GetAZs ""]
CidrBlock: 10.0.1.0/24
MapPublicIpOnLaunch: true

InternetGateway:
Type: AWS::EC2::InternetGateway

VpcGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref Vpc

RouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref Vpc

DefaultRoute:
Type: AWS::EC2::Route
DependsOn: VpcGatewayAttachment
Properties:
RouteTableId: !Ref RouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway

Subnet1RouteTableAssoc:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet1
RouteTableId: !Ref RouteTable

Subnet2RouteTableAssoc:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet2
RouteTableId: !Ref RouteTable

# ACM Certificate (DNS validated)
Certificate:
Type: AWS::CertificateManager::Certificate
Properties:
DomainName: !Ref DomainName
DomainValidationOptions:
- DomainName: !Ref DomainName
HostedZoneId: !Ref HostedZoneId
ValidationMethod: DNS

# S3 bucket for CA certificate bundle
CaCertBucket:
Type: AWS::S3::Bucket
Properties:
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true

# ALB Trust Store
TrustStore:
Type: AWS::ElasticLoadBalancingV2::TrustStore
Properties:
CaCertificatesBundleS3Bucket: !Ref CaCertBucket
CaCertificatesBundleS3Key: ca-certs/rootCA.pem
Name: ExampleTrustStore

# ALB Security Group
AlbSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security group for example ALB
VpcId: !Ref Vpc
SecurityGroupIngress:
- CidrIp: 0.0.0.0/0
FromPort: 443
ToPort: 443
IpProtocol: tcp
SecurityGroupEgress:
- CidrIp: 255.255.255.255/32
Description: Disallow all traffic
FromPort: 252
IpProtocol: icmp
ToPort: 86

# Application Load Balancer
Alb:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
DependsOn:
- DefaultRoute
- Subnet1RouteTableAssoc
- Subnet2RouteTableAssoc
Properties:
Scheme: internet-facing
Type: application
SecurityGroups:
- !GetAtt AlbSecurityGroup.GroupId
Subnets:
- !Ref PublicSubnet1
- !Ref PublicSubnet2
LoadBalancerAttributes:
- Key: deletion_protection.enabled
Value: "false"

# HTTPS Listener with mTLS trust store association
HttpsListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
LoadBalancerArn: !Ref Alb
Port: 443
Protocol: HTTPS
Certificates:
- CertificateArn: !Ref Certificate
# ====================== REMOVE THIS TO POST DEPLOYMENT ======================
MutualAuthentication:
Mode: verify
TrustStoreArn: !GetAtt TrustStore.TrustStoreArn
# ============================================================================
DefaultActions:
- Type: fixed-response
FixedResponseConfig:
ContentType: text/plain
MessageBody: OK
StatusCode: "200"

# DNS Record
DnsRecord:
Type: AWS::Route53::RecordSet
Properties:
HostedZoneId: !Ref HostedZoneId
Name: !Ref DomainName
Type: CNAME
TTL: "1800"
ResourceRecords:
- !GetAtt Alb.DNSName

Outputs:
AlbDnsName:
Value: !GetAtt Alb.DNSName
TrustStoreArn:
Value: !GetAtt TrustStore.TrustStoreArn
ListenerArn:
Value: !Ref HttpsListener
```

### Other Details

_No response_

Contributor guide

Open the contributing guide

Research direction

Start with the minimal CloudFormation template in the issue and reproduce the deployment, then remove MutualAuthentication from HttpsListener and inspect the underlying listener state. Done means the trust store is disassociated, or deployment reports that disassociation is unsupported instead of completing with drift.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws
Domain
cloud, infrastructure
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.