@@ -230,10 +230,70 @@ func fillRepSpecsWithDynamicBlock(resourceb *hclwrite.Body, root attrVals) (dyna
230230 if err != nil {
231231 return dynamicBlock {}, err
232232 }
233- forSpec := hcl .TokensFromExpr (buildForExpr (nSpec , hcl .GetAttrExpr (dSpec .forEach ), true ))
234- forSpec = append (forSpec , dConfig .tokens ... )
235- tokens := hcl .TokensFuncFlatten (forSpec )
236- dSpec .tokens = tokens
233+
234+ // Check if we have a dynamic region_configs block that was successfully processed
235+ if dConfig .tokens != nil {
236+ forSpec := hcl .TokensFromExpr (buildForExpr (nSpec , hcl .GetAttrExpr (dSpec .forEach ), true ))
237+ forSpec = append (forSpec , dConfig .tokens ... )
238+ tokens := hcl .TokensFuncFlatten (forSpec )
239+ dSpec .tokens = tokens
240+ return dSpec , nil
241+ }
242+
243+ // Handle static region_configs blocks inside dynamic replication_specs
244+ specBody := dSpec .content .Body ()
245+
246+ // Collect static region_configs blocks
247+ staticConfigs := collectBlocks (specBody , nConfigSrc )
248+ if len (staticConfigs ) == 0 {
249+ // No static blocks found, check if there's also no dynamic block
250+ hasDynamicBlock := false
251+ for _ , block := range specBody .Blocks () {
252+ if block .Type () == nDynamic && getResourceName (block ) == nConfigSrc {
253+ hasDynamicBlock = true
254+ break
255+ }
256+ }
257+ if ! hasDynamicBlock {
258+ return dynamicBlock {}, fmt .Errorf ("replication_specs must have at least one regions_config" )
259+ }
260+ // There's a dynamic block but fillConfigsWithDynamicRegion returned empty
261+ return dynamicBlock {}, nil
262+ }
263+
264+ repSpecb := hclwrite .NewEmptyFile ().Body ()
265+
266+ // Handle zone_name attribute
267+ if zoneNameAttr := specBody .GetAttribute (nZoneName ); zoneNameAttr != nil {
268+ zoneNameExpr := transformReference (hcl .GetAttrExpr (zoneNameAttr ), nRepSpecs , nSpec )
269+ repSpecb .SetAttributeRaw (nZoneName , hcl .TokensFromExpr (zoneNameExpr ))
270+ }
271+
272+ // Process static region_configs blocks
273+ var configs []* hclwrite.Body
274+ for _ , configBlock := range staticConfigs {
275+ config , err := getRegionConfig (configBlock , root , false )
276+ if err != nil {
277+ return dynamicBlock {}, err
278+ }
279+ configs = append (configs , config )
280+ }
281+
282+ configs = sortConfigsByPriority (configs )
283+ repSpecb .SetAttributeRaw (nConfig , hcl .TokensArray (configs ))
284+
285+ // Handle num_shards attribute
286+ if numShardsAttr := specBody .GetAttribute (nNumShards ); numShardsAttr != nil {
287+ numShardsExpr := transformReference (hcl .GetAttrExpr (numShardsAttr ), nRepSpecs , nSpec )
288+ forSpec := hcl .TokensFromExpr (buildForExpr (nSpec , hcl .GetAttrExpr (dSpec .forEach ), true ))
289+ innerFor := hcl .TokensFromExpr (buildForExpr ("i" , fmt .Sprintf ("range(%s)" , numShardsExpr ), false ))
290+ innerFor = append (innerFor , hcl .TokensObject (repSpecb )... )
291+ dSpec .tokens = hcl .TokensFuncFlatten (append (forSpec , hcl .EncloseBracketsNewLines (innerFor )... ))
292+ } else {
293+ forSpec := hcl .TokensFromExpr (buildForExpr (nSpec , hcl .GetAttrExpr (dSpec .forEach ), true ))
294+ dSpec .tokens = hcl .TokensFuncFlatten (append (forSpec , hcl .TokensArraySingle (repSpecb )... ))
295+ }
296+
237297 return dSpec , nil
238298}
239299
0 commit comments