Repository: klothoplatform/klotho
Pull request #823 (2023-12-13 19:29:14)

eks fixes and sanitize pulumi name
sanitize pulumi app name

a couple eks fixes

### Standard checks

- **Unit tests**: Any special considerations?
- **Docs**: Do we need to update any docs, internal or public?
- **Backwards compatibility**: Will this break existing apps? If so, what would be the extra work required to keep them working?



Patch:
diff --git a/pkg/engine2/operational_eval/evaluator.go b/pkg/engine2/operational_eval/evaluator.go
index f8fa8e38..ea56edff 100644
--- a/pkg/engine2/operational_eval/evaluator.go
+++ b/pkg/engine2/operational_eval/evaluator.go
@@ -407,6 +407,14 @@ func (eval *Evaluator) UpdateId(oldId, newId construct.ResourceId) error {
 		return err
 	}
 
+	// update all constraints that pertain to the old id
+	c := eval.Solution.Constraints()
+	for i, rc := range c.Resources {
+		if rc.Target == oldId {
+			c.Resources[i].Target = newId
+		}
+	}
+
 	var errs error
 
 	replaceVertex := func(oldKey Key, vertex Vertex) {
diff --git a/pkg/engine2/operational_eval/vertex_path_expand.go b/pkg/engine2/operational_eval/vertex_path_expand.go
index 9569ccc0..9609830f 100644
--- a/pkg/engine2/operational_eval/vertex_path_expand.go
+++ b/pkg/engine2/operational_eval/vertex_path_expand.go
@@ -203,7 +203,92 @@ func (v *pathExpandVertex) runExpansion(eval *Evaluator, expansion path_selectio
 			Value:    delay.Value,
 		})
 	}
-	return nil
+
+	// do this after weve added all resources and edges to the sol ctx so that we replace the ids properly
+	return v.handleResultProperties(eval, result)
+}
+
+// handleProperties
+func (v *pathExpandVertex) handleResultProperties(
+	eval *Evaluator,
+	result path_selection.ExpansionResult,
+) error {
+	adj, err := result.Graph.AdjacencyMap()
+	if err != nil {
+		return err
+	}
+	pred, err := result.Graph.PredecessorMap()
+	if err != nil {
+		return err
+	}
+
+	handleResultProperties := func(
+		res *construct.Resource,
+		rt *knowledgebase.ResourceTemplate,
+		resources map[construct.ResourceId]graph.Edge[construct.ResourceId],
+		Direction knowledgebase.Direction,
+	) error {
+		var errs error
+		for target := range resources {
+			targetRes, err := result.Graph.Vertex(target)
+			if err != nil {
+				errs = errors.Join(errs, err)
+				continue
+			}
+			errs = errors.Join(errs, rt.LoopProperties(res, func(prop knowledgebase.Property) error {
+				opRuleCtx := operational_rule.OperationalRuleContext{
+					Solution: eval.Solution,
+					Property: prop,
+					Data:     knowledgebase.DynamicValueData{Resource: res.ID},
+				}
+				details := prop.Details()
+				if details.OperationalRule == nil || len(details.OperationalRule.Step.Resources) == 0 {
+					return nil
+				}
+				step := details.OperationalRule.Step
+				for _, selector := range step.Resources {
+					if step.Direction == Direction {
+						canUse, err := selector.CanUse(
+							solution_context.DynamicCtx(eval.Solution),
+							knowledgebase.DynamicValueData{Resource: res.ID},
+							targetRes,
+						)
+						if canUse && err == nil {
+							err = opRuleCtx.SetField(res, targetRes, step)
+							if err != nil {
+								errs = errors.Join(errs, err)
+							}
+						}
+					}
+				}
+				return nil
+			}))
+		}
+		return errs
+	}
+
+	var errs error
+	for id, downstreams := range adj {
+		oldId := id
+		rt, err := eval.Solution.KnowledgeBase().GetResourceTemplate(id)
+		if err != nil {
+			errs = errors.Join(errs, err)
+			continue
+		}
+		res, err := eval.Solution.RawView().Vertex(id)
+		if err != nil {
+			errs = errors.Join(errs, err)
+			continue
+		}
+
+		errs = errors.Join(errs, handleResultProperties(res, rt, downstreams, knowledgebase.DirectionDownstream))
+		errs = errors.Join(errs, handleResultProperties(res, rt, pred[id], knowledgebase.DirectionUpstream))
+
+		if oldId != res.ID {
+			errs = errors.Join(errs, eval.UpdateId(oldId, res.ID))
+		}
+	}
+	return errs
 }
 
 func (v *pathExpandVertex) getExpansionsToRun(eval *Evaluator) ([]path_selection.ExpansionInput, error) {
diff --git a/pkg/engine2/path_selection/path_expansion.go b/pkg/engine2/path_selection/path_expansion.go
index f20cbda8..e48c9889 100644
--- a/pkg/engine2/path_selection/path_expansion.go
+++ b/pkg/engine2/path_selection/path_expansion.go
@@ -8,7 +8,6 @@ import (
 
 	"github.com/dominikbraun/graph"
 	construct "github.com/klothoplatform/klotho/pkg/construct2"
-	"github.com/klothoplatform/klotho/pkg/engine2/operational_rule"
 	"github.com/klothoplatform/klotho/pkg/engine2/solution_context"
 	knowledgebase "github.com/klothoplatform/klotho/pkg/knowledge_base2"
 	"github.com/klothoplatform/klotho/pkg/set"
@@ -233,75 +232,6 @@ func findSubExpansionsToRun(
 	return
 }
 
-func handleProperties(
-	ctx solution_context.SolutionContext,
-	resultResources []*construct.Resource,
-	tempGraph construct.Graph,
-) error {
-	var errs error
-	// Go in reverse order so that IDs are set correctly before a previous resource's property is set to its ID.
-	// For example, set Subnet#VPC (namespace property) before Lambda#Subnets
-	for i := len(resultResources) - 1; i >= 0; i-- {
-		res := resultResources[i]
-
-		rt, err := ctx.KnowledgeBase().GetResourceTemplate(res.ID)
-		if err != nil {
-			errs = errors.Join(errs, err)
-			continue
-		}
-
-		handleProp := func(prop knowledgebase.Property) error {
-			oldId := res.ID
-			opRuleCtx := operational_rule.OperationalRuleContext{
-				Solution: ctx,
-				Property: prop,
-				Data:     knowledgebase.DynamicValueData{Resource: res.ID},
-			}
-			details := prop.Details()
-			if details.OperationalRule == nil || len(details.OperationalRule.Step.Resources) == 0 {
-				return nil
-			}
-			step := details.OperationalRule.Step
-			for _, selector := range step.Resources {
-				if step.Direction == knowledgebase.DirectionDownstream && i < len(resultResources)-1 {
-					downstreamRes := resultResources[i+1]
-					canUse, err := selector.CanUse(
-						solution_context.DynamicCtx(ctx),
-						knowledgebase.DynamicValueData{Resource: res.ID},
-						downstreamRes,
-					)
-					if canUse && err == nil {
-						err = opRuleCtx.SetField(res, downstreamRes, step)
-						if err != nil {
-							errs = errors.Join(errs, err)
-						}
-					}
-				} else if i > 0 {
-					upstreamRes := resultResources[i-1]
-					if canUse, err := selector.CanUse(solution_context.DynamicCtx(ctx),
-						knowledgebase.DynamicValueData{Resource: res.ID}, upstreamRes); canUse && err == nil {
-						err = opRuleCtx.SetField(res, upstreamRes, step)
-						if err != nil {
-							errs = errors.Join(errs, err)
-						}
-					}
-
-				}
-			}
-			if details.Namespace && oldId != res.ID {
-				// add a marker for where to find the new id in the result graph
-				_, props, err := tempGraph.VertexWithProperties(oldId)
-				if err == nil && props.Attributes != nil {
-					props.Attributes["new_id"] = res.ID.String()
-				}
-			}
-			return nil
-		}
-		errs = errors.Join(errs, rt.LoopProperties(res, handleProp))
-	}
-	return errs
-}
-
 // ExpandEdge takes a given `selectedPath` and resolves it to a path of resourceIds that can be used
 // for creating resources, or existing resources.
 func expandPath(
@@ -564,14 +494,9 @@ func addPathToGraph(ctx solution_context.SolutionContext, g construct.Graph, pat
 	if errs != nil {
 		return nil, errs
 	}
-	// handle the properties before adding to the graph to make sure the IDs are set correctly
-	err := handleProperties(ctx, result, g)
-	if err != nil {
-		return nil, err
-	}
 	var prevRes construct.ResourceId
 	for i, r := range result {
-		err = g.AddVertex(r)
+		err := g.AddVertex(r)
 		if err != nil && !errors.Is(err, graph.ErrVertexAlreadyExists) {
 			errs = errors.Join(errs, err)
 		}
diff --git a/pkg/infra/cli2.go b/pkg/infra/cli2.go
index b8835e80..c5d23c5f 100644
--- a/pkg/infra/cli2.go
+++ b/pkg/infra/cli2.go
@@ -128,7 +128,7 @@ func GenerateIac(cmd *cobra.Command, args []string) error {
 	switch generateIacCfg.provider {
 	case "pulumi":
 		pulumiPlugin := iac3.Plugin{
-			Config: &config.Application{AppName: generateIacCfg.appName},
+			Config: &iac3.PulumiConfig{AppName: generateIacCfg.appName},
 			KB:     kb,
 		}
 		iacFiles, err := pulumiPlugin.Translate(solCtx)
diff --git a/pkg/infra/iac3/plugin.go b/pkg/infra/iac3/plugin.go
index d36ec0bf..b438347e 100644
--- a/pkg/infra/iac3/plugin.go
+++ b/pkg/infra/iac3/plugin.go
@@ -8,10 +8,10 @@ import (
 	"fmt"
 	"io"
 	"io/fs"
+	"regexp"
 	"strings"
 	"text/template"
 
-	"github.com/klothoplatform/klotho/pkg/config"
 	construct "github.com/klothoplatform/klotho/pkg/construct2"
 	"github.com/klothoplatform/klotho/pkg/engine2/solution_context"
 	kio "github.com/klothoplatform/klotho/pkg/io"
@@ -20,10 +20,16 @@ import (
 	"github.com/klothoplatform/klotho/pkg/templateutils"
 )
 
-type Plugin struct {
-	Config *config.Application
-	KB     *knowledgebase.KnowledgeBase
-}
+type (
+	PulumiConfig struct {
+		AppName string
+	}
+
+	Plugin struct {
+		Config *PulumiConfig
+		KB     *knowledgebase.KnowledgeBase
+	}
+)
 
 func (p Plugin) Name() string {
 	return "pulumi3"
@@ -43,6 +49,10 @@ var (
 
 func (p Plugin) Translate(ctx solution_context.SolutionContext) ([]kio.File, error) {
 
+	err := p.sanitizeConfig()
+	if err != nil {
+		return nil, err
+	}
 	// TODO We'll eventually want to split the output into different files, but we don't know exactly what that looks
 	// like yet. For now, just write to a single file, "index.ts"
 	buf := getBuffer()
@@ -132,6 +142,15 @@ func (p Plugin) Translate(ctx solution_context.SolutionContext) ([]kio.File, err
 	return files, nil
 }
 
+func (p *Plugin) sanitizeConfig() error {
+	reg, err := regexp.Compile("[^a-zA-Z0-9-_]+")
+	if err != nil {
+		return fmt.Errorf("Error compiling regex: %v", err)
+	}
+	p.Config.AppName = reg.ReplaceAllString(p.Config.AppName, "")
+	return nil
+}
+
 func renderGlobals(w io.Writer) error {
 	globalsFile, err := files.Open("templates/globals.ts")
 	if err != nil {
diff --git a/pkg/knowledge_base2/emitter.go b/pkg/knowledge_base2/emitter.go
index 5f6378ab..6b9acfa5 100644
--- a/pkg/knowledge_base2/emitter.go
+++ b/pkg/knowledge_base2/emitter.go
@@ -170,6 +170,9 @@ func (c *ConsumptionObject) Convert(value any, res construct.ResourceId, ctx Dyn
 		"sub": func(a int, b int) int {
 			return a - b
 		},
+		"add": func(a int, b int) int {
+			return a + b
+		},
 	},
 	).Parse(c.Converter)
 	if err != nil {
diff --git a/pkg/templates/aws/edges/kubernetes_persistent_volume-efs_file_system.yaml b/pkg/templates/aws/edges/kubernetes_persistent_volume-efs_file_system.yaml
index 7df9ef64..0122a4d9 100644
--- a/pkg/templates/aws/edges/kubernetes_persistent_volume-efs_file_system.yaml
+++ b/pkg/templates/aws/edges/kubernetes_persistent_volume-efs_file_system.yaml
@@ -8,7 +8,7 @@ operational_rules:
         resources:
           - selector: aws:eks_add_on
             properties:
-              AddOnName: efs-csi-driver
+              AddOnName: aws-efs-csi-driver
               Cluster: '{{ fieldValue "Cluster" .Source }}'
       - resource: '{{ .Source }}'
         direction: downstream
diff --git a/pkg/templates/aws/edges/kubernetes_storage_class-eks_cluster.yaml b/pkg/templates/aws/edges/kubernetes_storage_class-eks_cluster.yaml
new file mode 100644
index 00000000..107ae44a
--- /dev/null
+++ b/pkg/templates/aws/edges/kubernetes_storage_class-eks_cluster.yaml
@@ -0,0 +1,2 @@
+source: kubernetes:storage_class
+target: aws:eks_cluster
\ No newline at end of file
diff --git a/pkg/templates/kubernetes/edges/pod-persistent_volume.yaml b/pkg/templates/kubernetes/edges/pod-persistent_volume.yaml
index 5ca7f930..3205481b 100644
--- a/pkg/templates/kubernetes/edges/pod-persistent_volume.yaml
+++ b/pkg/templates/kubernetes/edges/pod-persistent_volume.yaml
@@ -8,13 +8,13 @@ operational_rules:
         configuration:
           field: Object.spec.volumes
           value:
-            - Name: '{{ fieldValue "Object.metadata.name" .Target }}'
-              PersistentVolumeClaim:
-                ClaimName: '{{ fieldValue "Object.metadata.name" (downstream "kubernetes:persistent_volume_claim" .Target) }}'
+            - name: '{{ fieldValue "Object.metadata.name" .Target }}'
+              persistentVolumeClaim:
+                claimName: '{{ fieldValue "Object.metadata.name" (downstream "kubernetes:persistent_volume_claim" .Target) }}'
       - resource: '{{ .Source }}'
         configuration:
           field: Object.spec.containers[0].volumeMounts
           value:
-            - Name: '{{ fieldValue "Object.metadata.name" .Target }}'
+            - name: '{{ fieldValue "Object.metadata.name" .Target }}'
               mountPath: /mnt/efs
       
\ No newline at end of file
diff --git a/pkg/templates/kubernetes/resources/pod.yaml b/pkg/templates/kubernetes/resources/pod.yaml
index 43668768..95ee9683 100644
--- a/pkg/templates/kubernetes/resources/pod.yaml
+++ b/pkg/templates/kubernetes/resources/pod.yaml
@@ -47,7 +47,7 @@ consumption:
           {
             "name": "{{ $key }}",
             "value": "{{ $value }}"
-          }{{if ne $i (sub (len $) 1)}},{{end}}
+          }{{if ne $i (sub (len $) 1)}},{{end}}{{ $i = add $i 1 }}
         {{ end }}
         ]
 
diff --git a/pkg/templates/kubernetes/resources/service.yaml b/pkg/templates/kubernetes/resources/service.yaml
index 92e611e5..01615186 100644
--- a/pkg/templates/kubernetes/resources/service.yaml
+++ b/pkg/templates/kubernetes/resources/service.yaml
@@ -14,6 +14,7 @@ sanitize_name:
 properties:
   Cluster:
     type: resource
+    namespace: true
     operational_rule:
       step:
         direction: downstream
diff --git a/pkg/templates/kubernetes/resources/target_group_binding.yaml b/pkg/templates/kubernetes/resources/target_group_binding.yaml
index f20b1e07..77fc2f73 100644
--- a/pkg/templates/kubernetes/resources/target_group_binding.yaml
+++ b/pkg/templates/kubernetes/resources/target_group_binding.yaml
@@ -16,6 +16,7 @@ properties:
     type: resource
     namespace: true
     operational_rule:
+      step:
         direction: downstream
         resources:
           - classifications:


Test patch:
diff --git a/pkg/engine2/testdata/k8s_api.dataflow-viz.yaml b/pkg/engine2/testdata/k8s_api.dataflow-viz.yaml
index 5a612b6c..51f217bc 100755
--- a/pkg/engine2/testdata/k8s_api.dataflow-viz.yaml
+++ b/pkg/engine2/testdata/k8s_api.dataflow-viz.yaml
@@ -8,7 +8,7 @@ resources:
     parent: vpc/vpc-0
 
   load_balancer/rest-api-4-integbcc77100 -> kubernetes:pod:eks_cluster-0/pod2:
-    path: aws:load_balancer_listener:rest_api_4_integration_0-pod2,aws:target_group:rest-api-4-integbcc77100,kubernetes:target_group_binding:restapi4integration0-pod2,kubernetes:service:restapi4integration0-pod2
+    path: aws:load_balancer_listener:rest_api_4_integration_0-pod2,aws:target_group:rest-api-4-integbcc77100,kubernetes:target_group_binding:eks_cluster-0:restapi4integration0-pod2,kubernetes:service:eks_cluster-0:restapi4integration0-pod2
 
 
   kubernetes:helm_chart:eks_cluster-0/metricsserver:
diff --git a/pkg/engine2/testdata/k8s_api.expect.yaml b/pkg/engine2/testdata/k8s_api.expect.yaml
index e4e53ed8..61117077 100755
--- a/pkg/engine2/testdata/k8s_api.expect.yaml
+++ b/pkg/engine2/testdata/k8s_api.expect.yaml
@@ -142,7 +142,8 @@ resources:
         Protocol: TCP
         TargetType: ip
         Vpc: aws:vpc:vpc-0
-    kubernetes:target_group_binding:restapi4integration0-pod2:
+    kubernetes:target_group_binding:eks_cluster-0:restapi4integration0-pod2:
+        Cluster: aws:eks_cluster:eks_cluster-0
         Object:
             apiVersion: elbv2.k8s.aws/v1beta1
             kind: TargetGroupBinding
@@ -175,7 +176,7 @@ resources:
             vpcId: aws:vpc:vpc-0#Id
             webhookNamespaceSelectors: null
         Version: 1.5.5
-    kubernetes:service:restapi4integration0-pod2:
+    kubernetes:service:eks_cluster-0:restapi4integration0-pod2:
         Cluster: aws:eks_cluster:eks_cluster-0
         Object:
             apiVersion: v1
@@ -284,12 +285,12 @@ resources:
                         - ec2.amazonaws.com
             Version: "2012-10-17"
         ManagedPolicies:
+            - arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
             - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
             - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
             - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
             - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
             - arn:aws:iam::aws:policy/AWSCloudMapFullAccess
-            - arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
     aws:iam_role:pod2:
         AssumeRolePolicyDoc:
             Statement:
@@ -501,12 +502,6 @@ resources:
               Protocol: "-1"
               ToPort: 0
         IngressRules:
-            - CidrBlocks:
-                - 10.0.128.0/18
-              Description: Allow ingress traffic from ip addresses within the subnet subnet-0
-              FromPort: 0
-              Protocol: "-1"
-              ToPort: 0
             - CidrBlocks:
                 - 10.0.192.0/18
               Description: Allow ingress traffic from ip addresses within the subnet subnet-1
@@ -524,6 +519,12 @@ resources:
               Protocol: "-1"
               Self: true
               ToPort: 0
+            - CidrBlocks:
+                - 10.0.128.0/18
+              Description: Allow ingress traffic from ip addresses within the subnet subnet-0
+              FromPort: 0
+              Protocol: "-1"
+              ToPort: 0
         Vpc: aws:vpc:vpc-0
     aws:route_table:vpc-0:subnet-0-route_table:
         Routes:
@@ -614,16 +615,18 @@ edges:
     aws:load_balancer:rest-api-4-integbcc77100 -> aws:subnet:vpc-0:subnet-0:
     aws:load_balancer:rest-api-4-integbcc77100 -> aws:subnet:vpc-0:subnet-1:
     aws:load_balancer_listener:rest_api_4_integration_0-pod2 -> aws:target_group:rest-api-4-integbcc77100:
-    aws:target_group:rest-api-4-integbcc77100 -> kubernetes:target_group_binding:restapi4integration0-pod2:
-    kubernetes:target_group_binding:restapi4integration0-pod2 -> aws:eks_cluster:eks_cluster-0:
-    kubernetes:target_group_binding:restapi4integration0-pod2 -> kubernetes:helm_chart:eks_cluster-0:aws-load-balancer-controller:
-    kubernetes:target_group_binding:restapi4integration0-pod2 -> kubernetes:service:restapi4integration0-pod2:
+    aws:target_group:rest-api-4-integbcc77100 -> kubernetes:target_group_binding:eks_cluster-0:restapi4integration0-pod2:
+    kubernetes:target_group_binding:eks_cluster-0:restapi4integration0-pod2 -> aws:eks_cluster:eks_cluster-0:
+    ? kubernetes:target_group_binding:eks_cluster-0:restapi4integration0-pod2 -> kubernetes:helm_chart:eks_cluster-0:aws-load-balancer-controller
+    :
+    ? kubernetes:target_group_binding:eks_cluster-0:restapi4integration0-pod2 -> kubernetes:service:eks_cluster-0:restapi4integration0-pod2
+    :
     kubernetes:helm_chart:eks_cluster-0:aws-load-balancer-controller -> aws:eks_cluster:eks_cluster-0:
     kubernetes:helm_chart:eks_cluster-0:aws-load-balancer-controller -> aws:region:region-0:
     ? kubernetes:helm_chart:eks_cluster-0:aws-load-balancer-controller -> kubernetes:service_account:eks_cluster-0:aws-load-balancer-controller
     :
-    kubernetes:service:restapi4integration0-pod2 -> aws:eks_cluster:eks_cluster-0:
-    kubernetes:service:restapi4integration0-pod2 -> kubernetes:pod:eks_cluster-0:pod2:
+    kubernetes:service:eks_cluster-0:restapi4integration0-pod2 -> aws:eks_cluster:eks_cluster-0:
+    kubernetes:service:eks_cluster-0:restapi4integration0-pod2 -> kubernetes:pod:eks_cluster-0:pod2:
     kubernetes:service_account:eks_cluster-0:aws-load-balancer-controller -> aws:eks_cluster:eks_cluster-0:
     kubernetes:service_account:eks_cluster-0:aws-load-balancer-controller -> aws:iam_role:aws-load-balancer-controller:
     kubernetes:pod:eks_cluster-0:pod2 -> aws:ecr_image:pod2-ecr_image:
diff --git a/pkg/engine2/testdata/k8s_api.iac-viz.yaml b/pkg/engine2/testdata/k8s_api.iac-viz.yaml
index fbd7a86f..d7c68c58 100755
--- a/pkg/engine2/testdata/k8s_api.iac-viz.yaml
+++ b/pkg/engine2/testdata/k8s_api.iac-viz.yaml
@@ -124,9 +124,9 @@ resources:
   kubernetes:helm_chart:eks_cluster-0/aws-load-balancer-controller -> region/region-0:
   kubernetes:helm_chart:eks_cluster-0/aws-load-balancer-controller -> kubernetes:service_account:eks_cluster-0/aws-load-balancer-controller:
 
-  kubernetes:service/restapi4integration0-pod2:
-  kubernetes:service/restapi4integration0-pod2 -> eks_cluster/eks_cluster-0:
-  kubernetes:service/restapi4integration0-pod2 -> kubernetes:pod:eks_cluster-0/pod2:
+  kubernetes:service:eks_cluster-0/restapi4integration0-pod2:
+  kubernetes:service:eks_cluster-0/restapi4integration0-pod2 -> eks_cluster/eks_cluster-0:
+  kubernetes:service:eks_cluster-0/restapi4integration0-pod2 -> kubernetes:pod:eks_cluster-0/pod2:
 
   kubernetes:config_map/fluent-bit-cluster-info:
   kubernetes:config_map/fluent-bit-cluster-info -> eks_cluster/eks_cluster-0:
@@ -155,11 +155,11 @@ resources:
   aws:api_deployment:rest_api_4/api_deployment-0 -> aws:api_method:rest_api_4/rest_api_4_integration_0_method:
   aws:api_deployment:rest_api_4/api_deployment-0 -> rest_api/rest_api_4:
 
-  kubernetes:target_group_binding/restapi4integration0-pod2:
-  kubernetes:target_group_binding/restapi4integration0-pod2 -> eks_cluster/eks_cluster-0:
-  kubernetes:target_group_binding/restapi4integration0-pod2 -> target_group/rest-api-4-integbcc77100:
-  kubernetes:target_group_binding/restapi4integration0-pod2 -> kubernetes:helm_chart:eks_cluster-0/aws-load-balancer-controller:
-  kubernetes:target_group_binding/restapi4integration0-pod2 -> kubernetes:service/restapi4integration0-pod2:
+  kubernetes:target_group_binding:eks_cluster-0/restapi4integration0-pod2:
+  kubernetes:target_group_binding:eks_cluster-0/restapi4integration0-pod2 -> eks_cluster/eks_cluster-0:
+  kubernetes:target_group_binding:eks_cluster-0/restapi4integration0-pod2 -> target_group/rest-api-4-integbcc77100:
+  kubernetes:target_group_binding:eks_cluster-0/restapi4integration0-pod2 -> kubernetes:helm_chart:eks_cluster-0/aws-load-balancer-controller:
+  kubernetes:target_group_binding:eks_cluster-0/restapi4integration0-pod2 -> kubernetes:service:eks_cluster-0/restapi4integration0-pod2:
 
   kubernetes:manifest/fluent-bit:
   kubernetes:manifest/fluent-bit -> eks_cluster/eks_cluster-0: