From c135656bb0b6de9cce639218a83acf958f9bca4e Mon Sep 17 00:00:00 2001 From: Hirotaka Tagawa / wafuwafu13 Date: Wed, 14 Jun 2023 12:30:55 +0100 Subject: [PATCH] fix(core): prevent the error when the condition is split into groups of 10 and 1 in `Fn.conditionOr()` (#25708) Closes #25696 >The problem I'm running into is for a list of 11 elements. CDK generates two Fn::Or expressions: One with 10 elements and one with 1 element. When deployment this stack, CloudFormation complains that an Fn::Or must contain at least 2 elements. reproduce code: https://github.com/aws/aws-cdk/issues/25696#issuecomment-1560136915 approach: https://github.com/aws/aws-cdk/issues/25696#issuecomment-1559887661 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/aws-cdk-lib/core/lib/cfn-fn.ts | 5 +- .../aws-cdk-lib/core/test/condition.test.ts | 100 ++++++++++++++++++ 2 files changed, 104 insertions(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/core/lib/cfn-fn.ts b/packages/aws-cdk-lib/core/lib/cfn-fn.ts index 889af6c465aec..2441aaabe56a0 100644 --- a/packages/aws-cdk-lib/core/lib/cfn-fn.ts +++ b/packages/aws-cdk-lib/core/lib/cfn-fn.ts @@ -334,7 +334,10 @@ export class Fn { if (conditions.length === 1) { return conditions[0] as ICfnRuleConditionExpression; } - return Fn.conditionOr(..._inGroupsOf(conditions, 10).map(group => new FnOr(...group))); + if (conditions.length <= 10) { + return new FnOr(...conditions); + } + return Fn.conditionOr(..._inGroupsOf(conditions, 10).map(group => Fn.conditionOr(...group))); } /** diff --git a/packages/aws-cdk-lib/core/test/condition.test.ts b/packages/aws-cdk-lib/core/test/condition.test.ts index 35666822b113f..cfb5670394122 100644 --- a/packages/aws-cdk-lib/core/test/condition.test.ts +++ b/packages/aws-cdk-lib/core/test/condition.test.ts @@ -59,4 +59,104 @@ describe('condition', () => { }, }); }); + + test('condition length is 10n + 1 in Fn.conditionOr', () => { + // GIVEN + const stack = new cdk.Stack(); + const expression = cdk.Fn.conditionOr( + cdk.Fn.conditionEquals('a', '1'), + cdk.Fn.conditionEquals('b', '2'), + cdk.Fn.conditionEquals('c', '3'), + cdk.Fn.conditionEquals('d', '4'), + cdk.Fn.conditionEquals('e', '5'), + cdk.Fn.conditionEquals('f', '6'), + cdk.Fn.conditionEquals('g', '7'), + cdk.Fn.conditionEquals('h', '8'), + cdk.Fn.conditionEquals('i', '9'), + cdk.Fn.conditionEquals('j', '10'), + cdk.Fn.conditionEquals('k', '11'), + ); + + // WHEN + new cdk.CfnCondition(stack, 'Condition', { expression }); + + // THEN + expect(toCloudFormation(stack)).toEqual({ + Conditions: { + Condition: { + 'Fn::Or': [ + { + 'Fn::Or': [ + { 'Fn::Equals': ['a', '1'] }, + { 'Fn::Equals': ['b', '2'] }, + { 'Fn::Equals': ['c', '3'] }, + { 'Fn::Equals': ['d', '4'] }, + { 'Fn::Equals': ['e', '5'] }, + { 'Fn::Equals': ['f', '6'] }, + { 'Fn::Equals': ['g', '7'] }, + { 'Fn::Equals': ['h', '8'] }, + { 'Fn::Equals': ['i', '9'] }, + { 'Fn::Equals': ['j', '10'] }, + ], + }, + { + 'Fn::Equals': ['k', '11'], + }, + ], + }, + }, + }); + }); + + test('condition length is more than 10 in Fn.conditionOr', () => { + // GIVEN + const stack = new cdk.Stack(); + const expression = cdk.Fn.conditionOr( + cdk.Fn.conditionEquals('a', '1'), + cdk.Fn.conditionEquals('b', '2'), + cdk.Fn.conditionEquals('c', '3'), + cdk.Fn.conditionEquals('d', '4'), + cdk.Fn.conditionEquals('e', '5'), + cdk.Fn.conditionEquals('f', '6'), + cdk.Fn.conditionEquals('g', '7'), + cdk.Fn.conditionEquals('h', '8'), + cdk.Fn.conditionEquals('i', '9'), + cdk.Fn.conditionEquals('j', '10'), + cdk.Fn.conditionEquals('k', '11'), + cdk.Fn.conditionEquals('l', '12'), + ); + + // WHEN + new cdk.CfnCondition(stack, 'Condition', { expression }); + + // THEN + expect(toCloudFormation(stack)).toEqual({ + Conditions: { + Condition: { + 'Fn::Or': [ + { + 'Fn::Or': [ + { 'Fn::Equals': ['a', '1'] }, + { 'Fn::Equals': ['b', '2'] }, + { 'Fn::Equals': ['c', '3'] }, + { 'Fn::Equals': ['d', '4'] }, + { 'Fn::Equals': ['e', '5'] }, + { 'Fn::Equals': ['f', '6'] }, + { 'Fn::Equals': ['g', '7'] }, + { 'Fn::Equals': ['h', '8'] }, + { 'Fn::Equals': ['i', '9'] }, + { 'Fn::Equals': ['j', '10'] }, + ], + }, + { + 'Fn::Or': [ + { 'Fn::Equals': ['k', '11'] }, + { 'Fn::Equals': ['l', '12'] }, + ], + }, + ], + }, + }, + }); + }); });