diff --git a/aws/platform/README.md b/aws/platform/README.md
index 99599928..bf6c2df2 100644
--- a/aws/platform/README.md
+++ b/aws/platform/README.md
@@ -135,6 +135,7 @@ You can then use it to manually edit the aws-auth ConfigMap:
| [auth\_config\_map](#module\_auth\_config\_map) | ./modules/auth-config-map | n/a |
| [aws\_ebs\_csi\_driver](#module\_aws\_ebs\_csi\_driver) | ./modules/aws-ebs-csi-driver | n/a |
| [aws\_load\_balancer\_controller](#module\_aws\_load\_balancer\_controller) | ./modules/load-balancer-controller | n/a |
+| [cloudwatch\_adapter\_service\_account\_role](#module\_cloudwatch\_adapter\_service\_account\_role) | ./modules/cloudwatch-adapter-service-account-role | n/a |
| [cloudwatch\_logs](#module\_cloudwatch\_logs) | ./modules/cloudwatch-logs | n/a |
| [cluster\_autoscaler\_service\_account\_role](#module\_cluster\_autoscaler\_service\_account\_role) | ./modules/cluster-autoscaler-service-account-role | n/a |
| [cluster\_name](#module\_cluster\_name) | ../cluster-name | n/a |
@@ -170,6 +171,7 @@ You can then use it to manually edit the aws-auth ConfigMap:
| [aws\_tags](#input\_aws\_tags) | Tags to be applied to created AWS resources | `map(string)` | `{}` | no |
| [cert\_manager\_values](#input\_cert\_manager\_values) | Overrides to pass to the Helm chart | `list(string)` | `[]` | no |
| [certificate\_issuer](#input\_certificate\_issuer) | YAML spec for certificate issuer; defaults to self-signed | `string` | `null` | no |
+| [cloudwatch\_adapter\_values](#input\_cloudwatch\_adapter\_values) | Overrides to pass to the Helm chart | `list(string)` | `[]` | no |
| [cluster\_autoscaler\_values](#input\_cluster\_autoscaler\_values) | Overrides to pass to the Helm chart | `list(string)` | `[]` | no |
| [cluster\_name](#input\_cluster\_name) | Name of the EKS cluster | `string` | n/a | yes |
| [custom\_roles](#input\_custom\_roles) | Additional IAM roles which have custom cluster privileges | `map(string)` | `{}` | no |
diff --git a/aws/platform/main.tf b/aws/platform/main.tf
index 254d96b9..70669747 100644
--- a/aws/platform/main.tf
+++ b/aws/platform/main.tf
@@ -24,6 +24,11 @@ module "common_platform" {
var.cert_manager_values
)
+ cloudwatch_adapter_values = concat(
+ local.cloudwatch_adapter_values,
+ var.cloudwatch_adapter_values
+ )
+
cluster_autoscaler_values = concat(
local.cluster_autoscaler_values,
var.cluster_autoscaler_values
@@ -128,6 +133,15 @@ module "cloudwatch_logs" {
skip_destroy = var.logs_skip_destroy
}
+module "cloudwatch_adapter_service_account_role" {
+ source = "./modules/cloudwatch-adapter-service-account-role"
+
+ aws_namespace = [module.cluster_name.full]
+ aws_tags = var.aws_tags
+ k8s_namespace = var.k8s_namespace
+ oidc_issuer = data.aws_ssm_parameter.oidc_issuer.value
+}
+
module "cluster_autoscaler_service_account_role" {
source = "./modules/cluster-autoscaler-service-account-role"
@@ -251,6 +265,16 @@ locals {
})
]
+ cloudwatch_adapter_values = [
+ yamlencode({
+ serviceAccount = {
+ annotations = {
+ "eks.amazonaws.com/role-arn" = module.cloudwatch_adapter_service_account_role.arn
+ }
+ }
+ })
+ ]
+
cluster_autoscaler_values = [
yamlencode({
autoDiscovery = {
diff --git a/aws/platform/modules/cloudwatch-adapter-service-account-role/README.md b/aws/platform/modules/cloudwatch-adapter-service-account-role/README.md
new file mode 100644
index 00000000..f092de81
--- /dev/null
+++ b/aws/platform/modules/cloudwatch-adapter-service-account-role/README.md
@@ -0,0 +1,44 @@
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 0.14.8 |
+| [aws](#requirement\_aws) | ~> 4.0 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [aws](#provider\_aws) | ~> 4.0 |
+
+## Modules
+
+| Name | Source | Version |
+|------|--------|---------|
+| [cloudwatch\_adapter\_service\_account\_role](#module\_cloudwatch\_adapter\_service\_account\_role) | ../../../service-account-role | n/a |
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [aws_iam_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
+| [aws_iam_role_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
+| [aws_iam_policy_document.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [aws\_namespace](#input\_aws\_namespace) | Prefix to be applied to created AWS resources | `list(string)` | `[]` | no |
+| [aws\_tags](#input\_aws\_tags) | Tags to be applied to created AWS resources | `map(string)` | `{}` | no |
+| [k8s\_namespace](#input\_k8s\_namespace) | Kubernetes namespace in which resources should be created | `string` | n/a | yes |
+| [oidc\_issuer](#input\_oidc\_issuer) | OIDC issuer of the Kubernetes cluster | `string` | n/a | yes |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [arn](#output\_arn) | The ARN of the created role |
+| [service\_account\_role\_arn](#output\_service\_account\_role\_arn) | ARN of the AWS IAM role created for service accounts |
+
\ No newline at end of file
diff --git a/aws/platform/modules/cloudwatch-adapter-service-account-role/main.tf b/aws/platform/modules/cloudwatch-adapter-service-account-role/main.tf
new file mode 100644
index 00000000..c05c594d
--- /dev/null
+++ b/aws/platform/modules/cloudwatch-adapter-service-account-role/main.tf
@@ -0,0 +1,28 @@
+module "cloudwatch_adapter_service_account_role" {
+ source = "../../../service-account-role"
+
+ name = "cloudwatch-adapter"
+ namespace = var.aws_namespace
+ oidc_issuers = [var.oidc_issuer]
+ service_accounts = ["${var.k8s_namespace}:cloudwatch-adapter"]
+ tags = var.aws_tags
+}
+
+resource "aws_iam_policy" "this" {
+ name = module.cloudwatch_adapter_service_account_role.name
+ policy = data.aws_iam_policy_document.this.json
+}
+
+resource "aws_iam_role_policy_attachment" "this" {
+ role = module.cloudwatch_adapter_service_account_role.name
+ policy_arn = aws_iam_policy.this.arn
+}
+
+data "aws_iam_policy_document" "this" {
+ statement {
+ actions = [
+ "cloudwatch:GetMetricData"
+ ]
+ resources = ["*"]
+ }
+}
diff --git a/aws/platform/modules/cloudwatch-adapter-service-account-role/makefile b/aws/platform/modules/cloudwatch-adapter-service-account-role/makefile
new file mode 100644
index 00000000..364a9e25
--- /dev/null
+++ b/aws/platform/modules/cloudwatch-adapter-service-account-role/makefile
@@ -0,0 +1,67 @@
+MODULEFILES := $(wildcard *.tf)
+TFLINTRC ?= ../../.tflint.hcl
+TFDOCSRC ?= ../../.terraform-docs.yml
+
+.PHONY: default
+default: checkfmt validate docs lint
+
+.PHONY: checkfmt
+checkfmt: .fmt
+
+.PHONY: fmt
+fmt: $(MODULEFILES)
+ terraform fmt
+ @touch .fmt
+
+.PHONY: validate
+validate: .validate
+
+.PHONY: docs
+docs: README.md
+
+.PHONY: lint
+lint: .lint
+
+.lint: $(MODULEFILES) .lintinit
+ tflint --config=$(TFLINTRC)
+ @touch .lint
+
+.lintinit: $(TFLINTRC)
+ tflint --init --config=$(TFLINTRC) --module
+ @touch .lintinit
+
+README.md: $(MODULEFILES)
+ terraform-docs --config "$(TFDOCSRC)" markdown table . --output-file README.md
+
+.fmt: $(MODULEFILES)
+ terraform fmt -check
+ @touch .fmt
+
+.PHONY: init
+init: .init
+
+.init: versions.tf .dependencies
+ terraform init -backend=false
+ @touch .init
+
+.validate: .init $(MODULEFILES) $(wildcard *.tf.example)
+ echo | cat - $(wildcard *.tf.example) > test.tf
+ if AWS_DEFAULT_REGION=us-east-1 terraform validate; then \
+ rm test.tf; \
+ touch .validate; \
+ else \
+ rm test.tf; \
+ false; \
+ fi
+
+.dependencies: *.tf
+ @grep -ohE \
+ "\b(backend|provider|resource|module) ['\"][[:alpha:]][[:alnum:]]*|\bsource *=.*" *.tf | \
+ sed "s/['\"]//" | sort | uniq | \
+ tee /tmp/initdeps | \
+ diff -q .dependencies - >/dev/null 2>&1 || \
+ mv /tmp/initdeps .dependencies
+
+.PHONY: clean
+clean:
+ rm -rf .dependencies .fmt .init .lint .lintinit .terraform* .validate
diff --git a/aws/platform/modules/cloudwatch-adapter-service-account-role/outputs.tf b/aws/platform/modules/cloudwatch-adapter-service-account-role/outputs.tf
new file mode 100644
index 00000000..d778c65f
--- /dev/null
+++ b/aws/platform/modules/cloudwatch-adapter-service-account-role/outputs.tf
@@ -0,0 +1,9 @@
+output "arn" {
+ description = "The ARN of the created role"
+ value = module.cloudwatch_adapter_service_account_role.instance.arn
+}
+
+output "service_account_role_arn" {
+ description = "ARN of the AWS IAM role created for service accounts"
+ value = module.cloudwatch_adapter_service_account_role.instance.arn
+}
diff --git a/aws/platform/modules/cloudwatch-adapter-service-account-role/variables.tf b/aws/platform/modules/cloudwatch-adapter-service-account-role/variables.tf
new file mode 100644
index 00000000..e0b085c9
--- /dev/null
+++ b/aws/platform/modules/cloudwatch-adapter-service-account-role/variables.tf
@@ -0,0 +1,21 @@
+variable "aws_namespace" {
+ type = list(string)
+ default = []
+ description = "Prefix to be applied to created AWS resources"
+}
+
+variable "aws_tags" {
+ type = map(string)
+ description = "Tags to be applied to created AWS resources"
+ default = {}
+}
+
+variable "k8s_namespace" {
+ type = string
+ description = "Kubernetes namespace in which resources should be created"
+}
+
+variable "oidc_issuer" {
+ type = string
+ description = "OIDC issuer of the Kubernetes cluster"
+}
diff --git a/aws/platform/modules/cloudwatch-adapter-service-account-role/versions.tf b/aws/platform/modules/cloudwatch-adapter-service-account-role/versions.tf
new file mode 100644
index 00000000..020f4777
--- /dev/null
+++ b/aws/platform/modules/cloudwatch-adapter-service-account-role/versions.tf
@@ -0,0 +1,9 @@
+terraform {
+ required_version = ">= 0.14.8"
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = "~> 4.0"
+ }
+ }
+}
diff --git a/aws/platform/variables.tf b/aws/platform/variables.tf
index 0c7ae6eb..5e6c4279 100644
--- a/aws/platform/variables.tf
+++ b/aws/platform/variables.tf
@@ -51,6 +51,12 @@ variable "certificate_issuer" {
default = null
}
+variable "cloudwatch_adapter_values" {
+ description = "Overrides to pass to the Helm chart"
+ type = list(string)
+ default = []
+}
+
variable "cluster_autoscaler_values" {
description = "Overrides to pass to the Helm chart"
type = list(string)
diff --git a/platform/README.md b/platform/README.md
index 647f8c97..e4c37697 100644
--- a/platform/README.md
+++ b/platform/README.md
@@ -39,6 +39,7 @@ practices.
| Name | Source | Version |
|------|--------|---------|
| [cert\_manager](#module\_cert\_manager) | ./modules/cert-manager | n/a |
+| [cloudwatch\_adapter](#module\_cloudwatch\_adapter) | ./modules/cloudwatch-adapter | n/a |
| [cluster\_autoscaler](#module\_cluster\_autoscaler) | ./modules/cluster-autoscaler | n/a |
| [external\_dns](#module\_external\_dns) | ./modules/external-dns | n/a |
| [federated\_prometheus](#module\_federated\_prometheus) | ./modules/prometheus-instance | n/a |
@@ -71,6 +72,7 @@ practices.
| [cert\_manager\_values](#input\_cert\_manager\_values) | Overrides to pass to the Helm chart | `list(string)` | `[]` | no |
| [cert\_manager\_version](#input\_cert\_manager\_version) | Version of cert-manager to install | `string` | `null` | no |
| [certificate\_issuer](#input\_certificate\_issuer) | YAML spec for certificate issuer; defaults to self-signed | `string` | `null` | no |
+| [cloudwatch\_adapter\_values](#input\_cloudwatch\_adapter\_values) | Overrides to pass to the Helm chart | `list(string)` | `[]` | no |
| [cluster\_autoscaler\_values](#input\_cluster\_autoscaler\_values) | Overrides to pass to the Helm chart | `list(string)` | `[]` | no |
| [cluster\_autoscaler\_version](#input\_cluster\_autoscaler\_version) | Version of cluster-autoscaler to install | `string` | `null` | no |
| [domain\_names](#input\_domain\_names) | Domains which are allowed in this cluster | `list(string)` | `[]` | no |
diff --git a/platform/main.tf b/platform/main.tf
index 5f17b1ae..7509e972 100644
--- a/platform/main.tf
+++ b/platform/main.tf
@@ -60,6 +60,15 @@ module "cert_manager" {
k8s_namespace = local.flightdeck_namespace
}
+module "cloudwatch_adapter" {
+ source = "./modules/cloudwatch-adapter"
+
+ chart_values = var.cloudwatch_adapter_values
+ k8s_namespace = local.flightdeck_namespace
+
+ depends_on = [ module.module.prometheus_adapter ]
+}
+
module "cluster_autoscaler" {
source = "./modules/cluster-autoscaler"
diff --git a/platform/modules/cloudwatch-adapter/README.md b/platform/modules/cloudwatch-adapter/README.md
new file mode 100644
index 00000000..811c467b
--- /dev/null
+++ b/platform/modules/cloudwatch-adapter/README.md
@@ -0,0 +1,28 @@
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 0.14.8 |
+| [helm](#requirement\_helm) | ~> 2.4 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [helm](#provider\_helm) | ~> 2.4 |
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [helm_release.cloudwatch_adapter](https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release) | resource |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [chart\_values](#input\_chart\_values) | Overrides to pass to the Helm chart | `list(string)` | `[]` | no |
+| [k8s\_namespace](#input\_k8s\_namespace) | Kubernetes namespace in which secrets should be created | `string` | n/a | yes |
+| [name](#input\_name) | Name for the Helm release | `string` | `"cloudwatch-adapter"` | no |
+
\ No newline at end of file
diff --git a/platform/modules/cloudwatch-adapter/chart/Chart.yaml b/platform/modules/cloudwatch-adapter/chart/Chart.yaml
new file mode 100644
index 00000000..d79a9252
--- /dev/null
+++ b/platform/modules/cloudwatch-adapter/chart/Chart.yaml
@@ -0,0 +1,11 @@
+apiVersion: v2
+name: cloudwatch-adapter
+description: Configuration for cloudwatch adapter to fetch AWS Cloudwatch metrics in kubernetes
+
+type: application
+
+version: 0.1.0
+
+appVersion: 1.0.0
+
+# Downloaded from https://artifacthub.io/packages/helm/deliveryhero/k8s-cloudwatch-adapter
diff --git a/platform/modules/cloudwatch-adapter/chart/templates/_helpers.tpl b/platform/modules/cloudwatch-adapter/chart/templates/_helpers.tpl
new file mode 100644
index 00000000..19b218a6
--- /dev/null
+++ b/platform/modules/cloudwatch-adapter/chart/templates/_helpers.tpl
@@ -0,0 +1,61 @@
+
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "k8s-cloudwatch-adapter.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 "k8s-cloudwatch-adapter.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 "k8s-cloudwatch-adapter.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "k8s-cloudwatch-adapter.labels" -}}
+app.kubernetes.io/name: {{ include "k8s-cloudwatch-adapter.name" . }}
+helm.sh/chart: {{ include "k8s-cloudwatch-adapter.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- if .Values.extraLabels }}
+{{ toYaml .Values.extraLabels }}
+{{- end }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "k8s-cloudwatch-adapter.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+ {{ default (include "k8s-cloudwatch-adapter.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+ {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
+
diff --git a/platform/modules/cloudwatch-adapter/chart/templates/apiservice.yaml b/platform/modules/cloudwatch-adapter/chart/templates/apiservice.yaml
new file mode 100644
index 00000000..164bd1a4
--- /dev/null
+++ b/platform/modules/cloudwatch-adapter/chart/templates/apiservice.yaml
@@ -0,0 +1,14 @@
+apiVersion: apiregistration.k8s.io/v1
+kind: APIService
+metadata:
+ name: v1beta1.external.metrics.k8s.io
+spec:
+ service:
+ name: {{ include "k8s-cloudwatch-adapter.fullname" . }}
+ namespace: "{{ .Release.Namespace }}"
+ group: external.metrics.k8s.io
+ version: v1beta1
+ insecureSkipTLSVerify: true
+ groupPriorityMinimum: 100
+ versionPriority: 100
+
diff --git a/platform/modules/cloudwatch-adapter/chart/templates/clusterrole.yaml b/platform/modules/cloudwatch-adapter/chart/templates/clusterrole.yaml
new file mode 100644
index 00000000..351cd802
--- /dev/null
+++ b/platform/modules/cloudwatch-adapter/chart/templates/clusterrole.yaml
@@ -0,0 +1,41 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: {{ include "k8s-cloudwatch-adapter.fullname" . }}:crd-metrics-reader
+ labels:
+ app: {{ .Release.Name }}
+rules:
+- apiGroups:
+ - metrics.aws
+ resources:
+ - "externalmetrics"
+ verbs:
+ - list
+ - get
+ - watch
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: {{ include "k8s-cloudwatch-adapter.fullname" . }}-resource-reader
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - namespaces
+ - pods
+ - services
+ verbs:
+ - get
+ - list
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: {{ include "k8s-cloudwatch-adapter.fullname" . }}:external-metrics-reader
+rules:
+- apiGroups:
+ - external.metrics.k8s.io
+ resources: ["*"]
+ verbs: ["*"]
+
diff --git a/platform/modules/cloudwatch-adapter/chart/templates/clusterrolebinding.yaml b/platform/modules/cloudwatch-adapter/chart/templates/clusterrolebinding.yaml
new file mode 100644
index 00000000..8a8a5954
--- /dev/null
+++ b/platform/modules/cloudwatch-adapter/chart/templates/clusterrolebinding.yaml
@@ -0,0 +1,55 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: {{ include "k8s-cloudwatch-adapter.fullname" . }}:crd-metrics-reader
+ labels:
+ app: {{ .Release.Name }}
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: {{ include "k8s-cloudwatch-adapter.fullname" . }}:crd-metrics-reader
+subjects:
+ - name: {{ template "k8s-cloudwatch-adapter.serviceAccountName" . }}
+ namespace: "{{ .Release.Namespace }}"
+ kind: ServiceAccount
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: {{ include "k8s-cloudwatch-adapter.fullname" . }}-resource-reader
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: {{ include "k8s-cloudwatch-adapter.fullname" . }}-resource-reader
+subjects:
+- kind: ServiceAccount
+ name: {{ template "k8s-cloudwatch-adapter.serviceAccountName" . }}
+ namespace: "{{ .Release.Namespace }}"
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: {{ include "k8s-cloudwatch-adapter.fullname" . }}:external-metrics-reader
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: {{ include "k8s-cloudwatch-adapter.fullname" . }}:external-metrics-reader
+subjects:
+- kind: ServiceAccount
+ name: horizontal-pod-autoscaler
+ namespace: kube-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: {{ include "k8s-cloudwatch-adapter.fullname" . }}:system:auth-delegator
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: system:auth-delegator
+subjects:
+- kind: ServiceAccount
+ name: {{ template "k8s-cloudwatch-adapter.serviceAccountName" . }}
+ namespace: "{{ .Release.Namespace }}"
+
+
diff --git a/platform/modules/cloudwatch-adapter/chart/templates/crd.yaml b/platform/modules/cloudwatch-adapter/chart/templates/crd.yaml
new file mode 100644
index 00000000..5aef62cd
--- /dev/null
+++ b/platform/modules/cloudwatch-adapter/chart/templates/crd.yaml
@@ -0,0 +1,84 @@
+{{- if .Capabilities.APIVersions.Has "apiextensions.k8s.io/v1" }}
+apiVersion: apiextensions.k8s.io/v1
+{{- else }}
+apiVersion: apiextensions.k8s.io/v1beta1
+{{- end }}
+kind: CustomResourceDefinition
+metadata:
+ name: externalmetrics.metrics.aws
+spec:
+ group: metrics.aws
+ {{- if .Capabilities.APIVersions.Has "apiextensions.k8s.io/v1" }}
+ versions:
+ - name: v1alpha1
+ served: true
+ storage: true
+ schema:
+ openAPIV3Schema:
+ type: object
+ properties:
+ spec:
+ type: object
+ required:
+ - name
+ - queries
+ properties:
+ name:
+ type: string
+ roleArn:
+ type: string
+ region:
+ type: string
+ queries:
+ type: array
+ items:
+ type: object
+ properties:
+ expression:
+ type: string
+ id:
+ type: string
+ label:
+ type: string
+ metricStat:
+ type: object
+ properties:
+ metric:
+ type: object
+ required:
+ - metricName
+ properties:
+ dimensions:
+ type: array
+ items:
+ type: object
+ required:
+ - name
+ - value
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ metricName:
+ type: string
+ namespace:
+ type: string
+ period:
+ type: integer
+ stat:
+ type: string
+ unit:
+ type: string
+ returnData:
+ type: boolean
+ {{- else }}
+ version: v1alpha1
+ {{- end }}
+ names:
+ kind: ExternalMetric
+ plural: externalmetrics
+ singular: externalmetric
+ scope: Namespaced
+
+
diff --git a/platform/modules/cloudwatch-adapter/chart/templates/deployment.yaml b/platform/modules/cloudwatch-adapter/chart/templates/deployment.yaml
new file mode 100644
index 00000000..c5873667
--- /dev/null
+++ b/platform/modules/cloudwatch-adapter/chart/templates/deployment.yaml
@@ -0,0 +1,63 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "k8s-cloudwatch-adapter.fullname" . }}
+ labels:
+{{ include "k8s-cloudwatch-adapter.labels" . | indent 4 }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ app.kubernetes.io/name: {{ include "k8s-cloudwatch-adapter.name" . }}
+ app.kubernetes.io/instance: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app.kubernetes.io/name: {{ include "k8s-cloudwatch-adapter.name" . }}
+ app.kubernetes.io/instance: {{ .Release.Name }}
+ spec:
+ {{- with .Values.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ serviceAccountName: {{ template "k8s-cloudwatch-adapter.serviceAccountName" . }}
+ securityContext:
+ {{- toYaml .Values.podSecurityContext | nindent 8 }}
+ containers:
+ - name: {{ .Chart.Name }}
+ securityContext:
+ {{- toYaml .Values.securityContext | nindent 12 }}
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ args:
+ - /adapter
+ {{- range $key, $val := .Values.adapter.args }}
+ - --{{ $key }}={{ $val }}
+ {{- end }}
+ ports:
+ - containerPort: 6443
+ name: https
+ - containerPort: 8080
+ name: http
+ volumeMounts:
+ - mountPath: /tmp
+ name: temp-vol
+ resources:
+ {{- toYaml .Values.resources | nindent 10 }}
+ volumes:
+ - name: temp-vol
+ emptyDir: {}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+
+
diff --git a/platform/modules/cloudwatch-adapter/chart/templates/rolebinding.yaml b/platform/modules/cloudwatch-adapter/chart/templates/rolebinding.yaml
new file mode 100644
index 00000000..19848e40
--- /dev/null
+++ b/platform/modules/cloudwatch-adapter/chart/templates/rolebinding.yaml
@@ -0,0 +1,14 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+ name: {{ include "k8s-cloudwatch-adapter.fullname" . }}-auth-reader
+ namespace: kube-system
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: Role
+ name: extension-apiserver-authentication-reader
+subjects:
+- kind: ServiceAccount
+ name: {{ include "k8s-cloudwatch-adapter.fullname" . }}
+ namespace: "{{ .Release.Namespace }}"
+
diff --git a/platform/modules/cloudwatch-adapter/chart/templates/service.yaml b/platform/modules/cloudwatch-adapter/chart/templates/service.yaml
new file mode 100644
index 00000000..6b157140
--- /dev/null
+++ b/platform/modules/cloudwatch-adapter/chart/templates/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "k8s-cloudwatch-adapter.fullname" . }}
+ labels:
+{{ include "k8s-cloudwatch-adapter.labels" . | indent 4 }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - name: https
+ port: 443
+ targetPort: 6443
+ - name: http
+ port: 80
+ targetPort: 8080
+ selector:
+ app.kubernetes.io/name: {{ include "k8s-cloudwatch-adapter.name" . }}
+ app.kubernetes.io/instance: {{ .Release.Name }}
+
diff --git a/platform/modules/cloudwatch-adapter/chart/templates/serviceaccount.yaml b/platform/modules/cloudwatch-adapter/chart/templates/serviceaccount.yaml
new file mode 100644
index 00000000..967c34b8
--- /dev/null
+++ b/platform/modules/cloudwatch-adapter/chart/templates/serviceaccount.yaml
@@ -0,0 +1,12 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ template "k8s-cloudwatch-adapter.serviceAccountName" . }}
+{{- with .Values.serviceAccount.annotations }}
+ annotations: {{ toYaml . | nindent 4 }}
+{{- end }}
+ labels:
+{{ include "k8s-cloudwatch-adapter.labels" . | indent 4 }}
+{{- end -}}
+
diff --git a/platform/modules/cloudwatch-adapter/chart/values.yaml b/platform/modules/cloudwatch-adapter/chart/values.yaml
new file mode 100644
index 00000000..b31f7e98
--- /dev/null
+++ b/platform/modules/cloudwatch-adapter/chart/values.yaml
@@ -0,0 +1,50 @@
+adapter:
+ args:
+ cert-dir: /tmp
+ secure-port: 6443
+ logtostderr: true
+ v: 2
+
+replicaCount: 1
+
+image:
+ pullPolicy: IfNotPresent
+ tag: "v0.9.0"
+ repository: chankh/k8s-cloudwatch-adapter
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+ # Specifies whether a service account should be created
+ create: true
+ # The name of the service account to use.
+ # If not set and create is true, a name is generated using the fullname template
+ name: ""
+ annotations: {}
+
+
+podSecurityContext:
+ fsGroup: 65534
+
+securityContext: {}
+ # capabilities:
+ # drop:
+ # - ALL
+ # readOnlyRootFilesystem: true
+ # runAsNonRoot: true
+ # runAsUser: 1000
+
+service:
+ type: ClusterIP
+ port: 80
+
+resources: {}
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+extraLabels: {}
diff --git a/platform/modules/cloudwatch-adapter/main.tf b/platform/modules/cloudwatch-adapter/main.tf
new file mode 100644
index 00000000..aebe3268
--- /dev/null
+++ b/platform/modules/cloudwatch-adapter/main.tf
@@ -0,0 +1,7 @@
+resource "helm_release" "cloudwatch_adapter" {
+ chart = "${path.module}/chart"
+ name = var.name
+ namespace = var.k8s_namespace
+ values = var.chart_values
+}
+
diff --git a/platform/modules/cloudwatch-adapter/makefile b/platform/modules/cloudwatch-adapter/makefile
new file mode 100644
index 00000000..364a9e25
--- /dev/null
+++ b/platform/modules/cloudwatch-adapter/makefile
@@ -0,0 +1,67 @@
+MODULEFILES := $(wildcard *.tf)
+TFLINTRC ?= ../../.tflint.hcl
+TFDOCSRC ?= ../../.terraform-docs.yml
+
+.PHONY: default
+default: checkfmt validate docs lint
+
+.PHONY: checkfmt
+checkfmt: .fmt
+
+.PHONY: fmt
+fmt: $(MODULEFILES)
+ terraform fmt
+ @touch .fmt
+
+.PHONY: validate
+validate: .validate
+
+.PHONY: docs
+docs: README.md
+
+.PHONY: lint
+lint: .lint
+
+.lint: $(MODULEFILES) .lintinit
+ tflint --config=$(TFLINTRC)
+ @touch .lint
+
+.lintinit: $(TFLINTRC)
+ tflint --init --config=$(TFLINTRC) --module
+ @touch .lintinit
+
+README.md: $(MODULEFILES)
+ terraform-docs --config "$(TFDOCSRC)" markdown table . --output-file README.md
+
+.fmt: $(MODULEFILES)
+ terraform fmt -check
+ @touch .fmt
+
+.PHONY: init
+init: .init
+
+.init: versions.tf .dependencies
+ terraform init -backend=false
+ @touch .init
+
+.validate: .init $(MODULEFILES) $(wildcard *.tf.example)
+ echo | cat - $(wildcard *.tf.example) > test.tf
+ if AWS_DEFAULT_REGION=us-east-1 terraform validate; then \
+ rm test.tf; \
+ touch .validate; \
+ else \
+ rm test.tf; \
+ false; \
+ fi
+
+.dependencies: *.tf
+ @grep -ohE \
+ "\b(backend|provider|resource|module) ['\"][[:alpha:]][[:alnum:]]*|\bsource *=.*" *.tf | \
+ sed "s/['\"]//" | sort | uniq | \
+ tee /tmp/initdeps | \
+ diff -q .dependencies - >/dev/null 2>&1 || \
+ mv /tmp/initdeps .dependencies
+
+.PHONY: clean
+clean:
+ rm -rf .dependencies .fmt .init .lint .lintinit .terraform* .validate
diff --git a/platform/modules/cloudwatch-adapter/outputs.tf b/platform/modules/cloudwatch-adapter/outputs.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/platform/modules/cloudwatch-adapter/variables.tf b/platform/modules/cloudwatch-adapter/variables.tf
new file mode 100644
index 00000000..8995a498
--- /dev/null
+++ b/platform/modules/cloudwatch-adapter/variables.tf
@@ -0,0 +1,16 @@
+variable "chart_values" {
+ description = "Overrides to pass to the Helm chart"
+ type = list(string)
+ default = []
+}
+
+variable "k8s_namespace" {
+ type = string
+ description = "Kubernetes namespace in which secrets should be created"
+}
+
+variable "name" {
+ description = "Name for the Helm release"
+ type = string
+ default = "cloudwatch-adapter"
+}
diff --git a/platform/modules/cloudwatch-adapter/versions.tf b/platform/modules/cloudwatch-adapter/versions.tf
new file mode 100644
index 00000000..0ed6889f
--- /dev/null
+++ b/platform/modules/cloudwatch-adapter/versions.tf
@@ -0,0 +1,9 @@
+terraform {
+ required_version = ">= 0.14.8"
+ required_providers {
+ helm = {
+ source = "hashicorp/helm"
+ version = "~> 2.4"
+ }
+ }
+}
diff --git a/platform/variables.tf b/platform/variables.tf
index 3243ce56..e8dc621e 100644
--- a/platform/variables.tf
+++ b/platform/variables.tf
@@ -16,6 +16,12 @@ variable "certificate_issuer" {
default = null
}
+variable "cloudwatch_adapter_values" {
+ description = "Overrides to pass to the Helm chart"
+ type = list(string)
+ default = []
+}
+
variable "cluster_autoscaler_values" {
description = "Overrides to pass to the Helm chart"
type = list(string)