8000 Refactor CFn conditions & mappings by dominikschubert · Pull Request #8546 · localstack/localstack · GitHub
[go: up one dir, main page]

Skip to content

Refactor CFn conditions & mappings #8546

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Jun 28, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
add test for unref-able outputs
  • Loading branch information
dominikschubert committed Jun 26, 2023
commit 79aeb736a31a7cabb652ba9e691c3556f51cb5c7

This file was deleted.

44 changes: 24 additions & 20 deletions tests/integration/cloudformation/engine/test_conditions.py
8000
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@


class TestCloudFormationConditions:
"""
TODO: what happens to outputs that reference a resource that isn't deployed?
"""

@pytest.mark.aws_validated
def test_simple_condition_evaluation_deploys_resource(
self, aws_client, deploy_cfn_template, cleanups
Expand Down Expand Up @@ -54,8 +50,9 @@ def test_simple_condition_evaluation_doesnt_deploy_resource(
)
# verify that CloudFormation ignores the resource
aws_client.cloudformation.describe_stack_resources(StackName=deployment.stack_id)
# assert stack_resources['StackResources'] == []

# FIXME: currently broken in localstack
# assert stack_resources['StackResources'] == []

# verify actual resource deployment
assert [
Expand All @@ -75,7 +72,7 @@ def test_simple_intrinsic_fn_condition_evaluation(

The conditional ShouldSetCustomName (yep | nope) switches between an autogenerated and a predefined name for the topic

TODO: this should also work with the simple-intrinsic-condition-name-conflict.yaml template where the ID of the condition and the ID of the parameter are the same(!).
FIXME: this should also work with the simple-intrinsic-condition-name-conflict.yaml template where the ID of the condition and the ID of the parameter are the same(!).
It is currently broken in LocalStack though
"""
topic_name = f"test-topic-{short_uid()}"
Expand Down Expand Up @@ -129,7 +126,7 @@ def test_dependent_ref(self, aws_client, snapshot):
@pytest.mark.skipif(condition=not is_aws_cloud(), reason="not supported yet")
def test_dependent_ref_intrinsic_fn_condition(self, aws_client, deploy_cfn_template):
"""
Checks behavior of un-refable
Checks behavior of un-refable resources
"""
topic_name = f"test-topic-{short_uid()}"
ssm_param_name = f"test-param-{short_uid()}"
Expand All @@ -151,11 +148,11 @@ def test_dependent_ref_with_macro(
self, aws_client, deploy_cfn_template, lambda_su_role, cleanups
):
"""

specifying option-b would normally lead to an error without the macro because of the unresolved ref.
Because the macro replaced the resources though, the test passes. We've shown that conditions aren't fully evaluated before the transformations
Because the macro replaced the resources though, the test passes.
We've therefore shown that conditions aren't fully evaluated before the transformations

A few interesting findings:
Related findings:
* macros are not allowed to transform Parameters (macro invocation by CFn will fail in this case)

"""
Expand Down Expand Up @@ -197,16 +194,6 @@ def test_dependent_ref_with_macro(
ChangeSetName=changeset_name, StackName=stack_name
)

# # verify that CloudFormation ignores the resource
# stack_resources = aws_client.cloudformation.describe_stack_resources(StackName=deployment.stack_id)
# # assert stack_resources['StackResources'] == []
#
# # verify actual resource deployment
# assert [t for t in aws_client.sns.list_topics()['Topics'] if topic_name in t['TopicArn']]
# # assert [t for t in aws_client.sns.list_topics()['Topics'] if topic_name in t['TopicArn']] == []
# param = aws_client.ssm.get_parameter(Name=ssm_param_name)
# assert param['Parameter']['Value']

@pytest.mark.parametrize(
["env_type", "should_create_bucket", "should_create_policy"],
[
Expand Down Expand Up @@ -235,6 +222,8 @@ def test_nested_conditions(
snapshot,
):
"""
Tests the case where a condition references another condition

EnvType == "prod" && BucketName != "" ==> creates bucket + policy
EnvType == "test" && BucketName != "" ==> creates bucket only
EnvType == "test" && BucketName == "" ==> no resource created
Expand Down Expand Up @@ -316,6 +305,21 @@ def test_nested_conditions(

assert bucket_policy_exists == should_create_policy

@pytest.mark.skipif(condition=not is_aws_cloud(), reason="not supported yet")
@pytest.mark.aws_validated
def test_output_reference_to_skipped_resource(self, deploy_cfn_template, aws_client, snapshot):
"""test what happens to outputs that reference a resource that isn't deployed due to a falsy condition"""
with pytest.raises(aws_client.cloudformation.exceptions.ClientError) as e:
deploy_cfn_template(
template_path=os.path.join(
THIS_DIR, "../../templates/conditions/ref-condition-output.yaml"
),
parameters={
"OptionParameter": "option-b",
},
)
snapshot.match("unresolved_resource_reference_exception", e.value.response)

# def test_updating_only_conditions_during_stack_update(self):
# ...

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"tests/integration/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_nested_conditions[test-nobucket-nopolicy]": {
"recorded-date": "06-06-2023, 23:53:29",
"recorded-date": "26-06-2023, 14:20:49",
"recorded-content": {
"create_cs_result": {
"Id": "arn:aws:cloudformation:<region>:111111111111:changeSet/<resource:1>",
Expand Down Expand Up @@ -122,7 +122,7 @@
}
},
"tests/integration/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_nested_conditions[test-bucket-nopolicy]": {
"recorded-date": "06-06-2023, 23:54:34",
"recorded-date": "26-06-2023, 14:21:54",
"recorded-content": {
"create_cs_result": {
"Id": "arn:aws:cloudformation:<region>:111111111111:changeSet/<resource:1>",
Expand Down Expand Up @@ -308,7 +308,7 @@
}
},
"tests/integration/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_nested_conditions[prod-nobucket-nopolicy]": {
"recorded-date": "06-06-2023, 23:55:38",
"recorded-date": "26-06-2023, 14:22:58",
"recorded-content": {
"create_cs_result": {
"Id": "arn:aws:cloudformation:<region>:111111111111:changeSet/<resource:1>",
Expand Down Expand Up @@ -430,7 +430,7 @@
}
},
"tests/integration/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_nested_conditions[prod-bucket-policy]": {
"recorded-date": "06-06-2023, 23:56:44",
"recorded-date": "26-06-2023, 14:24:03",
"recorded-content": {
"create_cs_result": {
"Id": "arn:aws:cloudformation:<region>:111111111111:changeSet/<resource:1>",
Expand Down Expand Up @@ -729,7 +729,7 @@
}
},
"tests/integration/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_dependent_ref": {
"recorded-date": "07-06-2023, 11:30:09",
"recorded-date": "26-06-2023, 14:18:26",
"recorded-content": {
"dependent_ref_exc": {
"Error": {
Expand All @@ -743,5 +743,21 @@
}
}
}
},
"tests/integration/cloudformation/engine/test_conditions.py::TestCloudFormationConditions::test_output_reference_to_skipped_resource": {
"recorded-date": "27-06-2023, 00:43:18",
"recorded-content": {
"unresolved_resource_reference_exception": {
"Error": {
"Code": "ValidationError",
"Message": "Unresolved resource dependencies [MyTopic] in the Outputs block of the template",
"Type": "Sender"
},
"ResponseMetadata": {
"HTTPHeaders": {},
"HTTPStatusCode": 400
}
}
}
}
}
19 changes: 19 additions & 0 deletions tests/integration/templates/conditions/ref-condition-output.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Parameters:
OptionParameter:
Type: String
AllowedValues:
- option-a
- option-b
Resources:
MyTopic:
Type: AWS::SNS::Topic
Condition: ShouldCreateTopic

Conditions:
ShouldCreateTopic: !Equals
- !Ref OptionParameter
- option-a

Outputs:
TopicRef:
Value: !Ref MyTopic
0