|
| 1 | +# Conditions |
| 2 | + |
| 3 | +Conditions allow a template developer to create many scenarios using the same template. cfn-lint does not use parameter values to determine the validaty of a template so cfn-lint will try to validate all the possible scenarios that are created by using conditions. |
| 4 | + |
| 5 | +# Using conditions |
| 6 | + |
| 7 | +## Defining conditions |
| 8 | + |
| 9 | +Conditions are defined in a section of your CloudFormation template. At the lowest level all conditions will equate to a set of `Fn::Equals` that compares two values. Advanced condition scenarios can be created using `Fn::And`, `Fn::Or`, `Fn::Not`. Conditions can be nested using `Fn::Condition` function. |
| 10 | + |
| 11 | +```yaml |
| 12 | +Parameters: |
| 13 | + Environment: |
| 14 | + Type: String |
| 15 | +Conditions: |
| 16 | + IsProduction: !Equals [!Ref Environment, "prod"] |
| 17 | + IsDevelopment: !Equals [!Ref Environment, "dev"] |
| 18 | + IsProductionAndUsEast1: |
| 19 | + !And |
| 20 | + - !Condition IsProduction |
| 21 | + - !Equals [!Ref AWS::Region, "us-east-1"] |
| 22 | +``` |
| 23 | +
|
| 24 | +## Using conditions |
| 25 | +
|
| 26 | +Conditions can be used in two locations. 1/ Is the at the resource or output level defined by the attribute `Condition` 2/ Using the function `Fn::If` under a resources `Properties` property. `Fn::If` can be used at any layer as long as it is the only key in an object. |
| 27 | + |
| 28 | +```yaml |
| 29 | +Resources: |
| 30 | + HTTPSCertificate: |
| 31 | + Type: AWS::CertificateManager::Certificate |
| 32 | + Condition: HaveTargets |
| 33 | + Properties: |
| 34 | + DomainName: 'example.com' |
| 35 | + ValidationMethod: DNS |
| 36 | +
|
| 37 | + CloudFrontAlias: |
| 38 | + Type: AWS::Route53::RecordSet |
| 39 | + Condition: CreateDNSRecords |
| 40 | + Properties: |
| 41 | + HostedZoneId: !Ref ServiceHostedZoneId |
| 42 | + Name: 'example.com' |
| 43 | + Type: A |
| 44 | + AliasTarget: |
| 45 | + DNSName: !GetAtt Distribution1.DomainName |
| 46 | + HostedZoneId: Z2FDTNDATAQYW2 |
| 47 | +
|
| 48 | + Distribution1: |
| 49 | + Type: AWS::CloudFront::Distribution |
| 50 | + Condition: HaveTargets |
| 51 | + Properties: |
| 52 | + DistributionConfig: |
| 53 | + Enabled: true |
| 54 | + ViewerCertificate: |
| 55 | + AcmCertificateArn: !Ref HTTPSCertificate |
| 56 | + SslSupportMethod: sni-only |
| 57 | + MinimumProtocolVersion: TLSv1.2_2019 |
| 58 | + DefaultCacheBehavior: |
| 59 | + TargetOriginId: Service1 |
| 60 | +Outputs: |
| 61 | + DomainName: |
| 62 | + Value: !If [HaveTargets, !GetAtt Distribution1.DomainName, ""] |
| 63 | +``` |
| 64 | + |
| 65 | + |
| 66 | +# Handling conditions |
| 67 | + |
| 68 | +## SymPy |
| 69 | +[SymPy](https://docs.sympy.org/) is a python package that allows you to build formulas and calculate if a scenario is a legitimate scenario. For instance cfn-lint will build a solver for conditions `IsProduction` and `IsDevelopment` that will calculate the following possibilites `True`/`False`, `False`/`True`, or `False`/`False`. To build a solver cfn-lint will build formulas accordingly `Fn::And` is converted to `And`, `Fn::Or` is converted to `Or`, and `Fn::Not` is converted to `Not`. It will understand `Fn::Equals` that use the same parameter and create a `Not(And(...))` formula that will make sure that the equals in the `And` are no never `True` together. |
0 commit comments