aws-cloudformation / cfn-lint

CloudFormation Linter
MIT No Attribution
2.4k stars 576 forks source link

Throw the E3510 when the policy is not created because of the condition #3456

Open dengmingtong opened 5 days ago

dengmingtong commented 5 days ago

Is this feature request related to a new rule or cfn-lint capabilities?

No response

Describe the feature you'd like to request

Hello, We have below use case.

We have a cloudformation template to create Policy as below:

"IngestionCommonResourcesCreateApplicationLoadBalancerupdateAlbRulesLambdaAuthPolicy56A5093E": {
   "Type": "AWS::IAM::Policy",
   "Properties": {
    "PolicyDocument": {
     "Statement": [
      {
       "Action": "secretsmanager:GetSecretValue",
       "Effect": "Allow",
       "Resource": {
        "Ref": "AuthenticationSecretArn"
       }
      }
     ],
     "Version": "2012-10-17"
    },
    "PolicyName": "IngestionCommonResourcesCreateApplicationLoadBalancerupdateAlbRulesLambdaAuthPolicy56A5093E",
    "Roles": [
     {
      "Ref": "IngestionCommonResourcesCreateApplicationLoadBalancerupdateAlbRulesLambdaRole89F8B50D"
     }
    ]
   },
   "Metadata": {
    "aws:cdk:path": "s3-v2enable1/IngestionCommonResources/CreateApplicationLoadBalancer/updateAlbRulesLambdaAuthPolicy/Resource"
   },
   "Condition": "IngestionCommonResourcesCreateApplicationLoadBalancerauthEnableConditionF2B09238"
  },

And AuthenticationSecretArn is input parameter as below:

"AuthenticationSecretArn": {
   "Type": "String",
   "Default": "",
   "AllowedPattern": "^$|^arn:aws(-cn|-us-gov)?:secretsmanager:[a-z0-9-]+:[0-9]{12}:secret:[a-zA-Z0-9-/]+$",
   "ConstraintDescription": "AuthenticationSecretArn must match pattern ^$|^arn:aws(-cn|-us-gov)?:secretsmanager:[a-z0-9-]+:[0-9]{12}:secret:[a-zA-Z0-9-/]+$",
   "Description": "The AuthenticationSecretArn of OIDC provider"
  },

Now the cfn-lint throw the below error: E3510 {'Ref': 'AuthenticationSecretArn'} does not match '(^arn:(aws|aws-cn|aws-us-gov):[^:]+:[^:](:(?:\d{12}|\*|aws)?:.+|)|\)$' when 'Ref' is resolved

Our use case is the Policy is controlled by a condition IngestionCommonResourcesCreateApplicationLoadBalancerauthEnableConditionF2B09238

If the AuthenticationSecretArn is '', condition will be false and policy will not be created.

Could you think about this use case and do some change to support this case?

Thanks, Mingtong

Describe the solution you'd like

If the AuthenticationSecretArn is '', condition will be false and policy will not be created.

Could you think about this use case and do some change to support this case?

Additional context

No response

Is this something that you'd be interested in working on?

Would this feature include a breaking change?

kddejong commented 5 days ago

Using the latest version of cfn-lint and this condition I cannot replicate this error.

"IngestionCommonResourcesCreateApplicationLoadBalancerauthEnableConditionF2B09238": {
            "Fn::Not": [
                {
                    "Fn::Equals": [
                        {"Ref": "AuthenticationSecretArn"},
                        ""
                    ]
                }
            ]
        }
dengmingtong commented 4 days ago

I wrote a cloudformation example template as below:

AWSTemplateFormatVersion: '2010-09-09'
Description: A CloudFormation template that creates an IAM policy conditionally.

Parameters:
  enable:
    Type: String
    Description: Parameter to enable or disable the creation of the IAM policy.
    AllowedValues:
      - "Yes"
      - "No"
    Default: "No"

  secretArn:
    Type: String
    Default: ""
    Description: The ARN of the secret to use in the IAM policy.

Conditions:
  CreatePolicy: !Equals [!Ref enable, "Yes"]  

Resources:

  MyIAMRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: [lambda.amazonaws.com]
            Action: ['sts:AssumeRole']
      Path: "/"
      Policies:
        - PolicyName: LambdaExecutionPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: "arn:aws:logs:*:*:*"

  ConditionalIAMPolicy:
    Type: AWS::IAM::Policy
    Condition: CreatePolicy
    Properties:
      PolicyName: ConditionalSecretPolicy
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Action: 
              - secretsmanager:GetSecretValue
            Resource: !Ref secretArn
      Roles:
        - !Ref MyIAMRole

execute: cfn-lint -e -t ./E3510-test.yaml

got below error:

E3510 {'Ref': 'secretArn'} does not match '(^arn:(aws|aws-cn|aws-us-gov):[^:]+:[^:](:(?:\d{12}|\*|aws)?:.+|)|\)$' when 'Ref' is resolved E3510-test.yaml:15:5

kddejong commented 4 days ago

This is similar to #3378. The error is coming from the fact that I can leave secretArn empty and have enable as yes. As it stands those two parameters really have no relationship in the conditions section.

The way we typically see this solved is something like: !And [!Equals [!Ref enable, "Yes"], !Not [!Equals [!Ref secretArn, ""]]]

or !Not [!Equals [!Ref secretArn, ""]]