Repository: aws-cloudformation/rain
Pull request #127 (2023-04-21 17:44:49)

Add parent template Conditions in modules


Patch:
diff --git a/cft/pkg/module.go b/cft/pkg/module.go
index 0743f558..b6668c9e 100644
--- a/cft/pkg/module.go
+++ b/cft/pkg/module.go
@@ -18,7 +18,12 @@ import (
 )
 
 // Clone a property-like node from the module and replace any overridden values
-func cloneAndReplaceProps(ext *yaml.Node, name string, moduleProps *yaml.Node, templateProps *yaml.Node) *yaml.Node {
+func cloneAndReplaceProps(
+	ext *yaml.Node,
+	name string,
+	moduleProps *yaml.Node,
+	templateProps *yaml.Node,
+	moduleParams *yaml.Node) *yaml.Node {
 
 	// Not all property-like attributes are required
 	if moduleProps == nil {
@@ -34,6 +39,23 @@ func cloneAndReplaceProps(ext *yaml.Node, name string, moduleProps *yaml.Node, t
 	// Replace any property values overridden in the parent template
 	if templateProps != nil {
 		for i, tprop := range templateProps.Content {
+
+			// Only look at the names, which have even indexes
+			if i%2 != 0 {
+				continue
+			}
+
+			found := false
+
+			_, moduleParam := s11n.GetMapValue(moduleParams, tprop.Value)
+
+			// Don't clone template props that are module parameters.
+			// Module params are used when we resolve Refs later
+			if moduleParam != nil {
+				continue
+			}
+
+			// Override anything hard coded into the module that is present in the parent template
 			for j, mprop := range props.Content {
 				// Property names are even-indexed array elements
 				if tprop.Value == mprop.Value && i%2 == 0 && j%2 == 0 {
@@ -41,8 +63,15 @@ func cloneAndReplaceProps(ext *yaml.Node, name string, moduleProps *yaml.Node, t
 					// Maybe we just require that you replace the entire property if it's nested
 					// Otherwise we have to do a diff
 					props.Content[j+1] = node.Clone(templateProps.Content[i+1])
+					found = true
 				}
 			}
+
+			if !found && i%2 == 0 {
+				props.Content = append(props.Content, &yaml.Node{Kind: yaml.ScalarNode, Value: tprop.Value})
+				props.Content = append(props.Content, node.Clone(templateProps.Content[i+1]))
+			}
+
 		}
 	}
 
@@ -280,7 +309,7 @@ func processModule(module *yaml.Node,
 		for _, pl := range propLike {
 			_, plProps := s11n.GetMapValue(moduleExtension, pl)
 			_, plTemplateProps := s11n.GetMapValue(templateResource, pl)
-			outProps := cloneAndReplaceProps(ext, pl, plProps, plTemplateProps)
+			outProps := cloneAndReplaceProps(ext, pl, plProps, plTemplateProps, moduleParams)
 			if pl == "Metadata" {
 				// Remove the Extends attribute
 				node.RemoveFromMap(outProps, "Extends")
@@ -336,6 +365,13 @@ func processModule(module *yaml.Node,
 		// Other refs are to the module's parameters
 		resolveRefs(ext, moduleParams, moduleResources, logicalId, templateProps)
 
+		// Add the Condition from the parent template
+		_, parentCondition := s11n.GetMapValue(templateResource, "Condition")
+		if parentCondition != nil {
+			ext.Content = append(ext.Content, &yaml.Node{Kind: yaml.ScalarNode, Value: "Condition"})
+			ext.Content = append(ext.Content, node.Clone(parentCondition))
+		}
+
 		// Add the extension to the output node
 		outputNode.Content = append(outputNode.Content, ext)
 	}


Test patch:
diff --git a/test/modules/bucket.yaml b/test/modules/bucket.yaml
index 52db3ec1..e92831b5 100644
--- a/test/modules/bucket.yaml
+++ b/test/modules/bucket.yaml
@@ -33,8 +33,6 @@ Resources:
         ServerSideEncryptionConfiguration:
           - ServerSideEncryptionByDefault:
              SSEAlgorithm: AES256
-      VersioningConfiguration:
-        Status: Enabled
       PublicAccessBlockConfiguration:
         BlockPublicAcls: true
         BlockPublicPolicy: true
diff --git a/test/modules/expect.yaml b/test/modules/expect.yaml
index 0ad14021..2b96cef2 100644
--- a/test/modules/expect.yaml
+++ b/test/modules/expect.yaml
@@ -36,8 +36,6 @@ Resources:
         ServerSideEncryptionConfiguration:
           - ServerSideEncryptionByDefault:
               SSEAlgorithm: AES256
-      VersioningConfiguration:
-        Status: Enabled
       PublicAccessBlockConfiguration:
         BlockPublicAcls: true
         BlockPublicPolicy: true
@@ -46,6 +44,10 @@ Resources:
       Tags:
         - Key: test-tag
           Value: test-value2
+      BucketName: ezbeard-cep-test-module-bucket
+      VersioningConfiguration:
+        Status: Enabled
+    Condition: ConditionA
 
   ModuleExampleLogBucket:
     DeletionPolicy: Delete
diff --git a/test/templates/module.yaml b/test/templates/module.yaml
index 944a3b6b..a97f81e1 100644
--- a/test/templates/module.yaml
+++ b/test/templates/module.yaml
@@ -19,11 +19,14 @@ Resources:
     #Type: !Rain::Module "https://raw.githubusercontent.com/ericzbeard/rain/modules/test/modules/bucket.yaml"
     Type: !Rain::Module "file://../../modules/bucket.yaml"
     UpdateReplacePolicy: Delete
+    Condition: ConditionA
     DependsOn: SecondResourceInOriginal
     Properties:
       LogBucketName: ezbeard-cep-test-module-log-bucket
       BucketName: ezbeard-cep-test-module-bucket
       RetentionPolicy: !Ref BucketRetentionPolicy
+      VersioningConfiguration:
+        Status: Enabled
       ConditionName: ConditionA
       Tags:
         - Key: test-tag