diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 85adacb..6dcd874 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,7 +26,7 @@ repos: args: [--markdown-linebreak-ext=md] exclude: CHANGELOG.md - - id: check-yaml + # - id: check-yaml - id: check-merge-conflict - id: check-executables-have-shebangs @@ -50,7 +50,7 @@ repos: # Terraform Hooks - repo: https://github.com/antonbabenko/pre-commit-terraform - rev: v1.96.1 # Get the latest from: https://github.com/antonbabenko/pre-commit-terraform/releases + rev: v1.97.3 # Get the latest from: https://github.com/antonbabenko/pre-commit-terraform/releases hooks: - id: terraform_fmt args: diff --git a/README.md b/README.md index fd79403..09d0981 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,6 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the | [terraform](#requirement\_terraform) | >= 0.13 | | [aws](#requirement\_aws) | >= 5.14.0 | | [helm](#requirement\_helm) | >= 2.11.0 | -| [kubernetes](#requirement\_kubernetes) | >= 2.23.0 | ## Providers @@ -28,7 +27,6 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the |------|---------| | [aws](#provider\_aws) | 5.84.0 | | [helm](#provider\_helm) | 2.17.0 | -| [kubernetes](#provider\_kubernetes) | 2.35.1 | ## Modules @@ -41,10 +39,9 @@ The module deploys Karpenter needed AWS resources, namely in IAM. It copies the | Name | Type | |------|------| -| [aws_iam_instance_profile.karpenter_node_instance_profile](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource | +| [aws_iam_instance_profile.karpenter_node](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource | | [helm_release.karpenter](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | -| [kubernetes_manifest.karpenter_node_class](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | -| [kubernetes_manifest.karpenter_node_pool](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) | resource | +| [helm_release.nodepool_resources](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource | | [aws_arn.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/arn) | data source | | [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | | [aws_ecr_image.karpenter_image](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ecr_image) | data source | diff --git a/karpenter-resources/Chart.yaml b/karpenter-resources/Chart.yaml new file mode 100644 index 0000000..cf46148 --- /dev/null +++ b/karpenter-resources/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: karpenter-resources +description: Helm chart for configuring custom resources for Karpenter on the cluster +version: 0.0.2 +appVersion: 0.0.2 +icon: https://repository-images.githubusercontent.com/278480393/dab059c8-caa1-4b55-aaa7-3d30e47a5616 diff --git a/karpenter-resources/README.md b/karpenter-resources/README.md new file mode 100644 index 0000000..e95f582 --- /dev/null +++ b/karpenter-resources/README.md @@ -0,0 +1,71 @@ +# Karpenter Resources Helm Chart + +## Overview + +This Helm chart is an abstraction layer designed for deploying various configurations of Karpenter nodes in a Kubernetes cluster managed by EKS. It integrates seamlessly with Terraform, allowing users to define different node pools and settings for their Kubernetes cluster. + +## Prerequisites + +- Helm 3.x or later installed +- Terraform installed +- Access to an AWS EKS cluster + +## Configuration + +The chart is configured to be used with Terraform. Here is an example of how you might define Helm releases for different Karpenter configurations in your Terraform files using EKS Blueprints add-ons: + +```hcl +module "eks_blueprints_addons" { + # ... other configurations ... + helm_releases = { + karpenter-resources-default = { + name = "default" + description = "A Helm chart for default node pool" + chart = "${path.module}/helm-values/karpenter-resources" + values = [ + <<-EOT + clusterName: ${module.eks.cluster_name} + ec2NodeClass: + karpenterRole: ${split("/", module.eks_blueprints_addons.karpenter.node_iam_role_arn)[1]} + nodePool: + labels: + - provisioner: default + - workload: rayhead + EOT + ] + } + } +} +``` + +## Testing the Chart with Helm Template + +To review the Kubernetes manifests that will be generated by the Helm chart based on your configuration, you can use the `helm template` command. This is especially useful for validating your Terraform configurations before applying them. + +1. **Generate the Manifests** + + Navigate to the directory where your Helm chart is located. + + ```sh + cd path/to/helm-chart + ``` + +2. **Run Helm Template** + + Use the `helm template` command with your custom values. For example: + + ```sh + helm template my-release-name . --values values.yaml + ``` + + Replace `my-release-name` with a name for your release, and `values.yaml` with the path to your custom values file. + + To test specific configurations defined in your Terraform file, you can create a temporary values file with the configuration snippet from your Terraform definition: + + ```sh + echo '' > temp-values.yaml + helm template my-release-name . --values temp-values.yaml + rm temp-values.yaml + ``` + + This will output the Kubernetes manifests to your terminal, allowing you to review them. diff --git a/karpenter-resources/templates/_helpers.tpl b/karpenter-resources/templates/_helpers.tpl new file mode 100644 index 0000000..19c2446 --- /dev/null +++ b/karpenter-resources/templates/_helpers.tpl @@ -0,0 +1,125 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "karpenter-node-pool.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "karpenter-node-pool.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "karpenter-node-pool.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "karpenter-node-pool.labels" -}} +helm.sh/chart: {{ include "karpenter-node-pool.chart" . }} +{{ include "karpenter-node-pool.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "karpenter-node-pool.selectorLabels" -}} +app.kubernetes.io/name: {{ include "karpenter-node-pool.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "karpenter-node-pool.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "karpenter-node-pool.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Expand the name of the chart. +*/}} +{{- define "karpenter-node-class.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "karpenter-node-class.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "karpenter-node-class.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "karpenter-node-class.labels" -}} +helm.sh/chart: {{ include "karpenter-node-class.chart" . }} +{{ include "karpenter-node-class.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "karpenter-node-class.selectorLabels" -}} +app.kubernetes.io/name: {{ include "karpenter-node-class.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "karpenter-node-class.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "karpenter-node-class.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/karpenter-resources/templates/node-class.yaml b/karpenter-resources/templates/node-class.yaml new file mode 100644 index 0000000..9610c63 --- /dev/null +++ b/karpenter-resources/templates/node-class.yaml @@ -0,0 +1,73 @@ +{{- if .Values.ec2NodeClass.enabled }} +apiVersion: karpenter.k8s.aws/v1 +kind: EC2NodeClass +metadata: + name: {{ .Values.nodePool.nodeClassRef.name }} +spec: + {{- if .Values.ec2NodeClass.amiFamily }} + amiFamily: {{ .Values.ec2NodeClass.amiFamily }} + {{- end }} + {{- if .Values.ec2NodeClass.amiSelectorTerms }} + amiSelectorTerms: + {{- toYaml .Values.ec2NodeClass.amiSelectorTerms | nindent 4 }} + {{- end }} + {{- if .Values.ec2NodeClass.subnetSelectorTerms }} + subnetSelectorTerms: + {{- range .Values.ec2NodeClass.subnetSelectorTerms }} + - {{- if .tags }} + tags: + {{- range $key, $value := .tags }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + {{- if .id }} + id: {{ .id }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.ec2NodeClass.securityGroupSelectorTerms }} + securityGroupSelectorTerms: + {{- range .Values.ec2NodeClass.securityGroupSelectorTerms }} + - {{- if .tags }} + tags: + {{- range $key, $value := .tags }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + {{- if .id }} + id: {{ .id }} + {{- end }} + {{- if .name }} + name: {{ .name }} + {{- end }} + {{- end }} + {{- end }} + instanceProfile: {{ .Values.ec2NodeClass.karpenterRole }} + {{- if .Values.ec2NodeClass.tags }} + tags: + {{- range $key, $value := .Values.ec2NodeClass.tags }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + metadataOptions: + httpEndpoint: {{ .Values.ec2NodeClass.metadataOptions.httpEndpoint }} + {{- if .Values.ec2NodeClass.metadataOptions.httpProtocolIPv6 }} + httpProtocolIPv6: {{ .Values.ec2NodeClass.metadataOptions.httpProtocolIPv6 }} + {{- end }} + {{- if .Values.ec2NodeClass.metadataOptions.httpPutResponseHopLimit }} + httpPutResponseHopLimit: {{ .Values.ec2NodeClass.metadataOptions.httpPutResponseHopLimit }} + {{- end }} + httpTokens: {{ .Values.ec2NodeClass.metadataOptions.httpTokens }} + {{- if .Values.ec2NodeClass.blockDeviceMappings }} + blockDeviceMappings: + {{- toYaml .Values.ec2NodeClass.blockDeviceMappings | nindent 4 }} + {{- end }} + detailedMonitoring: {{ .Values.ec2NodeClass.detailedMonitoring }} + {{- if .Values.ec2NodeClass.instanceStorePolicy }} + instanceStorePolicy: {{ .Values.ec2NodeClass.instanceStorePolicy }} + {{- end }} + {{- if .Values.ec2NodeClass.userData }} + userData: | + {{- .Values.ec2NodeClass.userData | nindent 4 }} + {{- end }} +{{- end }} diff --git a/karpenter-resources/templates/node-pool.yaml b/karpenter-resources/templates/node-pool.yaml new file mode 100644 index 0000000..ac8e368 --- /dev/null +++ b/karpenter-resources/templates/node-pool.yaml @@ -0,0 +1,57 @@ +{{- if .Values.nodePool.enabled }} +apiVersion: karpenter.sh/v1 +kind: NodePool +metadata: + name: {{ .Values.nodePool.name }} +spec: + template: + metadata: + labels: + NodePool: {{ .Values.nodePool.name }} + NodeGroupType: {{ .Values.nodePool.name }} + {{- if .Values.nodePool.labels }} + {{- with .Values.nodePool.labels }} + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + {{- end }} + spec: + nodeClassRef: + name: {{ .Values.nodePool.nodeClassRef.name }} + group: {{ .Values.nodePool.nodeClassRef.group }} + kind: {{ .Values.nodePool.nodeClassRef.kind }} + {{- with .Values.nodePool.taints }} + taints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodePool.requirements }} + requirements: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.nodePool.expireAfter }} + expireAfter: {{ .Values.nodePool.expireAfter }} + {{- end }} + {{- if .Values.nodePool.terminationGracePeriod }} + terminationGracePeriod: {{ .Values.nodePool.terminationGracePeriod }} + {{- end }} + disruption: + consolidationPolicy: {{ .Values.nodePool.disruption.consolidationPolicy }} + consolidateAfter: {{ .Values.nodePool.disruption.consolidateAfter }} + {{- with .Values.nodePool.disruption.budgets }} + budgets: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.nodePool.limits }} + limits: + {{- if .cpu }} + cpu: {{ .cpu }} + {{- end }} + {{- if .memory }} + memory: {{ .memory }} + {{- end }} + {{- end }} + {{- if .Values.nodePool.weight }} + weight: {{ .Values.nodePool.weight }} + {{- end }} +{{- end }} diff --git a/karpenter-resources/values.yaml b/karpenter-resources/values.yaml new file mode 100644 index 0000000..cc9886d --- /dev/null +++ b/karpenter-resources/values.yaml @@ -0,0 +1,69 @@ +# Shared values +name: default +clusterName: test-cluster + +# EC2NodeClass specific values +ec2NodeClass: + enabled: true + amiFamily: bottlerocket + amiSelectorTerms: + - alias: "Bottlerocket@latest" + subnetSelectorTerms: + - tags: + Name: subnet-name + securityGroupSelectorTerms: + - tags: + Name: security-group-name + karpenterRole: karpenter-role + metadataOptions: + httpEndpoint: enabled + httpProtocolIPv6: enabled + httpPutResponseHopLimit: 2 + httpTokens: required + blockDeviceMappings: + - deviceName: /dev/xvda + ebs: + volumeSize: "40Gi" + volumeType: gp3 + detailedMonitoring: true + instanceStorePolicy: RAID0 + + +# NodePool specific values +nodePool: + name: example-cluster-node-pool + enabled: true + nodeClassRef: + name: default + group: karpenter.k8s.aws + kind: EC2NodeClass + disruption: + consolidationPolicy: "WhenEmptyOrUnderutilized" + consolidateAfter: "5m" + budgets: + maxUnavailable: 1 + maxUnavailablePercentage: 10 + limits: + cpu: "1000" + memory: 1000Gi + weight: 1 + labels: {} + taints: [] + requirements: + - key: "kubernetes.io/arch" + operator: "In" + values: ["amd64"] + - key: kubernetes.io/os + operator: In + values: ["linux"] + - key: karpenter.sh/capacity-type + operator: In + values: ["on-demand", "spot"] + - key: karpenter.k8s.aws/instance-generation + operator: Gt + values: ["2"] + - key: "karpenter.k8s.aws/instance-hypervisor" + operator: In + values: ["nitro"] + expireAfter: "72h" + terminationGracePeriod: "4h" diff --git a/main.tf b/main.tf index 4393215..5e5818e 100644 --- a/main.tf +++ b/main.tf @@ -1,7 +1,7 @@ locals { namespace = "karpenter" amd_ami_family = "Bottlerocket" - amd_ami_alias = "bottlerocket" + amd_ami_alias = "bottlerocket@latest" } # Replicating from here: https://github.e.it.census.gov/SCT-Engineering/terraform-aws-eks/tree/master/modules/karpenter @@ -22,6 +22,20 @@ module "karpenter_resources" { tags = var.tags } +# Create IAM Instance Profile for Karpenter Nodes +resource "aws_iam_instance_profile" "karpenter_node" { + name = "${var.cluster_name}-karpenter-node-profile" + role = module.karpenter_resources.node_iam_role_name + + tags = merge( + var.tags, + { + "karpenter.sh/managed-by" = var.cluster_name + "kubernetes.io/cluster/${var.cluster_name}" = "owned" + } + ) +} + # Install Karpenter data "aws_ecr_image" "karpenter_image" { depends_on = [ @@ -117,7 +131,76 @@ resource "helm_release" "karpenter" { timeout = 300 } -resource "aws_iam_instance_profile" "karpenter_node_instance_profile" { - name = "${var.cluster_name}-karpenter-instance-profile" - role = module.karpenter_resources.node_iam_role_name +resource "helm_release" "nodepool_resources" { + depends_on = [ + helm_release.karpenter + ] + name = "nodepool-resources" + description = "Kubernetes Node Autoscaling: built for flexibility, performance, and simplicity" + chart = "./karpenter-resources" + version = local.module_version + namespace = local.namespace + + values = [ + file("${path.module}/karpenter-resources/values.yaml") + ] + #### Default values overrides + set { + name = "name" + value = var.cluster_name + } + set { + name = "clusterName" + value = var.cluster_name + } + set { + name = "ec2NodeClass.karpenterRole" + value = aws_iam_instance_profile.karpenter_node.name + } + set { + name = "ec2NodeClass.amiFamily" + value = local.amd_ami_family + } + set { + name = "ec2NodeClass.amiSelectorTerms[0].alias" + value = local.amd_ami_alias + } + set { + name = "ec2NodeClass.securityGroupSelectorTerms[0].tags.Name" + value = "${var.cluster_name}-node" + } + set { + name = "ec2NodeClass.subnetSelectorTerms[0].tags.Name" + value = var.subnets_name + } + # set { + # name = "ec2NodeClass.subnetSelectorTerms[0].tags.\"kubernetes.io/cluster/${var.cluster_name}\"" + # value = "shared" + # } + ### Node Class Inputs + set { + name = "nodePool.nodeClassRef.name" + value = "${var.cluster_name}-node-class" + } + set { + name = "nodePool.name" + value = "${var.cluster_name}-karpenter-node-pool" + } + set { + name = "nodeClass.cluster_name" + value = var.cluster_name + } + set { + name = "nodePool.limits.cpu" + value = "1000" + } + set { + name = "nodePool.limits.memory" + value = "1000Gi" + } + set { + name = "ec2NodeClass.tags" + value = jsonencode(var.tags) + } + } diff --git a/node_class.tf b/node_class.tf deleted file mode 100644 index e5b981e..0000000 --- a/node_class.tf +++ /dev/null @@ -1,67 +0,0 @@ -resource "kubernetes_manifest" "karpenter_node_class" { - depends_on = [aws_iam_instance_profile.karpenter_node_instance_profile] - - manifest = { - apiVersion = "${helm_release.karpenter.name}.k8s.aws/v1" - kind = "EC2NodeClass" - metadata = { - name = "${var.cluster_name}-${helm_release.karpenter.name}-node-class" - annotations = { - "kubernetes.io/description" = "EC2NodeClass for running ${local.amd_ami_family} nodes" - } - } - spec = { - amiFamily = local.amd_ami_family - amiSelectorTerms = [ - { - alias = "${local.amd_ami_alias}@latest" - } - ] - detailedMonitoring = true - instanceProfile = aws_iam_instance_profile.karpenter_node_instance_profile.name - instanceStorePolicy = "RAID0" - kubelet = { - evictionHard = { - "memory.available" = "5%" - "nodefs.available" = "10%" - "nodefs.inodesFree" = "10%" - } - evictionMaxPodGracePeriod = 60 - evictionSoft = { - "memory.available" = "500Mi" - "nodefs.available" = "15%" - "nodefs.inodesFree" = "15%" - } - evictionSoftGracePeriod = { - "memory.available" = "1m" - "nodefs.available" = "1m30s" - "nodefs.inodesFree" = "2m" - } - imageGCHighThresholdPercent = 85 - imageGCLowThresholdPercent = 80 - } - metadataOptions = { - httpEndpoint = "enabled" - httpProtocolIPv6 = "enabled" - httpPutResponseHopLimit = 2 - httpTokens = "required" - } - securityGroupSelectorTerms = [ - { - tags = { - Name = "${var.cluster_name}-node" - } - } - ] - subnetSelectorTerms = [ - { - tags = { - Name = var.subnets_name - "kubernetes.io/cluster/${var.cluster_name}" = "shared" - } - } - ] - tags = var.tags - } - } -} diff --git a/node_pool.tf b/node_pool.tf deleted file mode 100644 index a270888..0000000 --- a/node_pool.tf +++ /dev/null @@ -1,58 +0,0 @@ -resource "kubernetes_manifest" "karpenter_node_pool" { - depends_on = [kubernetes_manifest.karpenter_node_class] - manifest = { - apiVersion = "${helm_release.karpenter.name}.sh/v1" - kind = "NodePool" - metadata = { - name = "${var.cluster_name}-${helm_release.karpenter.name}-node-pool" - annotations = { - "kubernetes.io/description" = "General purpose NodePool for generic workloads" - } - } - spec = { - template = { - spec = { - requirements = [ - { - key = "kubernetes.io/arch" - operator = "In" - values = ["amd64"] - }, - { - key = "kubernetes.io/os" - operator = "In" - values = ["linux"] - }, - { - key = "${helm_release.karpenter.name}.k8s.aws/instance-hypervisor" - operator = "In" - values = ["nitro"] - }, - { - key = "${helm_release.karpenter.name}.sh/capacity-type" - operator = "In" - values = ["spot", "on-demand"] - }, - { - key = "${helm_release.karpenter.name}.k8s.aws/instance-generation" - operator = "Gt" - values = ["2"] - } - ] - nodeClassRef = { - group = "${helm_release.karpenter.name}.k8s.aws" - kind = "EC2NodeClass" - name = "${var.cluster_name}-${helm_release.karpenter.name}-node-class" - } - expireAfter = "72h" - terminationGracePeriod = "8h" - } - } - disruption = { - consolidationPolicy = "WhenEmptyOrUnderutilized" - consolidateAfter = "30s" - } - tags = var.tags - } - } -} diff --git a/requirements.tf b/requirements.tf index ae62e15..2e678e4 100644 --- a/requirements.tf +++ b/requirements.tf @@ -10,9 +10,5 @@ terraform { source = "hashicorp/helm" version = ">= 2.11.0" } - kubernetes = { - source = "hashicorp/kubernetes" - version = ">= 2.23.0" - } } }