Can't set 'access_logs.s3.bucket' back to 'false' for ALB using CloudFormation

0

I'm trying to turn on ALB access logs conditionally using CloudFormation as follows:

  LoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: !Join ['-', [!Ref 'AWS::StackName', ALB]]
      Type: application
      IpAddressType: !If [DoEnableIPv6Support, dualstack, ipv4]
      Scheme: internet-facing
      Subnets:
        - !Ref PublicSubnet1
        - !Ref PublicSubnet2
        - !Ref PublicSubnet3
        - !Ref PublicSubnet4
        - !Ref PublicSubnet5
        - !Ref PublicSubnet6
      SecurityGroups:
        - !Ref ALBSecurityGroup
      LoadBalancerAttributes:
        - Key: access_logs.s3.enabled
          Value: !If [EnableLoadBalancerAccessLogs, "true", "false"]
        - Key: access_logs.s3.bucket
          Value: !If [EnableLoadBalancerAccessLogs, !Ref AccessLogsBucket, ""]
        - Key: access_logs.s3.prefix
          Value: !If [EnableLoadBalancerAccessLogs, !Sub "${AWS::StackName}-ALB", ""]
      Tags:
        - Key: 'Stack'
          Value: !Ref 'AWS::StackName'

However, when EnableLoadBalancerAccessLogs is false, I'm running into this error:

The value of 'access_logs.s3.bucket' cannot be empty (Service: AmazonElasticLoadBalancing; Status Code: 400; Error Code: ValidationError; Request ID: REDACTED; Proxy: null)

The condition EnableLoadBalancerAccessLogs was defined as follows:

EnableLoadBalancerAccessLogs: !Not [!Equals [AccessLogsBucket, ""]]

I've also tried some potential workarounds for LoadBalancerAttributes, like

      LoadBalancerAttributes:
        - Key: access_logs.s3.enabled
          Value: !If [EnableLoadBalancerAccessLogs, "true", "false"]
        - !If
          - EnableLoadBalancerAccessLogs
          - Key: access_logs.s3.bucket
            Value: !Ref AccessLogsBucket
          - !Ref AWS::NoValue
        - !If
          - EnableLoadBalancerAccessLogs
          - Key: access_logs.s3.prefix
            Value: !Sub "${AWS::StackName}-ALB"
          - !Ref AWS::NoValue

or

      LoadBalancerAttributes: !If
        - EnableLoadBalancerAccessLogs
        - - Key: access_logs.s3.enabled
            Value: "true"
          - Key: access_logs.s3.bucket
            Value: !Ref AccessLogsBucket
          - Key: access_logs.s3.prefix
            Value: !Sub "${AWS::StackName}-ALB"
        - !Ref AWS::NoValue

but none of them worked.

CloudFormation docs says

access_logs.s3.bucket - The name of the S3 bucket for the access logs. This attribute is required if access logs are enabled. The bucket must exist in the same region as the load balancer and have a bucket policy that grants Elastic Load Balancing permissions to write to the bucket.

Is this a bug in AWS API?

1 Answer
0

This is intended behavior from AWS. What you'll want to do is completely remove access_logs.s3.bucket as a property when not doing ALB logging as leaving the property empty will throw an error.

It looks like the nesting is weird, you may need to break out each property completely with using AWS::NoValue to ensure that if false, there is not an empty property. The bug you're seeing is because CloudFormation still has the access_logs.s3.bucket property somehow.

jsonc
answered 2 years ago
  • Thanks @jsonc. Actually there was a bug in my template -- I forgot to call !Ref to get the parameter value. So instead of EnableLoadBalancerAccessLogs: !Not [!Equals [AccessLogsBucket, ""]], it should be EnableLoadBalancerAccessLogs: !Not [!Equals [!Ref AccessLogsBucket, ""]]

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions