Repository: cloudposse-terraform-components/aws-eks-karpenter-node-pool
Pull request #16: Add component tests
Author: login: goruha
Created: 2025-04-04T22:36:50Z | Merged: 2025-04-05T07:23:29Z

# What
* [x] Add `basic` component test
* [x] Add `disabled` component test
* [x] Test component drifting
* [ ] Add any additional use case tests


# Why
* Test basic component features
* Verify that the component does not create any resources when input `enabled: false` set
* Verify that the component does not drift on a second run with the same inputs
* Add test for any additional than basic use cases for the component

# References
* [Component test writing guide](https://docs.cloudposse.com/community/contribute/component-testing/)
* [List of component tests are done](https://github.com/orgs/cloudposse-terraform-components/projects/1/views/3)


<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **Refactor**  
  - Streamlined infrastructure role assignment to simplify deployment logic.  

- **New Features**  
  - Introduced several new configuration files enhancing cloud infrastructure management for clusters, node pools, networking, and vendor integrations.  
  - Added a flexible CLI configuration for customized deployments.  

- **Tests**  
  - Launched an expanded test suite to validate deployment behavior and resource provisioning.  

- **Chores**  
  - Upgraded remote state versions, improved dependency management, updated ignore rules, and removed an obsolete test script.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->


Diff:
diff --git a/src/provider-helm.tf b/src/provider-helm.tf
index 91cc7f6..ee1aaa6 100644
--- a/src/provider-helm.tf
+++ b/src/provider-helm.tf
@@ -133,9 +133,8 @@ locals {
     "--profile", var.kube_exec_auth_aws_profile
   ] : []
 
-  kube_exec_auth_role_arn = coalesce(var.kube_exec_auth_role_arn, module.iam_roles.terraform_role_arn)
   exec_role = local.kube_exec_auth_enabled && var.kube_exec_auth_role_arn_enabled ? [
-    "--role-arn", local.kube_exec_auth_role_arn
+    "--role-arn", coalesce(var.kube_exec_auth_role_arn, module.iam_roles.terraform_role_arn)
   ] : []
 
   # Provide dummy configuration for the case where the EKS cluster is not available.
diff --git a/src/providers.tf b/src/providers.tf
index c2419aa..61d4e74 100644
--- a/src/providers.tf
+++ b/src/providers.tf
@@ -4,7 +4,7 @@ provider "aws" {
   profile = module.iam_roles.profiles_enabled ? coalesce(var.import_profile_name, module.iam_roles.terraform_profile_name) : null
 
   dynamic "assume_role" {
-    for_each = module.iam_roles.profiles_enabled ? [] : ["role"]
+    for_each = compact([module.iam_roles.terraform_role_arn])
     content {
       role_arn = coalesce(var.import_role_arn, module.iam_roles.terraform_role_arn)
     }
diff --git a/src/remote-state.tf b/src/remote-state.tf
index ffca1d8..fef1be2 100644
--- a/src/remote-state.tf
+++ b/src/remote-state.tf
@@ -1,6 +1,6 @@
 module "eks" {
   source  = "cloudposse/stack-config/yaml//modules/remote-state"
-  version = "1.5.0"
+  version = "1.8.0"
 
   component = var.eks_component_name
 
@@ -16,7 +16,7 @@ module "eks" {
 
 module "vpc" {
   source  = "cloudposse/stack-config/yaml//modules/remote-state"
-  version = "1.5.0"
+  version = "1.8.0"
 
   component = "vpc"
 
diff --git a/test/.gitignore b/test/.gitignore
new file mode 100644
index 0000000..9807fcc
--- /dev/null
+++ b/test/.gitignore
@@ -0,0 +1,5 @@
+state/
+.cache
+test/test-suite.json
+.atmos
+test_suite.yaml
diff --git a/test/component_test.go b/test/component_test.go
new file mode 100644
index 0000000..9b80fb8
--- /dev/null
+++ b/test/component_test.go
@@ -0,0 +1,125 @@
+package test
+
+import (
+	"context"
+	"fmt"
+	"testing"
+	helper "github.com/cloudposse/test-helpers/pkg/atmos/component-helper"
+	awsHelper "github.com/cloudposse/test-helpers/pkg/aws"
+	"github.com/cloudposse/test-helpers/pkg/atmos"
+	"github.com/stretchr/testify/assert"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+    corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/runtime/schema"
+	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+
+	"k8s.io/client-go/dynamic"
+)
+
+type ComponentSuite struct {
+	helper.TestSuite
+}
+
+func (s *ComponentSuite) TestBasic() {
+	const component = "eks/karpenter-node-pool/basic"
+	const stack = "default-test"
+	const awsRegion = "us-east-2"
+
+	inputs := map[string]interface{}{}
+
+	defer s.DestroyAtmosComponent(s.T(), component, stack, &inputs)
+	options, _ := s.DeployAtmosComponent(s.T(), component, stack, &inputs)
+	assert.NotNil(s.T(), options)
+
+	var nodePools map[string]interface{}
+	atmos.OutputStruct(s.T(), options, "node_pools", &nodePools)
+	assert.NotEmpty(s.T(), nodePools)
+
+
+	var ec2NodeClasses map[string]interface{}
+	atmos.OutputStruct(s.T(), options, "ec2_node_classes", &ec2NodeClasses)
+	assert.NotEmpty(s.T(), nodePools)
+
+	clusterOptions := s.GetAtmosOptions("eks/cluster", stack, nil)
+	clusrerId := atmos.Output(s.T(), clusterOptions, "eks_cluster_id")
+
+	cluster := awsHelper.GetEksCluster(s.T(), context.Background(), awsRegion, clusrerId)
+
+	config, err := awsHelper.NewK8SClientConfig(cluster)
+	assert.NoError(s.T(), err)
+	assert.NotNil(s.T(), config)
+
+	dynamicClient, err := dynamic.NewForConfig(config)
+	if err != nil {
+		panic(fmt.Errorf("failed to create dynamic client: %v", err))
+	}
+
+	// Define the GroupVersionResource for the EC2NodeClass CRD
+	ec2NodeClassesGVR := schema.GroupVersionResource{
+		Group:    "karpenter.k8s.aws",
+		Version:  "v1",
+		Resource: "ec2nodeclasses",
+	}
+
+	ec2NodeClassesList, err := dynamicClient.Resource(ec2NodeClassesGVR).Namespace(corev1.NamespaceAll).List(context.Background(), metav1.ListOptions{})
+	assert.NoError(s.T(), err)
+
+	assert.Equal(s.T(), len(ec2NodeClassesList.Items), 1)
+	ec2NodeClassDefault := ec2NodeClassesList.Items[0]
+
+	assert.Equal(s.T(), ec2NodeClassDefault.GetName(), "default")
+
+	conditions, exists, err := unstructured.NestedSlice(ec2NodeClassDefault.Object, "status", "conditions")
+	assert.NoError(s.T(), err)
+	assert.True(s.T(), exists)
+	for _, condition := range conditions {
+		conditionMap := condition.(map[string]interface{})
+		assert.Equal(s.T(), conditionMap["status"], "True")
+	}
+
+
+	nodePoolGVR := schema.GroupVersionResource{
+		Group:    "karpenter.sh",
+		Version:  "v1",
+		Resource: "nodepools",
+	}
+
+	nodePoolsList, err := dynamicClient.Resource(nodePoolGVR).Namespace(corev1.NamespaceAll).List(context.Background(), metav1.ListOptions{})
+	assert.NoError(s.T(), err)
+
+	assert.Equal(s.T(), len(nodePoolsList.Items), 1)
+	nodePoolDefault := nodePoolsList.Items[0]
+
+	assert.Equal(s.T(), nodePoolDefault.GetName(), "default")
+
+	conditions, exists, err = unstructured.NestedSlice(nodePoolDefault.Object, "status", "conditions")
+	assert.NoError(s.T(), err)
+	assert.True(s.T(), exists)
+	for _, condition := range conditions {
+		conditionMap := condition.(map[string]interface{})
+		assert.Equal(s.T(), conditionMap["status"], "True")
+	}
+
+	s.DriftTest(component, stack, &inputs)
+}
+
+func (s *ComponentSuite) TestEnabledFlag() {
+	const component = "eks/karpenter-node-pool/disabled"
+	const stack = "default-test"
+	s.VerifyEnabledFlag(component, stack, nil)
+}
+
+func (s *ComponentSuite) SetupSuite() {
+	s.TestSuite.InitConfig()
+	s.TestSuite.Config.ComponentDestDir = "components/terraform/eks/karpenter-node-pool"
+	s.TestSuite.SetupSuite()
+}
+
+func TestRunSuite(t *testing.T) {
+	suite := new(ComponentSuite)
+	suite.AddDependency(t, "vpc", "default-test", nil)
+	suite.AddDependency(t, "eks/cluster", "default-test", nil)
+	suite.AddDependency(t, "eks/karpenter-controller", "default-test", nil)
+	helper.Run(t, suite)
+}
diff --git a/test/fixtures/atmos.yaml b/test/fixtures/atmos.yaml
new file mode 100644
index 0000000..214a451
--- /dev/null
+++ b/test/fixtures/atmos.yaml
@@ -0,0 +1,77 @@
+# CLI config is loaded from the following locations (from lowest to highest priority):
+# system dir (`/usr/local/etc/atmos` on Linux, `%LOCALAPPDATA%/atmos` on Windows)
+# home dir (~/.atmos)
+# current directory
+# ENV vars
+# Command-line arguments
+#
+# It supports POSIX-style Globs for file names/paths (double-star `**` is supported)
+# https://en.wikipedia.org/wiki/Glob_(programming)
+
+# Base path for components, stacks and workflows configurations.
+# Can also be set using `ATMOS_BASE_PATH` ENV var, or `--base-path` command-line argument.
+# Supports both absolute and relative paths.
+# If not provided or is an empty string, `components.terraform.base_path`, `components.helmfile.base_path`, `stacks.base_path` and `workflows.base_path`
+# are independent settings (supporting both absolute and relative paths).
+# If `base_path` is provided, `components.terraform.base_path`, `components.helmfile.base_path`, `stacks.base_path` and `workflows.base_path`
+# are considered paths relative to `base_path`.
+base_path: ""
+
+components:
+  terraform:
+    # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_BASE_PATH` ENV var, or `--terraform-dir` command-line argument
+    # Supports both absolute and relative paths
+    base_path: "components/terraform"
+    # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_APPLY_AUTO_APPROVE` ENV var
+    apply_auto_approve: true
+    # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_DEPLOY_RUN_INIT` ENV var, or `--deploy-run-init` command-line argument
+    deploy_run_init: true
+    # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_INIT_RUN_RECONFIGURE` ENV var, or `--init-run-reconfigure` command-line argument
+    init_run_reconfigure: true
+    # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_AUTO_GENERATE_BACKEND_FILE` ENV var, or `--auto-generate-backend-file` command-line argument
+    auto_generate_backend_file: true
+
+stacks:
+  # Can also be set using `ATMOS_STACKS_BASE_PATH` ENV var, or `--config-dir` and `--stacks-dir` command-line arguments
+  # Supports both absolute and relative paths
+  base_path: "stacks"
+  # Can also be set using `ATMOS_STACKS_INCLUDED_PATHS` ENV var (comma-separated values string)
+  # Since we are distinguishing stacks based on namespace, and namespace is not part
+  # of the stack name, we have to set `included_paths` via the ENV var in the Dockerfile
+  included_paths:
+    - "orgs/**/*"
+
+  # Can also be set using `ATMOS_STACKS_EXCLUDED_PATHS` ENV var (comma-separated values string)
+  excluded_paths:
+    - "**/_defaults.yaml"
+
+  # Can also be set using `ATMOS_STACKS_NAME_PATTERN` ENV var
+  name_pattern: "{tenant}-{stage}"
+
+workflows:
+  # Can also be set using `ATMOS_WORKFLOWS_BASE_PATH` ENV var, or `--workflows-dir` command-line arguments
+  # Supports both absolute and relative paths
+  base_path: "stacks/workflows"
+
+# https://github.com/cloudposse/atmos/releases/tag/v1.33.0
+logs:
+  file: "/dev/stdout"
+  # Supported log levels: Trace, Debug, Info, Warning, Off
+  level: Info
+
+settings:
+  # Can also be set using 'ATMOS_SETTINGS_LIST_MERGE_STRATEGY' environment variable, or '--settings-list-merge-strategy' command-line argument
+  list_merge_strategy: replace
+
+# `Go` templates in Atmos manifests
+# https://atmos.tools/core-concepts/stacks/templating
+# https://pkg.go.dev/text/template
+templates:
+  settings:
+    enabled: true
+    # https://masterminds.github.io/sprig
+    sprig:
+      enabled: true
+    # https://docs.gomplate.ca
+    gomplate:
+      enabled: true
diff --git a/test/fixtures/stacks/catalog/account-map.yaml b/test/fixtures/stacks/catalog/account-map.yaml
new file mode 100644
index 0000000..f83f5d7
--- /dev/null
+++ b/test/fixtures/stacks/catalog/account-map.yaml
@@ -0,0 +1,46 @@
+components:
+  terraform:
+    account-map:
+      metadata:
+        terraform_workspace: core-gbl-root
+      vars:
+        tenant: core
+        environment: gbl
+        stage: root
+
+#      This remote state is only for Cloud Posse internal use.
+#      It references the Cloud Posse test organizations actual infrastructure.
+#      remote_state_backend:
+#        s3:
+#          bucket: cptest-core-ue2-root-tfstate-core
+#          dynamodb_table: cptest-core-ue2-root-tfstate-core-lock
+#          role_arn: arn:aws:iam::822777368227:role/cptest-core-gbl-root-tfstate-core-ro
+#          encrypt: true
+#          key: terraform.tfstate
+#          acl: bucket-owner-full-control
+#          region: us-east-2
+
+      remote_state_backend_type: static
+      remote_state_backend:
+        # This static backend is used for tests that only need to use the account map iam-roles module
+        # to find the role to assume for Terraform operations. It is configured to use whatever
+        # the current user's role is, but the environment variable `TEST_ACCOUNT_ID` must be set to
+        # the account ID of the account that the user is currently assuming a role in.
+        #
+        # For some components, this backend is missing important data, and those components
+        # will need that data added to the backend configuration in order to work properly.
+        static:
+          account_info_map: {}
+          all_accounts: []
+          aws_partition: aws
+          full_account_map: {}
+          iam_role_arn_templates: {}
+          non_eks_accounts: []
+          profiles_enabled: false
+          root_account_aws_name: root
+          terraform_access_map: {}
+          terraform_dynamic_role_enabled: false
+          terraform_role_name_map:
+            apply: terraform
+            plan: planner
+          terraform_roles: {}
diff --git a/test/fixtures/stacks/catalog/eks-cluster.yaml b/test/fixtures/stacks/catalog/eks-cluster.yaml
new file mode 100644
index 0000000..85e3ce3
--- /dev/null
+++ b/test/fixtures/stacks/catalog/eks-cluster.yaml
@@ -0,0 +1,94 @@
+components:
+  terraform:
+    eks/cluster:
+      metadata:
+        component: eks/cluster
+      vars:
+        enabled: true
+
+        # Cluster node configuration
+        aws_ssm_agent_enabled: true
+        managed_node_groups_enabled: true
+        node_groups: # will create node group for each item in map
+          main: # Karpenter is responsible for scaling nodes, but this default node group is required for deploying EKS Addons
+            # EKS AMI version to use, e.g. "1.16.13-20200821" (no "v").
+            ami_release_version: null
+            # Type of Amazon Machine Image (AMI) associated with the EKS Node Group
+            ami_type: AL2_x86_64
+            # Additional name attributes (e.g. `1`) for the node group
+            attributes: []
+            # will create 1 auto scaling group in each specified availability zone
+            # or all AZs with subnets if none are specified anywhere
+            availability_zones: null
+            # Whether to enable Node Group to scale its AutoScaling Group
+            cluster_autoscaler_enabled: false
+            # True (recommended) to create new node_groups before deleting old ones, avoiding a temporary outage
+            create_before_destroy: true
+            # Desired number of worker nodes when initially provisioned
+            desired_group_size: 2
+            # Enable disk encryption for the created launch template (if we aren't provided with an existing launch template)
+            disk_encryption_enabled: true
+            # Disk size in GiB for worker nodes. Terraform will only perform drift detection if a configuration value is provided.
+            disk_size: 20
+            # Set of instance types associated with the EKS Node Group. Terraform will only perform drift detection if a configuration value is provided.
+            instance_types:
+              - t3.small
+            kubernetes_labels: {}
+            kubernetes_taints: []
+            node_role_policy_arns: null
+            kubernetes_version: null
+            max_group_size: 3
+            min_group_size: 2
+            resources_to_tag:
+              - instance
+              - volume
+            tags: null
+
+        access_config:
+          authentication_mode: "API"
+          bootstrap_cluster_creator_admin_permissions: true
+
+        # Fargate profiles, required for Karpenter
+        fargate_profiles:
+          karpenter:
+            kubernetes_namespace: karpenter
+            kubernetes_labels: null
+        fargate_profile_iam_role_kubernetes_namespace_delimiter: "@"
+        karpenter_iam_role_enabled: true
+
+        # Legacy settings
+        # The upstream component sets these to true by default to avoid breaking existing deployments,
+        # but new deployments should have these settings all disabled.
+        legacy_fargate_1_role_per_profile_enabled: false
+
+        addons_depends_on: true
+        deploy_addons_to_fargate: false
+
+        allow_ingress_from_vpc_accounts: []
+        public_access_cidrs: ["0.0.0.0/0"]
+        allowed_cidr_blocks: []
+        allowed_security_groups: []
+
+        enabled_cluster_log_types: []
+        apply_config_map_aws_auth: true
+        availability_zone_abbreviation_type: fixed
+        cluster_private_subnets_only: true
+        cluster_encryption_config_enabled: true
+        cluster_endpoint_private_access: true
+        cluster_endpoint_public_access: true
+        cluster_log_retention_period: 90
+        oidc_provider_enabled: true
+        cluster_kubernetes_version: "1.31"
+        addons:
+          vpc-cni:
+            addon_version: "v1.18.3-eksbuild.3"
+          kube-proxy:
+            addon_version: "v1.30.3-eksbuild.5"
+          coredns:
+            addon_version: "v1.11.3-eksbuild.1"
+            configuration_values: '{"autoScaling":{"enabled":true,"minReplicas":3}}'
+          aws-ebs-csi-driver:
+            addon_version: "v1.34.0-eksbuild.1"
+            configuration_values: '{"sidecars":{"snapshotter":{"forceEnable":false}}}'
+          aws-efs-csi-driver:
+            addon_version: "v2.0.8-eksbuild.1"
\ No newline at end of file
diff --git a/test/fixtures/stacks/catalog/eks-karpenter-controller.yaml b/test/fixtures/stacks/catalog/eks-karpenter-controller.yaml
new file mode 100644
index 0000000..bd921e6
--- /dev/null
+++ b/test/fixtures/stacks/catalog/eks-karpenter-controller.yaml
@@ -0,0 +1,44 @@
+components:
+  terraform:
+    eks/karpenter-controller:
+      metadata:
+        component: eks/karpenter-controller
+      vars:
+        enabled: true
+        kube_exec_auth_role_arn_enabled: false
+        name: "karpenter"
+        # https://github.com/aws/karpenter/tree/main/charts/karpenter
+        chart_repository: "oci://public.ecr.aws/karpenter"
+        chart: "karpenter"
+        chart_version: "1.0.0"
+        # Enable Karpenter to get advance notice of spot instances being terminated
+        # See https://karpenter.sh/docs/concepts/#interruption
+        interruption_handler_enabled: true
+        resources:
+          limits:
+            cpu: "100m"
+            memory: "512Mi"
+          requests:
+            cpu: "100m"
+            memory: "512Mi"
+        cleanup_on_fail: true
+        atomic: true
+        wait: true
+        rbac_enabled: true
+        # "karpenter-crd" can be installed as an independent helm chart to manage the lifecycle of Karpenter CRDs
+        crd_chart_enabled: true
+        crd_chart: "karpenter-crd"
+        # replicas set the number of Karpenter controller replicas to run
+        replicas: 2
+        # "settings" controls a subset of the settings for the Karpenter controller regarding batch idle and max duration.
+        # you can read more about these settings here: https://karpenter.sh/docs/reference/settings/
+        settings:
+          batch_idle_duration: "1s"
+          batch_max_duration: "10s"
+        # The logging settings for the Karpenter controller
+        logging:
+          enabled: true
+          level:
+            controller: "info"
+            global: "info"
+            webhook: "error"
diff --git a/test/fixtures/stacks/catalog/usecase/basic.yaml b/test/fixtures/stacks/catalog/usecase/basic.yaml
new file mode 100644
index 0000000..9637a50
--- /dev/null
+++ b/test/fixtures/stacks/catalog/usecase/basic.yaml
@@ -0,0 +1,187 @@
+components:
+  terraform:
+    eks/karpenter-node-pool/basic:
+      metadata:
+        component: eks/karpenter-node-pool
+      vars:
+        enabled: true
+        kube_exec_auth_role_arn_enabled: false
+        name: "karpenter-node-pool"
+        # https://karpenter.sh/v0.36.0/docs/concepts/nodepools/
+        node_pools:
+          default:
+            labels:
+              test: test
+            annotations:
+              test: test
+            # Whether to place EC2 instances launched by Karpenter into VPC private subnets. Set it to `false` to use public subnets
+            private_subnets_enabled: true
+            disruption:
+              max_instance_lifetime: "1h" # 14 days
+            # Karpenter provisioner total CPU limit for all pods running on the EC2 instances launched by Karpenter
+            total_cpu_limit: "100"
+            # Karpenter provisioner total memory limit for all pods running on the EC2 instances launched by Karpenter
+            total_memory_limit: "1000Gi"
+            # # Karpenter provisioner metadata options
+            # metadata_options: {}
+            # The AMI used by Karpenter provisioner when provisioning nodes. Based on the value set for amiFamily, Karpenter will automatically query for the appropriate EKS optimized AMI via AWS Systems Manager (SSM)
+            # Bottlerocket, AL2, Ubuntu
+            # https://karpenter.sh/docs/concepts/nodepools/#spectemplatespecrequirements
+            ami_family: AL2
+            # Karpenter provisioner block device mappings.
+            block_device_mappings:
+              - deviceName: /dev/xvda
+                ebs:
+                  volumeSize: 200Gi
+                  volumeType: gp3
+                  encrypted: true
+                  deleteOnTermination: true
+            # Set acceptable (In) and unacceptable (Out) Kubernetes and Karpenter values for node provisioning based on
+            # Well-Known Labels and cloud-specific settings. These can include instance types, zones, computer architecture,
+            # and capacity type (such as AWS spot or on-demand).
+            # See https://karpenter.sh/docs/concepts/nodepools/#spectemplatespecrequirements for more details
+            requirements:
+              # We do not need to set instance-category or generation because we set family explicitly.
+              #  # instance-category and instance-generation are required if you do not have any other instance-* restrictions,
+              #  # because otherwise Karpenter will fill in defaults, and you will get the error
+              #  # "Provider produced inconsistent result after apply"
+              #  - key: karpenter.k8s.aws/instance-category
+              #    operator: In
+              #    values: ["c", "m", "r"]
+              #  - key: karpenter.k8s.aws/instance-generation
+              #    operator: Gt
+              #    values: ["2"]
+              # Require encryption in transit. If we did not have a more explicit SCP, this
+              # would be sufficient to ensure that all instances are encrypted in transit.
+              - key: "karpenter.k8s.aws/instance-encryption-in-transit-supported"
+                operator: "In"
+                values: ["true"]
+              # Exclude instance types with 1 vCPU to make room for all the DaemonSets
+              - key: "karpenter.k8s.aws/instance-cpu"
+                operator: Gt
+                values: ["1"]
+              # With a lot of pods, we start hitting IOPS and Bandwidth issues
+              # on the EBS volume. Split things up over smaller instances
+              # (< 32 vCPUs) to ensure adequate disk performance.
+              - key: "karpenter.k8s.aws/instance-cpu"
+                operator: Lt
+                values: ["32"]
+              # See https://karpenter.sh/docs/concepts/nodepools/#capacity-type
+              # Allow fallback to on-demand instances when spot instances are unavailable
+              # By default, Karpenter uses the "price-capacity-optimized" allocation strategy
+              # https://aws.amazon.com/blogs/compute/introducing-price-capacity-optimized-allocation-strategy-for-ec2-spot-instances/
+              # It is currently not configurable, but that may change in the future.
+              # See https://github.com/aws/karpenter-provider-aws/issues/1240
+              - key: "karpenter.sh/capacity-type"
+                operator: "In"
+                values:
+                  - "on-demand"
+                  - "spot"
+
+              - key: "kubernetes.io/arch"
+                operator: "In"
+                values:
+                  - "amd64"
+
+              # Set instance family according to the DenyEC2InstancesWithoutEncryptionInTransit SCP
+              # https://raw.githubusercontent.com/cloudposse/terraform-aws-service-control-policies/0.14.1/catalog/ec2-policies.yaml
+              # We do this explicitly, despite the "instance-encryption-in-transit-supported" requirement, because
+              # new instance families will be added before the SCP is updated, and Karpenter just gives up if it
+              # tries to launch an instance and fails due to the SCP.
+              - key: "karpenter.k8s.aws/instance-family"
+                operator: "In"
+                values:
+                  # updated 2024-04-11
+                  - c5a
+                  - c5ad
+                  - c5n
+                  - c6a
+                  - c6gn
+                  - c6i
+                  - c6id
+                  - c6in
+                  - c7a
+                  - c7g
+                  - c7gd
+                  - c7gn
+                  - c7i
+                  - d3
+                  - d3en
+                  - dl1
+                  - dl2q
+                  - g4ad
+                  - g4dn
+                  - g5
+                  - g6
+                  - gr6
+                  - hpc6a
+                  - hpc6id
+                  - hpc7a
+                  - hpc7g
+                  - i3en
+                  - i4g
+                  - i4i
+                  - im4gn
+                  - inf1
+                  - inf2
+                  - is4gen
+                  - m5dn
+                  - m5n
+                  - m5zn
+                  - m6a
+                  - m6i
+                  - m6id
+                  - m6idn
+                  - m6in
+                  - m7a
+                  - m7g
+                  - m7gd
+                  - m7i
+                  - m7i-flex
+                  - p3dn
+                  - p4d
+                  - p4de
+                  - p5
+                  - r5dn
+                  - r5n
+                  - r6a
+                  - r6i
+                  - r6id
+                  - r6idn
+                  - r6in
+                  - r7a
+                  - r7g
+                  - r7gd
+                  - r7i
+                  - r7iz
+                  - trn1
+                  - trn1n
+                  - u-12tb1
+                  - u-18tb1
+                  - u-24tb1
+                  - u-3tb1
+                  - u-6tb1
+                  - u-9tb1
+                  - vt1
+                  - x2idn
+                  - x2iedn
+                  - x2iezn
+          # extra-pool-example:
+          #   <<: *node_pool_defaults
+          #   # here's an example of an extra node pool
+          #   disruption:
+          #     consolidation_policy: "WhenEmpty"
+          #     # If used to host GitHub action runners, experience suggests
+          #     # 3m is the practical minimum value, and 5m is a more reasonable lower limit.
+          #     consolidate_after: "5m"
+          #   labels:
+          #     "acme.co/node-role": "atomic-tasks"
+          #   taints:
+          #     - key: "acme.co/atomic-tasks"
+          #       # you may want to have another, similar pool, but with value "long"
+          #       # that supports long-running jobs by only using on-demand instances.
+          #       value: "short"
+          #       effect: "NoSchedule"
+          #   disruption:
+          #     max_instance_lifetime: "8h"
+          #     consolidation_policy: "WhenEmpty"
\ No newline at end of file
diff --git a/test/fixtures/stacks/catalog/usecase/disabled.yaml b/test/fixtures/stacks/catalog/usecase/disabled.yaml
new file mode 100644
index 0000000..5579ecf
--- /dev/null
+++ b/test/fixtures/stacks/catalog/usecase/disabled.yaml
@@ -0,0 +1,99 @@
+components:
+  terraform:
+    eks/karpenter-node-pool/disabled:
+      metadata:
+        component: eks/karpenter-node-pool
+      vars:
+        enabled: false
+        kube_exec_auth_role_arn_enabled: false
+        name: "karpenter-node-pool"
+        node_pools:
+          default:
+            name: default
+            private_subnets_enabled: true
+            disruption:
+              consolidation_policy: WhenUnderutilized
+              consolidate_after: 1h
+              max_instance_lifetime: 336h
+              budgets:
+                # This budget allows 0 disruptions during business hours (from 9am to 5pm) on weekdays
+                - schedule: "0 9 * * mon-fri"
+                  duration: 8h
+                  nodes: "0"
+            # The total cpu of the cluster. Maps to spec.limits.cpu in the Karpenter NodeClass
+            total_cpu_limit: "100"
+            # The total memory of the cluster. Maps to spec.limits.memory in the Karpenter NodeClass
+            total_memory_limit: "1000Gi"
+            # The weight of the node pool. See https://karpenter.sh/docs/concepts/scheduling/#weighted-nodepools
+            weight: 50
+            # Taints to apply to the nodes in the node pool. See https://karpenter.sh/docs/concepts/nodeclasses/#spectaints
+            taints:
+              - key: "node.kubernetes.io/unreachable"
+                effect: "NoExecute"
+                value: "true"
+            # Taints to apply to the nodes in the node pool at startup. See https://karpenter.sh/docs/concepts/nodeclasses/#specstartuptaints
+            startup_taints:
+              - key: "node.kubernetes.io/unreachable"
+                effect: "NoExecute"
+                value: "true"
+            # Metadata options for the node pool. See https://karpenter.sh/docs/concepts/nodeclasses/#specmetadataoptions
+            metadata_options:
+              httpEndpoint: "enabled" # allows the node to call the AWS metadata service
+              httpProtocolIPv6: "disabled"
+              httpPutResponseHopLimit: 2
+              httpTokens: "required"
+            # The AMI used by Karpenter provisioner when provisioning nodes. Based on the value set for amiFamily, Karpenter will automatically query for the appropriate EKS optimized AMI via AWS Systems Manager (SSM)
+            # Bottlerocket, AL2, Ubuntu
+            # https://karpenter.sh/v0.18.0/aws/provisioning/#amazon-machine-image-ami-family
+            ami_family: AL2
+            # Karpenter provisioner block device mappings.
+            block_device_mappings:
+              - deviceName: /dev/xvda
+                ebs:
+                  volumeSize: 200Gi
+                  volumeType: gp3
+                  encrypted: true
+                  deleteOnTermination: true
+            # Set acceptable (In) and unacceptable (Out) Kubernetes and Karpenter values for node provisioning based on
+            # Well-Known Labels and cloud-specific settings. These can include instance types, zones, computer architecture,
+            # and capacity type (such as AWS spot or on-demand).
+            # See https://karpenter.sh/v0.18.0/provisioner/#specrequirements for more details
+            requirements:
+              - key: "karpenter.sh/capacity-type"
+                operator: "In"
+                values:
+                  - "on-demand"
+                  - "spot"
+              - key: "node.kubernetes.io/instance-type"
+                operator: "In"
+                # See https://aws.amazon.com/ec2/instance-explorer/ and https://aws.amazon.com/ec2/instance-types/
+                # Values limited by DenyEC2InstancesWithoutEncryptionInTransit service control policy
+                # See https://github.com/cloudposse/terraform-aws-service-control-policies/blob/master/catalog/ec2-policies.yaml
+                # Karpenter recommends allowing at least 20 instance types to ensure availability.
+                values:
+                  - "c5n.2xlarge"
+                  - "c5n.xlarge"
+                  - "c5n.large"
+                  - "c6i.2xlarge"
+                  - "c6i.xlarge"
+                  - "c6i.large"
+                  - "m5n.2xlarge"
+                  - "m5n.xlarge"
+                  - "m5n.large"
+                  - "m5zn.2xlarge"
+                  - "m5zn.xlarge"
+                  - "m5zn.large"
+                  - "m6i.2xlarge"
+                  - "m6i.xlarge"
+                  - "m6i.large"
+                  - "r5n.2xlarge"
+                  - "r5n.xlarge"
+                  - "r5n.large"
+                  - "r6i.2xlarge"
+                  - "r6i.xlarge"
+                  - "r6i.large"
+              - key: "kubernetes.io/arch"
+                operator: "In"
+                values:
+                  - "amd64"
+
diff --git a/test/fixtures/stacks/catalog/vpc.yaml b/test/fixtures/stacks/catalog/vpc.yaml
new file mode 100644
index 0000000..0c853bb
--- /dev/null
+++ b/test/fixtures/stacks/catalog/vpc.yaml
@@ -0,0 +1,19 @@
+components:
+  terraform:
+    vpc:
+      metadata:
+        component: vpc
+      vars:
+        name: "vpc"
+        availability_zones:
+          - "b"
+          - "c"
+        public_subnets_enabled: true
+        max_nats: 1
+        # Private subnets do not need internet access
+        nat_gateway_enabled: true
+        nat_instance_enabled: false
+        subnet_type_tag_key: "eg.cptest.co/subnet/type"
+        max_subnet_count: 3
+        vpc_flow_logs_enabled: false
+        ipv4_primary_cidr_block: "172.16.0.0/16"
diff --git a/test/fixtures/stacks/orgs/default/test/_defaults.yaml b/test/fixtures/stacks/orgs/default/test/_defaults.yaml
new file mode 100644
index 0000000..84d0e62
--- /dev/null
+++ b/test/fixtures/stacks/orgs/default/test/_defaults.yaml
@@ -0,0 +1,66 @@
+import:
+  - catalog/account-map
+
+terraform:
+  backend_type: local
+  backend:
+    local:
+      path: '{{ getenv "COMPONENT_HELPER_STATE_DIR" | default "../../../state" }}/{{ .component }}/terraform.tfstate'
+      workspace_dir: '{{ getenv "COMPONENT_HELPER_STATE_DIR" | default "../../../state" }}/{{ .component }}/'
+  vars:
+    namespace: eg
+    tenant: default
+    environment: ue2
+    region: us-east-2
+    stage: test
+    label_order:
+      - namespace
+      - tenant
+      - environment
+      - stage
+      - name
+      - attributes
+    descriptor_formats:
+      account_name:
+        format: "%v-%v"
+        labels:
+          - tenant
+          - stage
+      stack:
+        format: "%v-%v-%v"
+        labels:
+          - tenant
+          - environment
+          - stage
+
+components:
+  terraform:
+    account-map:
+      remote_state_backend:
+        static:
+          account_info_map:
+            default-test:
+              account_email_format: aws+cptest-%s@example.com
+              eks: true
+              id: '{{ getenv "TEST_ACCOUNT_ID" | default "<TEST_ACCOUNT_ID>" }}'
+              ou: default
+              parent_ou: none
+              stage: test
+              tags:
+                eks: false
+              tenant: default
+          all_accounts:
+            - default-test
+          artifacts_account_account_name: default-test
+          audit_account_account_name: default-test
+          dns_account_account_name: default-test
+          eks_accounts:
+            - default-test
+          full_account_map:
+            default-test: '{{ getenv "TEST_ACCOUNT_ID" | default "<TEST_ACCOUNT_ID>" }}'
+          iam_role_arn_templates:
+            default-test: 'arn:aws:iam::{{ getenv "TEST_ACCOUNT_ID" | default "<TEST_ACCOUNT_ID>" }}:role/tester-%s'
+          identity_account_account_name: default-test
+          root_account_account_name: default-test
+          terraform_roles:
+            default-test: ''
diff --git a/test/fixtures/stacks/orgs/default/test/tests.yaml b/test/fixtures/stacks/orgs/default/test/tests.yaml
new file mode 100644
index 0000000..7b991e6
--- /dev/null
+++ b/test/fixtures/stacks/orgs/default/test/tests.yaml
@@ -0,0 +1,7 @@
+import:
+  - orgs/default/test/_defaults
+  - catalog/vpc
+  - catalog/eks-cluster
+  - catalog/eks-karpenter-controller
+  - catalog/usecase/basic
+  - catalog/usecase/disabled
diff --git a/test/fixtures/vendor.yaml b/test/fixtures/vendor.yaml
new file mode 100644
index 0000000..5c66977
--- /dev/null
+++ b/test/fixtures/vendor.yaml
@@ -0,0 +1,54 @@
+apiVersion: atmos/v1
+kind: AtmosVendorConfig
+metadata:
+  name: fixtures
+  description: Atmos vendoring manifest
+spec:
+  sources:
+    - component: "account-map"
+      source: github.com/cloudposse/terraform-aws-components.git//modules/account-map?ref={{.Version}}
+      version: 1.520.0
+      targets:
+        - "components/terraform/account-map"
+      included_paths:
+        - "**/*.tf"
+        - "**/*.md"
+        - "**/*.tftmpl"
+        - "**/modules/**"
+      excluded_paths: []
+
+    - component: "eks/karpenter-controller"
+      source: github.com/cloudposse-terraform-components/aws-eks-karpenter-controller.git//src?ref={{.Version}}
+      version: v1.535.2
+      targets:
+        - "components/terraform/eks/karpenter-controller"
+      included_paths:
+        - "**/*.tf"
+        - "**/*.md"
+        - "**/*.tftmpl"
+        - "**/modules/**"
+      excluded_paths: []
+
+    - component: "eks/cluster"
+      source: github.com/cloudposse-terraform-components/aws-eks-cluster.git//src?ref={{.Version}}
+      version: v1.535.1
+      targets:
+        - "components/terraform/eks/cluster"
+      included_paths:
+        - "**/*.tf"
+        - "**/*.md"
+        - "**/*.tftmpl"
+        - "**/modules/**"
+      excluded_paths: []
+
+    - component: "vpc"
+      source: github.com/cloudposse-terraform-components/aws-vpc.git//src?ref={{.Version}}
+      version: v1.536.0
+      targets:
+        - "components/terraform/vpc"
+      included_paths:
+        - "**/*.tf"
+        - "**/*.md"
+        - "**/*.tftmpl"
+        - "**/modules/**"
+      excluded_paths: []
diff --git a/test/go.mod b/test/go.mod
new file mode 100644
index 0000000..33400b7
--- /dev/null
+++ b/test/go.mod
@@ -0,0 +1,183 @@
+module test
+
+go 1.23.4
+
+toolchain go1.23.7
+
+require (
+	github.com/cloudposse/test-helpers v0.23.0
+	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
+	github.com/gruntwork-io/terratest v0.48.2
+	github.com/mattn/go-zglob v0.0.6 // indirect
+	github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
+	github.com/stretchr/testify v1.10.0
+	gopkg.in/yaml.v3 v3.0.1 // indirect
+)
+
+// replace github.com/rebuy-de/aws-nuke/v2/mocks => github.com/ekristen/aws-nuke/v3/ v3.29.0
+
+require k8s.io/apimachinery v0.32.3
+
+require (
+	dario.cat/mergo v1.0.1 // indirect
+	filippo.io/edwards25519 v1.1.0 // indirect
+	github.com/agext/levenshtein v1.2.3 // indirect
+	github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
+	github.com/aws/aws-sdk-go v1.55.5 // indirect
+	github.com/aws/aws-sdk-go-v2 v1.36.3 // indirect
+	github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.8 // indirect
+	github.com/aws/aws-sdk-go-v2/config v1.29.6 // indirect
+	github.com/aws/aws-sdk-go-v2/credentials v1.17.59 // indirect
+	github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.28 // indirect
+	github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.61 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.32 // indirect
+	github.com/aws/aws-sdk-go-v2/service/acm v1.30.18 // indirect
+	github.com/aws/aws-sdk-go-v2/service/amplify v1.28.8 // indirect
+	github.com/aws/aws-sdk-go-v2/service/autoscaling v1.51.12 // indirect
+	github.com/aws/aws-sdk-go-v2/service/backup v1.40.10 // indirect
+	github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.47.4 // indirect
+	github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.45.12 // indirect
+	github.com/aws/aws-sdk-go-v2/service/docdb v1.40.10 // indirect
+	github.com/aws/aws-sdk-go-v2/service/dynamodb v1.40.1 // indirect
+	github.com/aws/aws-sdk-go-v2/service/ec2 v1.203.0 // indirect
+	github.com/aws/aws-sdk-go-v2/service/ecr v1.41.0 // indirect
+	github.com/aws/aws-sdk-go-v2/service/ecs v1.53.13 // indirect
+	github.com/aws/aws-sdk-go-v2/service/efs v1.34.11 // indirect
+	github.com/aws/aws-sdk-go-v2/service/eks v1.60.1 // indirect
+	github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.43.12 // indirect
+	github.com/aws/aws-sdk-go-v2/service/iam v1.39.1 // indirect
+	github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2 // indirect
+	github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.6.0 // indirect
+	github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.13 // indirect
+	github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.13 // indirect
+	github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.13 // indirect
+	github.com/aws/aws-sdk-go-v2/service/kafka v1.38.16 // indirect
+	github.com/aws/aws-sdk-go-v2/service/kms v1.37.18 // indirect
+	github.com/aws/aws-sdk-go-v2/service/lambda v1.69.12 // indirect
+	github.com/aws/aws-sdk-go-v2/service/rds v1.93.12 // indirect
+	github.com/aws/aws-sdk-go-v2/service/route53 v1.48.7 // indirect
+	github.com/aws/aws-sdk-go-v2/service/s3 v1.76.1 // indirect
+	github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.18 // indirect
+	github.com/aws/aws-sdk-go-v2/service/sesv2 v1.41.5 // indirect
+	github.com/aws/aws-sdk-go-v2/service/sns v1.33.19 // indirect
+	github.com/aws/aws-sdk-go-v2/service/sqs v1.37.14 // indirect
+	github.com/aws/aws-sdk-go-v2/service/ssm v1.56.12 // indirect
+	github.com/aws/aws-sdk-go-v2/service/sso v1.24.15 // indirect
+	github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.14 // indirect
+	github.com/aws/aws-sdk-go-v2/service/sts v1.33.14 // indirect
+	github.com/aws/aws-sdk-go-v2/service/wafv2 v1.58.0 // indirect
+	github.com/aws/smithy-go v1.22.2 // indirect
+	github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
+	github.com/beorn7/perks v1.0.1 // indirect
+	github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
+	github.com/boombuler/barcode v1.0.2 // indirect
+	github.com/cespare/xxhash/v2 v2.3.0 // indirect
+	github.com/charmbracelet/lipgloss v0.10.0 // indirect
+	github.com/charmbracelet/log v0.4.0 // indirect
+	github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
+	github.com/emicklei/go-restful/v3 v3.12.1 // indirect
+	github.com/fsnotify/fsnotify v1.8.0 // indirect
+	github.com/fxamacker/cbor/v2 v2.7.0 // indirect
+	github.com/go-errors/errors v1.5.1 // indirect
+	github.com/go-logfmt/logfmt v0.6.0 // indirect
+	github.com/go-logr/logr v1.4.2 // indirect
+	github.com/go-openapi/jsonpointer v0.21.0 // indirect
+	github.com/go-openapi/jsonreference v0.21.0 // indirect
+	github.com/go-openapi/swag v0.23.0 // indirect
+	github.com/go-sql-driver/mysql v1.8.1 // indirect
+	github.com/gofrs/flock v0.12.1 // indirect
+	github.com/gogo/protobuf v1.3.2 // indirect
+	github.com/golang/protobuf v1.5.4 // indirect
+	github.com/google/gnostic-models v0.6.9 // indirect
+	github.com/google/go-cmp v0.6.0 // indirect
+	github.com/google/gofuzz v1.2.0 // indirect
+	github.com/google/uuid v1.6.0 // indirect
+	github.com/gruntwork-io/go-commons v0.17.2 // indirect
+	github.com/hashicorp/errwrap v1.1.0 // indirect
+	github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
+	github.com/hashicorp/go-getter/v2 v2.2.3 // indirect
+	github.com/hashicorp/go-multierror v1.1.1 // indirect
+	github.com/hashicorp/go-safetemp v1.0.0 // indirect
+	github.com/hashicorp/go-version v1.7.0 // indirect
+	github.com/hashicorp/hcl v1.0.0 // indirect
+	github.com/hashicorp/hcl/v2 v2.22.0 // indirect
+	github.com/hashicorp/terraform-json v0.23.0 // indirect
+	github.com/jackc/pgpassfile v1.0.0 // indirect
+	github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
+	github.com/jackc/pgx/v5 v5.7.2 // indirect
+	github.com/jackc/puddle/v2 v2.2.2 // indirect
+	github.com/jinzhu/copier v0.4.0 // indirect
+	github.com/jmespath/go-jmespath v0.4.0 // indirect
+	github.com/josharian/intern v1.0.0 // indirect
+	github.com/json-iterator/go v1.1.12 // indirect
+	github.com/klauspost/compress v1.17.11 // indirect
+	github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
+	github.com/magiconair/properties v1.8.9 // indirect
+	github.com/mailru/easyjson v0.9.0 // indirect
+	github.com/mattn/go-isatty v0.0.20 // indirect
+	github.com/mattn/go-runewidth v0.0.15 // indirect
+	github.com/mitchellh/go-homedir v1.1.0 // indirect
+	github.com/mitchellh/go-testing-interface v1.14.1 // indirect
+	github.com/mitchellh/go-wordwrap v1.0.1 // indirect
+	github.com/mitchellh/mapstructure v1.5.0 // indirect
+	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+	github.com/modern-go/reflect2 v1.0.2 // indirect
+	github.com/muesli/reflow v0.3.0 // indirect
+	github.com/muesli/termenv v0.15.2 // indirect
+	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
+	github.com/pelletier/go-toml/v2 v2.2.3 // indirect
+	github.com/pkg/errors v0.9.1 // indirect
+	github.com/pquerna/otp v1.4.0 // indirect
+	github.com/prometheus/client_golang v1.20.5 // indirect
+	github.com/prometheus/client_model v0.6.1 // indirect
+	github.com/prometheus/common v0.61.0 // indirect
+	github.com/prometheus/procfs v0.15.1 // indirect
+	github.com/rivo/uniseg v0.4.7 // indirect
+	github.com/russross/blackfriday/v2 v2.1.0 // indirect
+	github.com/sagikazarmark/locafero v0.7.0 // indirect
+	github.com/sagikazarmark/slog-shim v0.1.0 // indirect
+	github.com/sirupsen/logrus v1.9.3 // indirect
+	github.com/sourcegraph/conc v0.3.0 // indirect
+	github.com/spf13/afero v1.12.0 // indirect
+	github.com/spf13/cast v1.7.1 // indirect
+	github.com/spf13/pflag v1.0.5 // indirect
+	github.com/spf13/viper v1.19.0 // indirect
+	github.com/subosito/gotenv v1.6.0 // indirect
+	github.com/tmccombs/hcl2json v0.6.4 // indirect
+	github.com/ulikunitz/xz v0.5.11 // indirect
+	github.com/urfave/cli/v2 v2.27.5 // indirect
+	github.com/x448/float16 v0.8.4 // indirect
+	github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
+	github.com/zclconf/go-cty v1.15.0 // indirect
+	go.uber.org/multierr v1.11.0 // indirect
+	golang.org/x/crypto v0.33.0 // indirect
+	golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
+	golang.org/x/mod v0.22.0 // indirect
+	golang.org/x/net v0.35.0 // indirect
+	golang.org/x/oauth2 v0.25.0 // indirect
+	golang.org/x/sync v0.11.0 // indirect
+	golang.org/x/sys v0.30.0 // indirect
+	golang.org/x/term v0.29.0 // indirect
+	golang.org/x/text v0.22.0 // indirect
+	golang.org/x/time v0.9.0 // indirect
+	golang.org/x/tools v0.29.0 // indirect
+	google.golang.org/protobuf v1.36.1 // indirect
+	gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
+	gopkg.in/inf.v0 v0.9.1 // indirect
+	gopkg.in/ini.v1 v1.67.0 // indirect
+	gopkg.in/yaml.v2 v2.4.0 // indirect
+	k8s.io/api v0.32.3 // indirect
+	k8s.io/apiextensions-apiserver v0.32.3 // indirect
+	k8s.io/client-go v0.32.3 // indirect
+	k8s.io/klog/v2 v2.130.1 // indirect
+	k8s.io/kube-aggregator v0.32.3 // indirect
+	k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect
+	k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
+	sigs.k8s.io/aws-iam-authenticator v0.6.30 // indirect
+	sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
+	sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect
+	sigs.k8s.io/yaml v1.4.0 // indirect
+)
diff --git a/test/go.sum b/test/go.sum
new file mode 100644
index 0000000..aa71197
--- /dev/null
+++ b/test/go.sum
@@ -0,0 +1,423 @@
+dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
+dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
+filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
+filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
+github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
+github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
+github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
+github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
+github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU=
+github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
+github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM=
+github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg=
+github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.8 h1:zAxi9p3wsZMIaVCdoiQp2uZ9k1LsZvmAnoTBeZPXom0=
+github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.8/go.mod h1:3XkePX5dSaxveLAYY7nsbsZZrKxCyEuE5pM4ziFxyGg=
+github.com/aws/aws-sdk-go-v2/config v1.29.6 h1:fqgqEKK5HaZVWLQoLiC9Q+xDlSp+1LYidp6ybGE2OGg=
+github.com/aws/aws-sdk-go-v2/config v1.29.6/go.mod h1:Ft+WLODzDQmCTHDvqAH1JfC2xxbZ0MxpZAcJqmE1LTQ=
+github.com/aws/aws-sdk-go-v2/credentials v1.17.59 h1:9btwmrt//Q6JcSdgJOLI98sdr5p7tssS9yAsGe8aKP4=
+github.com/aws/aws-sdk-go-v2/credentials v1.17.59/go.mod h1:NM8fM6ovI3zak23UISdWidyZuI1ghNe2xjzUZAyT+08=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.28 h1:KwsodFKVQTlI5EyhRSugALzsV6mG/SGrdjlMXSZSdso=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.28/go.mod h1:EY3APf9MzygVhKuPXAc5H+MkGb8k/DOSQjWS0LgkKqI=
+github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.61 h1:BBIPjlEWLxX1huGTkBu/eeqyaXC0pVwDCYbQuE/JPfU=
+github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.61/go.mod h1:6dkLZQM1D/wKKFJEvyB1OCXJ0f68wcIPDOiXm0KyT8A=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 h1:ZK5jHhnrioRkUNOc+hOgQKlUL5JeC3S6JgLxtQ+Rm0Q=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34/go.mod h1:p4VfIceZokChbA9FzMbRGz5OV+lekcVtHlPKEO0gSZY=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 h1:SZwFm17ZUNNg5Np0ioo/gq8Mn6u9w19Mri8DnJ15Jf0=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34/go.mod h1:dFZsC0BLo346mvKQLWmoJxT+Sjp+qcVR1tRVHQGOH9Q=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 h1:Pg9URiobXy85kgFev3og2CuOZ8JZUBENF+dcgWBaYNk=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc=
+github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.32 h1:OIHj/nAhVzIXGzbAE+4XmZ8FPvro3THr6NlqErJc3wY=
+github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.32/go.mod h1:LiBEsDo34OJXqdDlRGsilhlIiXR7DL+6Cx2f4p1EgzI=
+github.com/aws/aws-sdk-go-v2/service/acm v1.30.18 h1:/MZpjVk95P+lF9dUcOmyQwp1r0Ld4A8AxfQLdf1w8bU=
+github.com/aws/aws-sdk-go-v2/service/acm v1.30.18/go.mod h1:JaIJpS5R/ADAyK2gGYcQSmpMyty24/nLxvwsPe629BI=
+github.com/aws/aws-sdk-go-v2/service/amplify v1.28.8 h1:wg7HSb3XnRAcom2v3nqxyAhmySVwKkHIkaUiEIbV6vc=
+github.com/aws/aws-sdk-go-v2/service/amplify v1.28.8/go.mod h1:d0nnjwZRjEV9f6I8PEbBv0o3xjzVNLvlOYVxQs+FeEw=
+github.com/aws/aws-sdk-go-v2/service/autoscaling v1.51.12 h1:Bfz5hDqAgm9NByWdA0zfof70CVkjb6SE3RwU75lj66Y=
+github.com/aws/aws-sdk-go-v2/service/autoscaling v1.51.12/go.mod h1:+yg2Ygx7ParYfxoo1CLHzqD1zcmWuKNDfxuB8CrOx44=
+github.com/aws/aws-sdk-go-v2/service/backup v1.40.10 h1:/qkt3SKl7VUI48CV47dMdJGte/kg6YIs9HGucKRomY4=
+github.com/aws/aws-sdk-go-v2/service/backup v1.40.10/go.mod h1:Vdu4P8UrQhIh69PlgCuJFVicDJgy4Z6i0lAEpJLBw2Q=
+github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.47.4 h1:4hiC8jzPP89L+MTljvKs1LLC12gKJLMJwysjOrbJz1E=
+github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.47.4/go.mod h1:Kj+z0vXRl21DsnPR+lA5DjVWCaRTvAmwQ/shTGHeY84=
+github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.45.12 h1:B7P9U6OmFa+TEnpny4JpWnYBkBfMMU592fomNZxVIc0=
+github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.45.12/go.mod h1:omuyZE5hIJGMRTWvXfRPdEy85w4exm5e65/4ExTibJw=
+github.com/aws/aws-sdk-go-v2/service/docdb v1.40.10 h1:M+Pc9FI5Inm5P7IisViLbw8tnLyTvteTeuwN0mWPX8U=
+github.com/aws/aws-sdk-go-v2/service/docdb v1.40.10/go.mod h1:T0Kj3lj/4DSrtuqAt0yFLbhv5qydUgXEuL8enHpxpcg=
+github.com/aws/aws-sdk-go-v2/service/dynamodb v1.40.1 h1:JUvURAe0mNRzYd+1uTHEiojeyWtNPIQ5EXnDKfgKGUU=
+github.com/aws/aws-sdk-go-v2/service/dynamodb v1.40.1/go.mod h1:FcMiR2AALpkrpik6JzbYu+iEfktzrs3XOq5Shk9nvik=
+github.com/aws/aws-sdk-go-v2/service/ec2 v1.203.0 h1:EDLBXOs5D0KUqDThg8ID63mK5E7lJ8pjHGBtix6O9j0=
+github.com/aws/aws-sdk-go-v2/service/ec2 v1.203.0/go.mod h1:nSbxgPGhyI9j/cMVSHUEEtNQzEYeNOkbHnHNeTuQqt0=
+github.com/aws/aws-sdk-go-v2/service/ecr v1.41.0 h1:PNluoO7Sh1myhX+6MiAUpFk46fG6827K4U+KrtUT3s8=
+github.com/aws/aws-sdk-go-v2/service/ecr v1.41.0/go.mod h1:dtD3a4sjUjVL86e0NUvaqdGvds5ED6itUiZPDaT+Gh8=
+github.com/aws/aws-sdk-go-v2/service/ecs v1.53.13 h1:Q16+YitA+4nt8Iv+37l1Yav2ejlDb9umjJrEmX/3Xj4=
+github.com/aws/aws-sdk-go-v2/service/ecs v1.53.13/go.mod h1:X4pNdZOGNt0sWAErA0rQfrcl8NCoqDwAWtPa94bAafM=
+github.com/aws/aws-sdk-go-v2/service/efs v1.34.11 h1:PgeGNM3l3fg7UlFpIFEogySDrYsAeMVePZcHJJw5eVo=
+github.com/aws/aws-sdk-go-v2/service/efs v1.34.11/go.mod h1:pH1iibM/aigOyMTkB9RFdGDXbofNRaLzh1qoh2fIp6E=
+github.com/aws/aws-sdk-go-v2/service/eks v1.60.1 h1:Q5YEz2N233+N2rKuPF5qO0OR0qp69BnukHRmrnMjV0c=
+github.com/aws/aws-sdk-go-v2/service/eks v1.60.1/go.mod h1:v1xXy6ea0PHtWkjFUvAUh6B/5wv7UF909Nru0dOIJDk=
+github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.43.12 h1:PLoBTtHl376mmxe5NSMUx1UD8yiM+BgIi9yJ1SgibHk=
+github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.43.12/go.mod h1:h7JSZfD6QGeaAWpTk0+e1hQw2Venf5gh7UlUTEAiZL8=
+github.com/aws/aws-sdk-go-v2/service/iam v1.39.1 h1:N4OauekXigX0GgsJ+FUm7OO5HkrJR0ByZJ2YS5PIy3U=
+github.com/aws/aws-sdk-go-v2/service/iam v1.39.1/go.mod h1:8rUmP3N5TJXWWEzdQ+2Tc1IELc97pxBt5Zbt4QLq7KI=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2 h1:D4oz8/CzT9bAEYtVhSBmFj2dNOtaHOtMKc2vHBwYizA=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2/go.mod h1:Za3IHqTQ+yNcRHxu1OFucBh0ACZT4j4VQFF0BqpZcLY=
+github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.6.0 h1:kT2WeWcFySdYpPgyqJMSUE7781Qucjtn6wBvrgm9P+M=
+github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.6.0/go.mod h1:WYH1ABybY7JK9TITPnk6ZlP7gQB8psI4c9qDmMsnLSA=
+github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.13 h1:eWoHfLIzYeUtJEuoUmD5PwTE+fLaIPN9NZ7UXd9CW0s=
+github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.13/go.mod h1:x5t8Ve0J7JK9VHKSPSRAdBrWAgr/5hH3UeCFMLoyUGQ=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.13 h1:SYVGSFQHlchIcy6e7x12bsrxClCXSP5et8cqVhL8cuw=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.13/go.mod h1:kizuDaLX37bG5WZaoxGPQR/LNFXpxp0vsUnqfkWXfNE=
+github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.13 h1:OBsrtam3rk8NfBEq7OLOMm5HtQ9Yyw32X4UQMya/wjw=
+github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.13/go.mod h1:3U4gFA5pmoCOja7aq4nSaIAGbaOHv2Yl2ug018cmC+Q=
+github.com/aws/aws-sdk-go-v2/service/kafka v1.38.16 h1:r1mu+ZsoNt+3AuqYMyG2JoMkt6pYhfrzY34ENMVm6Uc=
+github.com/aws/aws-sdk-go-v2/service/kafka v1.38.16/go.mod h1:HLgqO1+m+EYx7ldJjwYSMwOHV1+RPsIVBtpsv3MM/zI=
+github.com/aws/aws-sdk-go-v2/service/kms v1.37.18 h1:pi9M/9n1PLayBXjia7LfwgXwcpFdFO7Q2cqKOZa1ZmM=
+github.com/aws/aws-sdk-go-v2/service/kms v1.37.18/go.mod h1:vZXvmzfhdsPj/axc8+qk/2fSCP4hGyaZ1MAduWEHAxM=
+github.com/aws/aws-sdk-go-v2/service/lambda v1.69.12 h1:9L6sXmGtRvBFzgf14G4EwlGrFkhltigC3fbGIqZ5g+c=
+github.com/aws/aws-sdk-go-v2/service/lambda v1.69.12/go.mod h1:LUkuzqAgjdxkq+UiBnOs/z5LOGoFyEkeVKxeVXB+Rt8=
+github.com/aws/aws-sdk-go-v2/service/rds v1.93.12 h1:6vjEcP08FsczK2J55oxnbYC4UZ4UBDCBW+rBFtK0H/c=
+github.com/aws/aws-sdk-go-v2/service/rds v1.93.12/go.mod h1:oOqXBxRebL78/MgTi1EoBer+a3Myg0Wr2nO1qG881kM=
+github.com/aws/aws-sdk-go-v2/service/route53 v1.48.7 h1:oPqYaMfI6XYKXD5jlJ4JHipkKcA2Ska3JLLz11ukf0E=
+github.com/aws/aws-sdk-go-v2/service/route53 v1.48.7/go.mod h1:DFFR1FKSHaBJZF2eMW+6PsSg97pldSoHQnRx4tH2Mek=
+github.com/aws/aws-sdk-go-v2/service/s3 v1.76.1 h1:d4ZG8mELlLeUWFBMCqPtRfEP3J6aQgg/KTC9jLSlkMs=
+github.com/aws/aws-sdk-go-v2/service/s3 v1.76.1/go.mod h1:uZoEIR6PzGOZEjgAZE4hfYfsqK2zOHhq68JLKEvvXj4=
+github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.18 h1:U/gg5eOAPx9vzip9A6cQ2GkIAPBthHMaKDfZ/WWEuj0=
+github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.18/go.mod h1:ul2OTb6zT/dpZX/2bxKVwa6eIDBBlPNuau9uZuIoRAI=
+github.com/aws/aws-sdk-go-v2/service/sesv2 v1.41.5 h1:4Axfv4Ytz7gMiAigzbS3NXWcXRFFHBZB8vFcG7oYRsk=
+github.com/aws/aws-sdk-go-v2/service/sesv2 v1.41.5/go.mod h1:taGBqRDPFzem7/4UB0O8Sua9i1gRXg9fEWgUMKXeunA=
+github.com/aws/aws-sdk-go-v2/service/sns v1.33.19 h1:ghgWtf6FnkD6YqDUq65Zg5lzQ92xADHBoJdWUyChiFw=
+github.com/aws/aws-sdk-go-v2/service/sns v1.33.19/go.mod h1:/TQAkYgLlLoH1/2Y9qgaE460iPWhdq67emlW/ue42U8=
+github.com/aws/aws-sdk-go-v2/service/sqs v1.37.14 h1:KSVbQW2umLp7i4Lo6mvBUz5PqV+Ze/IL6LCTasxQWEk=
+github.com/aws/aws-sdk-go-v2/service/sqs v1.37.14/go.mod h1:jiaEkIw2Bb6IsoY9PDAZqVXJjNaKSxQGGj10CiloDWU=
+github.com/aws/aws-sdk-go-v2/service/ssm v1.56.12 h1:EKEY56SQTqEsOuh68B8YVqmsLJ1nuwUGYyKImyo+0ug=
+github.com/aws/aws-sdk-go-v2/service/ssm v1.56.12/go.mod h1:I/j1db6MPxBp7vcVrRAh+u+vERu79MWoyhoSjRaDl9E=
+github.com/aws/aws-sdk-go-v2/service/sso v1.24.15 h1:/eE3DogBjYlvlbhd2ssWyeuovWunHLxfgw3s/OJa4GQ=
+github.com/aws/aws-sdk-go-v2/service/sso v1.24.15/go.mod h1:2PCJYpi7EKeA5SkStAmZlF6fi0uUABuhtF8ILHjGc3Y=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.14 h1:M/zwXiL2iXUrHputuXgmO94TVNmcenPHxgLXLutodKE=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.14/go.mod h1:RVwIw3y/IqxC2YEXSIkAzRDdEU1iRabDPaYjpGCbCGQ=
+github.com/aws/aws-sdk-go-v2/service/sts v1.33.14 h1:TzeR06UCMUq+KA3bDkujxK1GVGy+G8qQN/QVYzGLkQE=
+github.com/aws/aws-sdk-go-v2/service/sts v1.33.14/go.mod h1:dspXf/oYWGWo6DEvj98wpaTeqt5+DMidZD0A9BYTizc=
+github.com/aws/aws-sdk-go-v2/service/wafv2 v1.58.0 h1:vJfgEyoSRn0E7Z3SwnXgA04xbp6/MiTFOE5Ypw/lbXw=
+github.com/aws/aws-sdk-go-v2/service/wafv2 v1.58.0/go.mod h1:Zai6/lANvFn0uX9OKqPGy4C9a7TIcbnlzzM1EHTd3kE=
+github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ=
+github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
+github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
+github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
+github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
+github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=
+github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4=
+github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
+github.com/boombuler/barcode v1.0.2 h1:79yrbttoZrLGkL/oOI8hBrUKucwOL0oOjUgEguGMcJ4=
+github.com/boombuler/barcode v1.0.2/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
+github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
+github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/charmbracelet/lipgloss v0.10.0 h1:KWeXFSexGcfahHX+54URiZGkBFazf70JNMtwg/AFW3s=
+github.com/charmbracelet/lipgloss v0.10.0/go.mod h1:Wig9DSfvANsxqkRsqj6x87irdy123SR4dOXlKa91ciE=
+github.com/charmbracelet/log v0.4.0 h1:G9bQAcx8rWA2T3pWvx7YtPTPwgqpk7D68BX21IRW8ZM=
+github.com/charmbracelet/log v0.4.0/go.mod h1:63bXt/djrizTec0l11H20t8FDSvA4CRZJ1KH22MdptM=
+github.com/cloudposse/test-helpers v0.21.1-0.20250317131037-7efa78ac9b05 h1:UqFp98DP9KIeXt+zF9EyGR0n7DIgA2QA1kZAi4HC8LM=
+github.com/cloudposse/test-helpers v0.21.1-0.20250317131037-7efa78ac9b05/go.mod h1:tNTOP4YcKyhs9+xm/FxLQiVyacK3EZ/KkWJLOpCqA18=
+github.com/cloudposse/test-helpers v0.22.0 h1:oxCysvwKpBA8H6IvcWQxId7Cx0D6NRJ2Dw+7vsTJW+Q=
+github.com/cloudposse/test-helpers v0.22.0/go.mod h1:UmmPgiLL44aJe9E98xXFn+y5aybGsU4l6pJ3iQZvmJ0=
+github.com/cloudposse/test-helpers v0.22.1-0.20250326115004-9e5a8774b3c1 h1:Pp00IP/ERAO4+Awj43LVNiNXuS+K0ljhe7W501352FM=
+github.com/cloudposse/test-helpers v0.22.1-0.20250326115004-9e5a8774b3c1/go.mod h1:UmmPgiLL44aJe9E98xXFn+y5aybGsU4l6pJ3iQZvmJ0=
+github.com/cloudposse/test-helpers v0.23.0 h1:fkwqzBa66Dv4jsw0bsMHO7OfTknuHA8VuuXZ61Vh6zg=
+github.com/cloudposse/test-helpers v0.23.0/go.mod h1:UmmPgiLL44aJe9E98xXFn+y5aybGsU4l6pJ3iQZvmJ0=
+github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=
+github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU=
+github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
+github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
+github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
+github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
+github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
+github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
+github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
+github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk=
+github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
+github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
+github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
+github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
+github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
+github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
+github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
+github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
+github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
+github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
+github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
+github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
+github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
+github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
+github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M=
+github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8=
+github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E=
+github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0=
+github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
+github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
+github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
+github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
+github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
+github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/gruntwork-io/go-commons v0.17.2 h1:14dsCJ7M5Vv2X3BIPKeG9Kdy6vTMGhM8L4WZazxfTuY=
+github.com/gruntwork-io/go-commons v0.17.2/go.mod h1:zs7Q2AbUKuTarBPy19CIxJVUX/rBamfW8IwuWKniWkE=
+github.com/gruntwork-io/terratest v0.48.2 h1:+VwfODchq8jxZZWD+s8gBlhD1z6/C4bFLNrhpm9ONrs=
+github.com/gruntwork-io/terratest v0.48.2/go.mod h1:Y5ETyD4ZQ2MZhasPno272fWuCpKwvTPYDi8Y0tIMqTE=
+github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
+github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
+github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
+github.com/hashicorp/go-getter/v2 v2.2.3 h1:6CVzhT0KJQHqd9b0pK3xSP0CM/Cv+bVhk+jcaRJ2pGk=
+github.com/hashicorp/go-getter/v2 v2.2.3/go.mod h1:hp5Yy0GMQvwWVUmwLs3ygivz1JSLI323hdIE9J9m7TY=
+github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
+github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
+github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo=
+github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I=
+github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
+github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
+github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/hashicorp/hcl/v2 v2.22.0 h1:hkZ3nCtqeJsDhPRFz5EA9iwcG1hNWGePOTw6oyul12M=
+github.com/hashicorp/hcl/v2 v2.22.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA=
+github.com/hashicorp/terraform-json v0.23.0 h1:sniCkExU4iKtTADReHzACkk8fnpQXrdD2xoR+lppBkI=
+github.com/hashicorp/terraform-json v0.23.0/go.mod h1:MHdXbBAbSg0GvzuWazEGKAn/cyNfIB7mN6y7KJN6y2c=
+github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
+github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
+github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
+github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
+github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI=
+github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
+github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
+github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
+github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8=
+github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
+github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
+github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
+github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
+github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
+github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
+github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
+github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
+github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
+github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
+github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
+github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM=
+github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
+github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
+github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
+github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
+github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/mattn/go-zglob v0.0.6 h1:mP8RnmCgho4oaUYDIDn6GNxYk+qJGUs8fJLn+twYj2A=
+github.com/mattn/go-zglob v0.0.6/go.mod h1:MxxjyoXXnMxfIpxTK2GAkw1w8glPsQILx3N5wrKakiY=
+github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
+github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
+github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
+github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
+github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
+github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
+github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
+github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
+github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
+github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
+github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
+github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
+github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
+github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
+github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
+github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg=
+github.com/pquerna/otp v1.4.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
+github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
+github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
+github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
+github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
+github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ=
+github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s=
+github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
+github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
+github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
+github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
+github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
+github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
+github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo=
+github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k=
+github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
+github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
+github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
+github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
+github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
+github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
+github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
+github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
+github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
+github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
+github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
+github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
+github.com/tmccombs/hcl2json v0.6.4 h1:/FWnzS9JCuyZ4MNwrG4vMrFrzRgsWEOVi+1AyYUVLGw=
+github.com/tmccombs/hcl2json v0.6.4/go.mod h1:+ppKlIW3H5nsAsZddXPy2iMyvld3SHxyjswOZhavRDk=
+github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
+github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
+github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
+github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
+github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
+github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
+github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
+github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ=
+github.com/zclconf/go-cty v1.15.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
+github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo=
+github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM=
+go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
+go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
+golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
+golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY=
+golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI=
+golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
+golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
+golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
+golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
+golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
+golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
+golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
+golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
+golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
+golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
+golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE=
+golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
+google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
+gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
+gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
+gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
+gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
+gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+k8s.io/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE=
+k8s.io/api v0.32.0/go.mod h1:4LEwHZEf6Q/cG96F3dqR965sYOfmPM7rq81BLgsE0p0=
+k8s.io/api v0.32.3 h1:Hw7KqxRusq+6QSplE3NYG4MBxZw1BZnq4aP4cJVINls=
+k8s.io/api v0.32.3/go.mod h1:2wEDTXADtm/HA7CCMD8D8bK4yuBUptzaRhYcYEEYA3k=
+k8s.io/apiextensions-apiserver v0.32.3 h1:4D8vy+9GWerlErCwVIbcQjsWunF9SUGNu7O7hiQTyPY=
+k8s.io/apiextensions-apiserver v0.32.3/go.mod h1:8YwcvVRMVzw0r1Stc7XfGAzB/SIVLunqApySV5V7Dss=
+k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg=
+k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
+k8s.io/apimachinery v0.32.3 h1:JmDuDarhDmA/Li7j3aPrwhpNBA94Nvk5zLeOge9HH1U=
+k8s.io/apimachinery v0.32.3/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
+k8s.io/client-go v0.32.0 h1:DimtMcnN/JIKZcrSrstiwvvZvLjG0aSxy8PxN8IChp8=
+k8s.io/client-go v0.32.0/go.mod h1:boDWvdM1Drk4NJj/VddSLnx59X3OPgwrOo0vGbtq9+8=
+k8s.io/client-go v0.32.3 h1:RKPVltzopkSgHS7aS98QdscAgtgah/+zmpAogooIqVU=
+k8s.io/client-go v0.32.3/go.mod h1:3v0+3k4IcT9bXTc4V2rt+d2ZPPG700Xy6Oi0Gdl2PaY=
+k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
+k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
+k8s.io/kube-aggregator v0.32.3 h1:j+lUE4V1sMANYv/wCdU2E8SgnSLJksaJ+6bNnoV6Pfs=
+k8s.io/kube-aggregator v0.32.3/go.mod h1:aAl5az9Rlq4sPPSf8/ckpDGSYit75g4g1dp6rKInXZM=
+k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y=
+k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4=
+k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
+k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+sigs.k8s.io/aws-iam-authenticator v0.6.30 h1:TtN7AXLH/ugoM8Nfb5ngSu57PDUh5GVpM19eer4mMYg=
+sigs.k8s.io/aws-iam-authenticator v0.6.30/go.mod h1:zcSm4YLd6eXEIjhX9TegLSxoBrbEaAJH/Of49GECjmk=
+sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8=
+sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
+sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA=
+sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4=
+sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
+sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
diff --git a/test/run.sh b/test/run.sh
deleted file mode 100755
index 15e077f..0000000
--- a/test/run.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-
-echo "hello tests"


Reviews:
user: login: coderabbitai[bot]
body: **Actionable comments posted: 2**

<details>
<summary>🧹 Nitpick comments (14)</summary><blockquote>

<details>
<summary>test/.gitignore (1)</summary><blockquote>

`1-5`: **.gitignore File Setup**  
The file includes essential ignore patterns (such as `state/`, `.cache`, `test/test-suite.json`, `.atmos`, and `test_suite.yaml`) to keep ephemeral and test-generated files out of version control. This is well aligned with the goal of maintaining a clean repository.  
  
 Consider reviewing whether additional file patterns (e.g., logs or other temporary files) should be ignored based on future test outputs.

</blockquote></details>
<details>
<summary>test/fixtures/stacks/catalog/vpc.yaml (1)</summary><blockquote>

`1-19`: **VPC YAML Configuration File**  
This new YAML file clearly defines the `vpc` component with relevant metadata and configuration variables. The structure is clean and the variable names are self-explanatory.  
  
 A trailing newline at the end of the file would improve consistency.

</blockquote></details>
<details>
<summary>test/fixtures/vendor.yaml (1)</summary><blockquote>

`1-55`: **AtmosVendorConfig File**  
The new vendor configuration file defines an `AtmosVendorConfig` for managing vendor components. Each component entry includes clear metadata, source information, specific version tags, and the corresponding target directories and path filters. This structured approach will aid in maintaining consistent vendor dependencies across Terraform components.  
  
 It may be beneficial to periodically verify that the specified version tags (e.g., `v1.535.2` for the Karpenter controller) remain up-to-date with upstream releases.

</blockquote></details>
<details>
<summary>test/fixtures/stacks/catalog/account-map.yaml (1)</summary><blockquote>

`23-47`: **Review of remote_state_backend block**  
The static backend configuration is comprehensive and clean. As a minor nitpick, consider ensuring that the file ends with a trailing newline per YAML lint recommendations.

</blockquote></details>
<details>
<summary>test/fixtures/stacks/catalog/usecase/basic.yaml (2)</summary><blockquote>

`91-168`: **Detailed list of acceptable instance families**  
The extensive list of instance families is impressive. To maintain this list over time, consider automating updates or periodic reviews to catch new instance types or deprecations.

---

`169-187`: **Extra node pool example and file termination**  
The commented-out example for an extra node pool is a helpful reference for future extensions. Please add a newline at the end of the file to adhere to YAML linting standards.

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 YAMLlint (1.35.1)</summary>

[error] 187-187: no new line character at the end of file

(new-line-at-end-of-file)

</details>

</details>

</blockquote></details>
<details>
<summary>test/go.mod (1)</summary><blockquote>

`19-184`: **Extended Dependency Requirements.**  
The subsequent “require” block includes a comprehensive list of dependencies. While this ensures full coverage, periodically review these indirect dependencies to remove any unneeded packages and reduce future maintenance overhead.

</blockquote></details>
<details>
<summary>test/fixtures/stacks/catalog/usecase/disabled.yaml (1)</summary><blockquote>

`1-100`: **New Disabled Karpenter Node Pool Configuration.**  
This YAML file is well structured, clearly indicating a disabled state through `enabled: false` and overriding role ARN usage with `kube_exec_auth_role_arn_enabled: false`. One minor nitpick: the value for “nodes” in the disruption budget (line 22) is specified as a string ("0"); if a numeric 0 is intended, consider removing the quotes to ensure proper type handling.

</blockquote></details>
<details>
<summary>test/fixtures/stacks/catalog/eks-cluster.yaml (1)</summary><blockquote>

`1-94`: **Extensive EKS Cluster Configuration and Formatting Note.**  
This new YAML configuration comprehensively covers cluster metadata, node group parameters, access settings, Fargate profiles, legacy compatibility, and addon versions. All settings appear clear and well documented.  
Please add a newline at the end of the file to conform with standard YAML file formatting and avoid linting errors.

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 YAMLlint (1.35.1)</summary>

[error] 94-94: no new line character at the end of file

(new-line-at-end-of-file)

</details>

</details>

</blockquote></details>
<details>
<summary>test/component_test.go (5)</summary><blockquote>

`13-13`: **Fix spacing inconsistency.**

There's an inconsistency in the indentation where spaces are used instead of tabs. This should be aligned with the rest of the file's formatting.

```diff
-    corev1 "k8s.io/api/core/v1"
+	corev1 "k8s.io/api/core/v1"
```

---

`39-39`: **Remove redundant empty line.**

There's an extra empty line here that should be removed to maintain consistent spacing.

---

`45-45`: **Fix typo in variable name.**

There's a typo in the variable name `clusrerId`, which should be `clusterId`.

```diff
-	clusrerId := atmos.Output(s.T(), clusterOptions, "eks_cluster_id")
+	clusterId := atmos.Output(s.T(), clusterOptions, "eks_cluster_id")
```

Make sure to update all references to this variable as well:
```diff
-	cluster := awsHelper.GetEksCluster(s.T(), context.Background(), awsRegion, clusrerId)
+	cluster := awsHelper.GetEksCluster(s.T(), context.Background(), awsRegion, clusterId)
```

---

`68-68`: **Improve assertion for list length.**

When checking a list's length, it's recommended to use `assert.Len()` instead of `assert.Equal()` for the length. This provides clearer error messages when tests fail.

```diff
-	assert.Equal(s.T(), len(ec2NodeClassesList.Items), 1)
+	assert.Len(s.T(), ec2NodeClassesList.Items, 1)
```

```diff
-	assert.Equal(s.T(), len(nodePoolsList.Items), 1)
+	assert.Len(s.T(), nodePoolsList.Items, 1)
```


Also applies to: 91-91

---

`81-81`: **Remove redundant empty line.**

There's an extra empty line here that should be removed to maintain consistent spacing.

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between d8b1576f8e63f85101831212d3aafc6d64618159 and be9447dd6bac778705e7b48c8218c6bbbfd4d315.

</details>

<details>
<summary>⛔ Files ignored due to path filters (1)</summary>

* `test/go.sum` is excluded by `!**/*.sum`

</details>

<details>
<summary>📒 Files selected for processing (17)</summary>

* `src/provider-helm.tf` (1 hunks)
* `src/providers.tf` (1 hunks)
* `src/remote-state.tf` (2 hunks)
* `test/.gitignore` (1 hunks)
* `test/component_test.go` (1 hunks)
* `test/fixtures/atmos.yaml` (1 hunks)
* `test/fixtures/stacks/catalog/account-map.yaml` (1 hunks)
* `test/fixtures/stacks/catalog/eks-cluster.yaml` (1 hunks)
* `test/fixtures/stacks/catalog/eks-karpenter-controller.yaml` (1 hunks)
* `test/fixtures/stacks/catalog/usecase/basic.yaml` (1 hunks)
* `test/fixtures/stacks/catalog/usecase/disabled.yaml` (1 hunks)
* `test/fixtures/stacks/catalog/vpc.yaml` (1 hunks)
* `test/fixtures/stacks/orgs/default/test/_defaults.yaml` (1 hunks)
* `test/fixtures/stacks/orgs/default/test/tests.yaml` (1 hunks)
* `test/fixtures/vendor.yaml` (1 hunks)
* `test/go.mod` (1 hunks)
* `test/run.sh` (0 hunks)

</details>

<details>
<summary>💤 Files with no reviewable changes (1)</summary>

* test/run.sh

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🪛 YAMLlint (1.35.1)</summary>

<details>
<summary>test/fixtures/stacks/catalog/usecase/basic.yaml</summary>

[error] 187-187: no new line character at the end of file

(new-line-at-end-of-file)

</details>
<details>
<summary>test/fixtures/stacks/catalog/eks-cluster.yaml</summary>

[error] 94-94: no new line character at the end of file

(new-line-at-end-of-file)

</details>

</details>

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (3)</summary>

* GitHub Check: Mergify Merge Protections
* GitHub Check: Mergify Merge Protections
* GitHub Check: Summary

</details>

<details>
<summary>🔇 Additional comments (24)</summary><blockquote>

<details>
<summary>src/remote-state.tf (2)</summary>

`1-4`: **EKS Remote-State Module Version Update**  
The `version` for the `eks` module has been updated to "1.8.0". Ensure that this version upgrade is compatible with the new configuration files and any related integration logic in the repository.  
  
 Please verify that no breaking changes exist between versions 1.5.0 and 1.8.0 that might affect component behavior.

---

`17-20`: **VPC Remote-State Module Version Update**  
Similarly, the `version` for the `vpc` module is updated to "1.8.0". Verify that all dependencies and state management settings are properly aligned with the requirements of this new version.  
  
 Confirm that any integration tests covering remote state interactions are updated accordingly.

</details>
<details>
<summary>test/fixtures/stacks/orgs/default/test/tests.yaml (1)</summary>

`1-7`: **Test Imports Configuration File**  
The file successfully aggregates imports of multiple configuration components (including defaults, VPC, EKS cluster, Karpenter controller, and both basic and disabled use cases). This centralization should simplify running comprehensive component tests.

</details>
<details>
<summary>src/providers.tf (1)</summary>

`6-11`: **Clarification on the dynamic assume_role block**  
The updated block now uses `compact([module.iam_roles.terraform_role_arn])` to ensure that the `assume_role` block is only instantiated when a non-empty ARN is provided. This is a neat improvement over conditional list construction. Please verify that the expected behavior holds in all environments (i.e. that `module.iam_roles.terraform_role_arn` reliably returns either a valid ARN or an empty value).

</details>
<details>
<summary>test/fixtures/stacks/catalog/account-map.yaml (1)</summary>

`1-22`: **Well-structured account map configuration**  
The metadata and variable sections are clearly defined. The commented-out remote state backend details provide useful context for internal use. Ensure that the `TEST_ACCOUNT_ID` environment variable is supplied when running tests.

</details>
<details>
<summary>test/fixtures/stacks/orgs/default/test/_defaults.yaml (2)</summary>

`1-10`: **Clear default backend configuration**  
The use of templated paths with `{{ getenv "COMPONENT_HELPER_STATE_DIR" | default "../../../state" }}` is clear and maintains consistency across state file locations. Just double-check that the expected environment overrides are correctly propagated in your test environment.

---

`36-66`: **Solid integration of account-map settings**  
Defining the `account-map` within the components block aids in centralizing configuration. Ensure that any updates to the account map are reflected consistently across all environments where this configuration is imported.

</details>
<details>
<summary>test/fixtures/stacks/catalog/eks-karpenter-controller.yaml (4)</summary>

`1-8`: **Comprehensive Karpenter controller settings (Part 1)**  
The initial section of the configuration (metadata and basic enabling flags) is clear and concise. The boolean flags (e.g., `enabled`, `kube_exec_auth_role_arn_enabled`) are appropriately set.

---

`9-16`: **Helm chart and version parameters**  
Defining the `chart_repository`, `chart`, and `chart_version` at this stage makes the update process straightforward. Verify that the specified `chart_version` ("1.0.0") is correct or update it as needed.

---

`17-27`: **Resource constraints and operational flags**  
The resource limits, requests, and operational toggles (like `cleanup_on_fail`, `atomic`, `wait`, and `rbac_enabled`) are well configured to ensure stable controller behavior.

---

`28-44`: **Logging and replica configuration**  
The logging settings and replica count (set to 2) are appropriately defined, meeting standard high-availability and troubleshooting requirements.

</details>
<details>
<summary>test/fixtures/stacks/catalog/usecase/basic.yaml (4)</summary>

`1-9`: **Basic node pool component definition is clear**  
The initial metadata and variable settings (such as enabling the node pool and setting a component name) are straightforward and well organized.

---

`10-18`: **Node pool labeling and subnet configuration**  
The labels, annotations, and the `private_subnets_enabled` flag are clearly set, aligning with standard practices for defining Kubernetes node pools.

---

`25-30`: **AMI and block device mappings configuration**  
The specification for `ami_family` and the block device mappings is precise. This should ensure that the nodes provisioned by Karpenter meet the expected standards.

---

`43-68`: **Node provisioning requirements are comprehensive**  
The requirements block covers encryption support and CPU constraints effectively. The clear delineation of acceptable values helps in filtering the proper instance types.

</details>
<details>
<summary>test/go.mod (3)</summary>

`1-6`: **Module Declaration and Go Version Setup.**  
The module is declared as “test” and specifies the Go version (1.23.4) as well as an explicit toolchain (go1.23.7), which is great for ensuring consistent builds.

---

`7-15`: **Dependency Block Clarity.**  
The primary “require” block lists both direct and indirect dependencies cleanly. Ensure that all pinned versions (e.g., for terratest and testify) match the intended compatibility for your tests.

---

`17-18`: **Replace Directive Verification.**  
The replace directive line (mapping `github.com/rebuy-de/aws-nuke/v2/mocks` to `github.com/ekristen/aws-nuke/v3/ v3.29.0`) is correctly formatted. Please verify that this mapping meets your module’s runtime expectations.

</details>
<details>
<summary>src/provider-helm.tf (1)</summary>

`136-138`: **Inline Role ARN Resolution.**  
The change consolidates the logic by directly inlining the role ARN determination using the `coalesce` function. This improves clarity by removing the redundant local variable. Be sure that `module.iam_roles.terraform_role_arn` reliably provides a valid ARN when `var.kube_exec_auth_role_arn` is empty.

</details>
<details>
<summary>test/fixtures/atmos.yaml (1)</summary>

`1-78`: **Comprehensive Atmos CLI Configuration.**  
The new `atmos.yaml` file effectively outlines the loading order and configuration priorities for CLI settings, including base paths, components, stacks, workflows, logs, and template settings. The detailed inline comments and ENV var mappings make this file easy to understand and maintain.

</details>
<details>
<summary>test/component_test.go (4)</summary>

`104-104`: **Great addition of drift testing.**

The drift test verifies that applying the component multiple times with the same inputs doesn't result in any changes, which is essential for idempotent infrastructure as code. This aligns perfectly with the PR objective of ensuring the component doesn't drift.

---

`107-111`: **Well-structured test for the enabled flag.**

This test checks that when the component is disabled, no resources are created. This is a critical test to ensure that the component behaves as expected when turned off, aligning with the PR objective of testing the `enabled` parameter.

---

`119-125`: **Well-organized test dependencies.**

The test clearly defines its dependencies on other components (vpc, eks/cluster, eks/karpenter-controller) which ensures proper test setup and teardown. This is crucial for reliable integration testing.

---

`24-105`: **Comprehensive test coverage for the basic functionality.**

The `TestBasic` method implements a thorough test that:
1. Deploys the component
2. Verifies the outputs
3. Checks the Kubernetes resources created
4. Validates resource conditions
5. Tests for drift

This approach ensures that the component functions correctly and maintains consistency, which directly addresses the PR objectives of validating fundamental features and testing for component drifting.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-04T22:45:24Z

Review comments:
diff_hunk: @@ -0,0 +1,187 @@
+components:
+  terraform:
+    eks/karpenter-node-pool/basic:
+      metadata:
+        component: eks/karpenter-node-pool
+      vars:
+        enabled: true
+        kube_exec_auth_role_arn_enabled: false
+        name: "karpenter-node-pool"
+        # https://karpenter.sh/v0.36.0/docs/concepts/nodepools/
+        node_pools:
+          default:
+            labels:
+              test: test
+            annotations:
+              test: test
+            # Whether to place EC2 instances launched by Karpenter into VPC private subnets. Set it to `false` to use public subnets
+            private_subnets_enabled: true
+            disruption:
+              max_instance_lifetime: "1h" # 14 days
+            # Karpenter provisioner total CPU limit for all pods running on the EC2 instances launched by Karpenter
+            total_cpu_limit: "100"
+            # Karpenter provisioner total memory limit for all pods running on the EC2 instances launched by Karpenter
+            total_memory_limit: "1000Gi"
path: test/fixtures/stacks/catalog/usecase/basic.yaml
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**Disruption settings and resource limits – Verify max_instance_lifetime**  
The disruption block defines a `max_instance_lifetime` of `"1h"` while the inline comment indicates "14 days." Please verify the intended duration. If 14 days is correct, update the value accordingly.  
  

Below is a suggested diff if 14 days is the intended lifetime:
```diff
-            disruption:
-              max_instance_lifetime: "1h" # 14 days
+            disruption:
+              max_instance_lifetime: "14d" # 14 days
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
            disruption:
              max_instance_lifetime: "14d" # 14 days
            # Karpenter provisioner total CPU limit for all pods running on the EC2 instances launched by Karpenter
            total_cpu_limit: "100"
            # Karpenter provisioner total memory limit for all pods running on the EC2 instances launched by Karpenter
            total_memory_limit: "1000Gi"
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-04-04T22:45:23Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,125 @@
+package test
+
+import (
+	"context"
+	"fmt"
+	"testing"
+	helper "github.com/cloudposse/test-helpers/pkg/atmos/component-helper"
+	awsHelper "github.com/cloudposse/test-helpers/pkg/aws"
+	"github.com/cloudposse/test-helpers/pkg/atmos"
+	"github.com/stretchr/testify/assert"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+    corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/runtime/schema"
+	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+
+	"k8s.io/client-go/dynamic"
+)
+
+type ComponentSuite struct {
+	helper.TestSuite
+}
+
+func (s *ComponentSuite) TestBasic() {
+	const component = "eks/karpenter-node-pool/basic"
+	const stack = "default-test"
+	const awsRegion = "us-east-2"
+
+	inputs := map[string]interface{}{}
+
+	defer s.DestroyAtmosComponent(s.T(), component, stack, &inputs)
+	options, _ := s.DeployAtmosComponent(s.T(), component, stack, &inputs)
+	assert.NotNil(s.T(), options)
+
+	var nodePools map[string]interface{}
+	atmos.OutputStruct(s.T(), options, "node_pools", &nodePools)
+	assert.NotEmpty(s.T(), nodePools)
+
+
+	var ec2NodeClasses map[string]interface{}
+	atmos.OutputStruct(s.T(), options, "ec2_node_classes", &ec2NodeClasses)
+	assert.NotEmpty(s.T(), nodePools)
path: test/component_test.go
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**Fix assertion variable in test.**

This assertion is checking `nodePools` again instead of `ec2NodeClasses`, which appears to be a copy-paste error.

```diff
-	assert.NotEmpty(s.T(), nodePools)
+	assert.NotEmpty(s.T(), ec2NodeClasses)
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
	assert.NotEmpty(s.T(), ec2NodeClasses)
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-04-04T22:45:23Z
author_association: CONTRIBUTOR

PR comments:
user: login: coderabbitai[bot]
created_at: 2025-04-04T22:36:57Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- walkthrough_start -->

## Walkthrough
This pull request consolidates and streamlines configurations across multiple files. In Terraform files, the redundant local variable for the role ARN is removed and the logic is integrated directly. The AWS provider section is updated to use the `compact` function for role handling. Remote-state module versions are updated. In the test directory, several new configuration files and a comprehensive test suite have been introduced, along with a new Go module file, while a simple shell script has been removed.

## Changes

| File(s) | Change Summary |
|---------|----------------|
| `src/provider-helm.tf` | Removed the `kube_exec_auth_role_arn` local variable; integrated the role ARN determination directly into the `exec_role` assignment. |
| `src/providers.tf` | Updated the `for_each` clause in the dynamic `assume_role` block to use the `compact` function for a more concise role handling. |
| `src/remote-state.tf` | Upgraded module versions for `eks` and `vpc` from `1.5.0` to `1.8.0`. |
| `test/.gitignore` | Added a new file to specify ignore patterns for test-related files and directories. |
| `test/component_test.go` | Introduced a new `ComponentSuite` with tests (`TestBasic` and `TestEnabledFlag`) for component deployment and configuration validation. |
| `test/fixtures/atmos.yaml` | Created a new CLI configuration file defining loading order and settings for components, stacks, and workflows. |
| `test/fixtures/stacks/catalog/*.yaml` | Added several YAML files for configuring account-map, EKS cluster, Karpenter controller, node pool use cases (basic and disabled), and VPC components. |
| `test/fixtures/stacks/orgs/default/test/*.yaml` | Introduced new organization configuration files including default settings and test import definitions. |
| `test/fixtures/vendor.yaml` | Added a new `AtmosVendorConfig` file for managing vendor components and their sources. |
| `test/go.mod` | Introduced a new Go module file for the `test` module with specified Go version, toolchain, and dependencies. |
| `test/run.sh` | Removed the obsolete shell script. |

## Sequence Diagram(s)
```mermaid
sequenceDiagram
    participant TR as TestRunner
    participant CS as ComponentSuite
    participant Deployer as AtmosComponent Deployer
    participant AWS as AWS Helper
    participant K8s as Kubernetes API

    TR->>CS: Run TestBasic()
    CS->>CS: SetupSuite() 
    CS->>Deployer: DeployAtmosComponent()
    Deployer-->>CS: Deployment Options
    CS->>AWS: GetEksCluster(clusterID)
    AWS-->>CS: Return Cluster Details
    CS->>K8s: List CRDs (EC2NodeClass & NodePools)
    K8s-->>CS: Return Resource Data
    CS->>TR: Assertions & Cleanup
```

## Poem
> Oh, I’m a bunny in a code-filled glen,  
> Hopping through changes again and again.  
> The Terraform fields are trimmed so neat,  
> YAML blossoms and tests complete.  
> With each commit I wiggle with delight,  
> Celebrating updates from morning till night!  
> 🐰✨

<!-- walkthrough_end -->
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details>
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=cloudposse-terraform-components/aws-eks-karpenter-node-pool&utm_content=16):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai generate unit testing code for this file.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and generate unit testing code.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai plan` to trigger planning for file edits and PR creation.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: CONTRIBUTOR
user: login: mergify[bot]
created_at: 2025-04-04T22:37:26Z
body: # Merge Protections

Your pull request matches the following merge protections and will not be merged until they are valid.

## 🟢 Require terratest

<details><summary>Wonderful, this rule succeeded.</summary>

This rule require terratest status
- [X] `check-success = test/terratest`

</details>
author_association: NONE
user: login: goruha
created_at: 2025-04-05T06:49:30Z
body: /terratest 
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-04-05T07:29:03Z
body: 
  <!-- release-pr-comment:190587856 -->
  These changes were released in [v1.535.1](https://github.com/cloudposse-terraform-components/aws-eks-karpenter-node-pool/releases/tag/v1.535.1).
  
author_association: CONTRIBUTOR