Skip to content

Commit f186d21

Browse files
authored
Convert conditions to SymPy (#2624)
* Update condition to v2
1 parent 7300c47 commit f186d21

16 files changed

+896
-1246
lines changed

.github/workflows/test.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
with:
2929
token: ${{ secrets.CODECOV_TOKEN }}
3030
file: ./coverage.xml # optional
31-
name: py${{ matrix.python-version }}-${{ matrix.env.TOXENV }}-${{ matrix.os }}
31+
name: py${{ matrix.python }}-${{ matrix.os }}
3232
flags: unittests # optional
3333
fail_ci_if_error: true # optional (default = false)
3434
integration:

docs/conditions.md

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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.

setup.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ def get_version(filename):
4949
'networkx>=2.4,<4',
5050
'junit-xml~=1.9',
5151
'jschema_to_python~=1.2.3',
52-
'sarif-om~=1.0.4'
52+
'sarif-om~=1.0.4',
53+
'sympy>=1.0.0',
5354
],
5455
python_requires='>=3.7, <=4.0, !=4.0',
5556
entry_points={

0 commit comments

Comments
 (0)