├── .gitignore ├── LICENSE ├── README.md ├── example ├── .terraform.lock.hcl ├── main.tf ├── outputs.example ├── outputs.tf └── top.example ├── main.tf ├── modules ├── apisix │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── clickhouse-operator │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── eks │ ├── README.md │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── grafana-operator │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── grafana │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── kubernetes-dashboard │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── kubernetes-manifests │ ├── chart │ │ ├── Chart.yaml │ │ ├── LICENSE │ │ ├── README.md │ │ ├── templates │ │ │ ├── _helpers.tpl │ │ │ └── resources.yaml │ │ └── values.yaml │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── nginx │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── openobserve-collector │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── openobserve │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── opentelemetry-operator │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── qryn │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── uptrace │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── vector │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── victoriametrics-operator │ ├── main.tf │ ├── outputs.tf │ └── variables.tf └── victoriametrics │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── outputs.tf ├── promlems.md ├── universal_values.yaml └── variables.tf /.gitignore: -------------------------------------------------------------------------------- 1 | # Local .terraform directories 2 | **/.terraform/* 3 | 4 | # .tfstate files 5 | *.tfstate 6 | *.tfstate.* 7 | 8 | # Crash log files 9 | crash.log 10 | crash.*.log 11 | 12 | # Exclude all .tfvars files, which are likely to contain sensitive data, such as 13 | # password, private keys, and other secrets. These should not be part of version 14 | # control as they are data points which are potentially sensitive and subject 15 | # to change depending on the environment. 16 | *.tfvars 17 | *.tfvars.json 18 | 19 | # Ignore override files as they are usually used to override resources locally and so 20 | # are not checked in 21 | override.tf 22 | override.tf.json 23 | *_override.tf 24 | *_override.tf.json 25 | 26 | # Include override files you do wish to add to version control using negated pattern 27 | # !example_override.tf 28 | 29 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 30 | # example: *tfplan* 31 | 32 | # Ignore CLI configuration files 33 | .terraformrc 34 | terraform.rc 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 TL;DR DevOps 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # aws-eks-terraform 2 | 3 | [![#StandWithBelarus](https://img.shields.io/badge/Belarus-red?label=%23%20Stand%20With&labelColor=white&color=red) 4 | Voices From Belarus](https://bysol.org/en/) [![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://vshymanskyy.github.io/StandWithUkraine) 5 | 6 | ## Overview 7 | 8 | This project provides a ready-to-use configuration for setting up an AWS EKS cluster with all necessary controllers, operators, and monitoring stack. By using this configuration, DevOps engineers can save 1-2 months of work. 9 | 10 | ### Key Features 11 | 12 | - **Adaptation for small clusters**: Many modules, especially [Grafana monitoring stack](https://grafana.com/about/grafana-stack/), are created with the intention of being used in large clusters. I understand the pain of small projects, so I tried to create a setup that is as simple and efficient as possible. For example, [VictoriaMetrics](https://victoriametrics.com/) stack selected as best prometheus-like monitoring engine and [Uptrace](https://uptrace.dev/) with AWS S3 backend selected for long term metrics, logs and traces storage. 13 | - **Node Group Templates**: Templates for creating Managed Node Groups and Fargate Profile linked to each availability zone individually. 14 | - **Default Settings and Integration**: Reasonable default values and integration between modules for seamless setup. 15 | 16 | Similar projects: 17 | - [eks blueprints](https://github.com/aws-ia/terraform-aws-eks-blueprints/tree/main) 18 | - [tEKS](https://github.com/particuleio/teks) 19 | - [eks demo](https://github.com/awslabs/eksdemo) 20 | 21 | ### Development Time 22 | 23 | - [Filipp Frizzy](https://github.com/Friz-zy/): 181h 30m 24 | 25 | ## About the Author 26 | 27 | I'm Filipp - a Lead DevOps Engineer with 12+ years of experience, currently based in Poland (UTC+2). I am open to work and considering Senior, Lead, or Architect DevOps roles with a B2B contract from $7k/month and 100% remote. I have extensive experience as a primary or lead DevOps engineer in product teams and startups. If you are looking for a DevOps engineer for a project, contact me on [LinkedIn](https://www.linkedin.com/in/filipp-frizzy-289a0360/). 28 | 29 | From my side: 30 | - Working as Ops and DevOps engineer since 2012, with over 7 years of experience with UK & US teams. 31 | - Experience as Single, Main, or Lead DevOps for small teams of other Ops people. 32 | - Migration of services into Docker environments, including Kubernetes, Docker Swarm, and AWS Elastic Containers. 33 | - AWS is my primary cloud since 2015 34 | - Proficient with GitLab, GitHub, Jenkins, ArgoCD, and FluxCD CI & CD. 35 | - Writing Terraform, Terragrunt, Ansible, SaltStack, and other IaC setups. 36 | - Solved several production disasters with various Kubernetes setups. 37 | - Skilled in SQL and NoSQL HA setups, like Galera MySQL, MongoDB, Kafka, ZooKeeper, Clickhouse, Redis, etc. 38 | - Developed many monitoring solutions with Prometheus, VictoriaMetrics, EFK, Zabbix, etc. 39 | - Authored 2 open source projects with over 1k stars. 40 | 41 | ## Included Components 42 | 43 | | Description | Purpose | Enabled | DNS | 44 | | --- | --- | --- | --- | 45 | |EKS cluster module based on [terraform-aws-modules/eks/aws](https://github.com/terraform-aws-modules/terraform-aws-eks) v19|Base|True|| 46 | |Templates for Managed Node Groups and Fargate Profile to link them to each availability zone instead of all zones at once|Base|True|| 47 | |Integration of modules with each other and reasonable default values|Base|True|| 48 | |[CoreDNS EKS addon](https://docs.aws.amazon.com/eks/latest/userguide/managing-coredns.html)|Core|True|| 49 | |[Kube-Proxy EKS addon](https://docs.aws.amazon.com/eks/latest/userguide/managing-kube-proxy.html)|Core|True|| 50 | |[VPC CNI EKS addon](https://docs.aws.amazon.com/eks/latest/userguide/managing-vpc-cni.html)|Core|True|| 51 | |[AWS EBS CSI driver EKS addon](https://docs.aws.amazon.com/eks/latest/userguide/managing-ebs-csi.html)|Core|True|| 52 | |[Snapshot Controller EKS addon](https://docs.aws.amazon.com/eks/latest/userguide/csi-snapshot-controller.html)|Core|True|| 53 | |[AWS EFS CSI driver](https://github.com/aws-ia/terraform-aws-eks-blueprints-addons/blob/main/docs/addons/aws-efs-csi-driver.md)|Core|True|| 54 | |[AWS Node Termination Handler](https://github.com/aws-ia/terraform-aws-eks-blueprints-addons/blob/main/docs/addons/aws-node-termination-handler.md)|Core|True|| 55 | |[Cert Manager](https://github.com/aws-ia/terraform-aws-eks-blueprints-addons/blob/main/docs/addons/cert-manager.md)|Core|True|| 56 | |[Cluster Autoscaler](https://github.com/aws-ia/terraform-aws-eks-blueprints-addons/blob/main/docs/addons/cluster-autoscaler.md)|Core|True|| 57 | |[Metrics Server](https://github.com/aws-ia/terraform-aws-eks-blueprints-addons/blob/main/docs/addons/metrics-server.md)|Core|True|| 58 | |[Vertical Pod Autoscaler](https://github.com/aws-ia/terraform-aws-eks-blueprints-addons/blob/main/docs/addons/vertical-pod-autoscaler.md)|Core|True|| 59 | |[Ingress Apisix](https://github.com/apache/apisix-ingress-controller)|Ingress|True|| 60 | |[Ingress Nginx](https://github.com/kubernetes/ingress-nginx)|Ingress|False|| 61 | |[Victoriametrics Operator](https://github.com/VictoriaMetrics/operator)|Operator|True|| 62 | |[Opentelemetry Operator](https://github.com/open-telemetry/opentelemetry-operator)|Operator|False|| 63 | |[Clickhouse Operator](https://github.com/Altinity/clickhouse-operator)|Operator|False|| 64 | |[Grafana Operator](https://artifacthub.io/packages/helm/bitnami/grafana-operator)|Operator|True|| 65 | |[Victoriametrics](https://github.com/VictoriaMetrics/helm-charts/blob/master/charts/victoria-metrics-k8s-stack/README.md)|Monitoring|True|vmauth.${var.ingress_domain}
victoriametrics.${var.ingress_domain}
vmalertmanager.${var.ingress_domain}
vmagent.${var.ingress_domain}
vmalert.${var.ingress_domain}| 66 | |[Grafana](https://grafana.com/oss/grafana/)|Monitoring|True|grafana.${var.ingress_domain}| 67 | |[Uptrace](https://uptrace.dev/)|Monitoring|True|uptrace.${var.ingress_domain}| 68 | |[Vector](https://vector.dev/)|Monitoring|True|| 69 | |[Qryn](https://qryn.metrico.in)|Monitoring|False|qryn.${var.ingress_domain}| 70 | |[Openobserve](https://openobserve.ai/)|Monitoring|False|openobserve.${var.ingress_domain}| 71 | |[Kubernetes Dashboard](https://github.com/kubernetes/dashboard)|Control|False|k8s-dashboard.${var.ingress_domain}| 72 | 73 | ## What is not included right now 74 | 75 | - Email integration 76 | - DNS integration 77 | - Alert rules 78 | - Resource limits 79 | - CI & CD integration 80 | - Network policies 81 | - Host-based pod segregation 82 | 83 | ## Dependencies 84 | 85 | - terraform 86 | - aws cli 87 | - kubectl 88 | - [terraform-aws-eks](https://github.com/terraform-aws-modules/terraform-aws-eks) 89 | - [aws-ia/eks-blueprints-addons/aws](https://github.com/aws-ia/terraform-aws-eks-blueprints-addons) 90 | 91 | This module contains a local-exec block with `kubectl patch` for applying `tolerations` and `nodeSelector` deployments in the `kube-system` namespace, which will only work in a Unix shell, and will fail on Windows. This patch is necessary as some EKS addons currently don't support `tolerations` and `nodeSelector` in their configurations, but it is only necessary if you use host nodes with taints to separate `management` processes from others. You can disable it by setting the `apply_kubectl_patch` variable to `false`. 92 | 93 | ## Example 94 | 95 | ``` 96 | cd example 97 | terraform init 98 | terraform apply -target=module.vpc 99 | terraform apply 100 | terraform output all 101 | ``` 102 | 103 | To destroy everything, run (you may need to run it twice): 104 | ``` 105 | terraform destroy -auto-approve 106 | ``` 107 | 108 | Force destroy in case of problems: 109 | ``` 110 | helm ls -a --all-namespaces | awk 'NR > 1 { print "-n "$2, $1}' | xargs -L1 helm delete 111 | kubectl delete all --all --all-namespaces 112 | terraform destroy -auto-approve 113 | ``` 114 | 115 | After `terraform destroy`, check EC2 volumes for unused disks as the aws-ebs-csi-driver doesn't delete them by default after deleting helm releases. 116 | 117 | ## Security 118 | 119 | `victoria-metrics-k8s-stack` is deployed without internal password protection. Multiple charts such as `apisix`, `qryn`, and `uptrace` contain explicit passwords in the values and do not use Kubernetes secrets. 120 | 121 | ## Upgrading Process 122 | 123 | Helm upgrade `reset_values` flag is set to `true` for everything except databases like PostgreSQL and Clickhouse. See this [explanation](https://shipmight.com/blog/understanding-helm-upgrade-reset-reuse-values). 124 | 125 | ## Outputs 126 | 127 | Check the [./example/outputs.example](./example/outputs.example) file to get an example of the output. For setting DNS, you can describe the ingress external address with `kubectl`: 128 | ``` 129 | kubectl get service/apisix-ingress-controller-apisix-gateway -n ingress-apisix 130 | ``` 131 | 132 | Additionally, a kubeconfig file `~/.kube/eks-${account_id}-${region}-${cluster_name}` will be created by the `aws eks` utility. 133 | 134 | ## Support 135 | 136 | You can support this or any other of my projects: 137 | - [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/filipp_frizzy) 138 | - [donationalerts.com/r/filipp_frizzy](https://www.donationalerts.com/r/filipp_frizzy) 139 | - ETH 0xCD9fC1719b9E174E911f343CA2B391060F931ff7 140 | - BTC bc1q8fhsj24f5ncv3995zk9v3jhwwmscecc6w0tdw3 141 | -------------------------------------------------------------------------------- /example/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/hashicorp/aws" { 5 | version = "5.50.0" 6 | constraints = ">= 4.0.0, >= 4.33.0, >= 4.36.0, >= 4.47.0, >= 4.57.0, >= 5.0.0" 7 | hashes = [ 8 | "h1:OE1Q924lUL15OytvxwkdIspPsLRe0m2044W55j3lihE=", 9 | "zh:19be42f5a545d6712dee4bdb704b018d23bacf5d902ac3cb061eb1750dfe6a20", 10 | "zh:1d880bdba95ce96efde37e5bcf457a57df2c1effa9b47bc67fa29c1a264ae53b", 11 | "zh:1e9c78e324d7492be5e7744436ed71d66fe4eca3fb6af07a28efd0d1e3bf7640", 12 | "zh:27ac672aa61b3795931561fdbe4a306ad1132af517d7711c14569429b2cc694f", 13 | "zh:3b978423dead02f9a98d25de118adf264a2331acdc4550ea93bed01feabc12e7", 14 | "zh:490d7eb4b922ba1b57e0ab8dec1a08df6517485febcab1e091fd6011281c3472", 15 | "zh:64e7c84e18dac1af5778d6f516e01a46f9c91d710867c39fbc7efa3cd972dc62", 16 | "zh:73867ac2956dcdd377121b3aa8fe2e1085e77fae9b61d018f56a863277ea4b6e", 17 | "zh:7ed899d0d5c49f009b445d7816e4bf702d9c48205c24cf884cd2ae0247160455", 18 | "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", 19 | "zh:9b93784b3fb13d08cf95a4131c49b56bf7e1cd35daad6156b3658a89ce6fb58f", 20 | "zh:b29d77eb75de474e46eb47e539c48916628d85599bcf14e5cc500b14a4578e75", 21 | "zh:bbd9cec8ca705452e4a3d21d56474eacb8cc7b1b74b7f310fdea4bdcffebab32", 22 | "zh:c352eb3169efa0e27a29b99a2630e8298710a084453c519caa39e5972ff6d1fc", 23 | "zh:e32f4744b43be1708b309a734e0ac10b5c0f9f92e5849298cf1a90f2b906f6f3", 24 | ] 25 | } 26 | 27 | provider "registry.terraform.io/hashicorp/cloudinit" { 28 | version = "2.3.4" 29 | constraints = ">= 2.0.0" 30 | hashes = [ 31 | "h1:cVIIhnXweOHavu1uV2bdKScTjLbM1WnKM/25wqYBJWo=", 32 | "zh:09f1f1e1d232da96fbf9513b0fb5263bc2fe9bee85697aa15d40bb93835efbeb", 33 | "zh:381e74b90d7a038c3a8dcdcc2ce8c72d6b86da9f208a27f4b98cabe1a1032773", 34 | "zh:398eb321949e28c4c5f7c52e9b1f922a10d0b2b073b7db04cb69318d24ffc5a9", 35 | "zh:4a425679614a8f0fe440845828794e609b35af17db59134c4f9e56d61e979813", 36 | "zh:4d955d8608ece4984c9f1dacda2a59fdb4ea6b0243872f049b388181aab8c80a", 37 | "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", 38 | "zh:a48fbee1d58d55a1f4c92c2f38c83a37c8b2f2701ed1a3c926cefb0801fa446a", 39 | "zh:b748fe6631b16a1dafd35a09377c3bffa89552af584cf95f47568b6cd31fc241", 40 | "zh:d4b931f7a54603fa4692a2ec6e498b95464babd2be072bed5c7c2e140a280d99", 41 | "zh:f1c9337fcfe3a7be39d179eb7986c22a979cfb2c587c05f1b3b83064f41785c5", 42 | "zh:f58fc57edd1ee3250a28943cd84de3e4b744cdb52df0356a53403fc240240636", 43 | "zh:f5f50de0923ff530b03e1bca0ac697534d61bb3e5fc7f60e13becb62229097a9", 44 | ] 45 | } 46 | 47 | provider "registry.terraform.io/hashicorp/helm" { 48 | version = "2.13.2" 49 | constraints = ">= 2.9.0" 50 | hashes = [ 51 | "h1:nlSqCo0PajJzjSlx0lXNUq1YcOr8p9b3ahcUUYN2pEg=", 52 | "zh:06c0663031ef5aa19e238fe50be5d3cbf5fb00548d2b26e779c607dfd2dc69a7", 53 | "zh:1850b8f2e729553ba8b96d69dce035b814ce959c6805c25484f407c4e720c497", 54 | "zh:1ec76814a99461cd79ee4c879ed455ab338a3cb9e63fbe9308f91b5515e72e42", 55 | "zh:78546b2f0b2e9072370c017d8056a2ffda908c2e463d2792244e4be6562ab772", 56 | "zh:9205eef438aa3d5e49505655b7c300f7cecfa30f8fa37ed84679f674420403f2", 57 | "zh:9335c7300675e5088ab4090af3c8150701c0bb8ea67ad23ebd753f6ab3a922a9", 58 | "zh:9722d8b419e9615a04b8fc9acb50e52d6ba988c7565cc517bc16faa0a9e895b3", 59 | "zh:aa93d9fc7db91f261b6e41970453926341eaa4222c1b8d507cdeabd0be0af4eb", 60 | "zh:c59a2af538de99c37e4ffe988f33633a9fb064e5360230adac5f6eb0fd473be8", 61 | "zh:d6323f61f255131a7d9f5a645982eb0f0d12f685270f54beade95c0b51a7a6c9", 62 | "zh:e7f46dd2aac9537d20aaac217806f2ebb3a347aaf6bbd28192c042286103635c", 63 | "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", 64 | ] 65 | } 66 | 67 | provider "registry.terraform.io/hashicorp/kubernetes" { 68 | version = "2.30.0" 69 | constraints = ">= 2.10.0, >= 2.20.0" 70 | hashes = [ 71 | "h1:wRVWY3sK32BNInDOlQnoGSmL638f3jjLFypCAotwpc8=", 72 | "zh:06531333a72fe6d2829f37a328e08a3fc4ed66226344a003b62418a834ac6c69", 73 | "zh:34480263939ef5007ce65c9f4945df5cab363f91e5260ae552bcd9f2ffeed444", 74 | "zh:59e71f9177da570c33507c44828288264c082d512138c5755800f2cd706c62bc", 75 | "zh:6e979b0c07326f9c8d1999096a920322d22261ca61d346b3a9775283d00a2fa5", 76 | "zh:73e3f228de0077b5c0a84ec5b1ada507fbb3456cba35a6b5758723f77715b7af", 77 | "zh:79e0de985159c056f001cc47a654620d51f5d55f554bcbcde1fe7d52f667db40", 78 | "zh:8accb9100f609377db42e3ced42cc9d5c36065a06644dfb21d3893bb8d4797fd", 79 | "zh:9f99aa0bf5caa4223a7dbf5d22d71c16083e782c4eea4b0130abfd6e6f1cec18", 80 | "zh:bcb2ad76ad05ec23f8da62231a2360d1f70bbcd28abd06b8458a9e2f17da7873", 81 | "zh:bce317d7790c2d3c4e724726dc78070db28daf7d861faa646fc891fe28842a29", 82 | "zh:ed0a8e7fa8a1c419a19840b421d18200c3a63cf16ccbcbc400cb375d5397f615", 83 | "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", 84 | ] 85 | } 86 | 87 | provider "registry.terraform.io/hashicorp/null" { 88 | version = "3.2.2" 89 | hashes = [ 90 | "h1:zT1ZbegaAYHwQa+QwIFugArWikRJI9dqohj8xb0GY88=", 91 | "zh:3248aae6a2198f3ec8394218d05bd5e42be59f43a3a7c0b71c66ec0df08b69e7", 92 | "zh:32b1aaa1c3013d33c245493f4a65465eab9436b454d250102729321a44c8ab9a", 93 | "zh:38eff7e470acb48f66380a73a5c7cdd76cc9b9c9ba9a7249c7991488abe22fe3", 94 | "zh:4c2f1faee67af104f5f9e711c4574ff4d298afaa8a420680b0cb55d7bbc65606", 95 | "zh:544b33b757c0b954dbb87db83a5ad921edd61f02f1dc86c6186a5ea86465b546", 96 | "zh:696cf785090e1e8cf1587499516b0494f47413b43cb99877ad97f5d0de3dc539", 97 | "zh:6e301f34757b5d265ae44467d95306d61bef5e41930be1365f5a8dcf80f59452", 98 | "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", 99 | "zh:913a929070c819e59e94bb37a2a253c228f83921136ff4a7aa1a178c7cce5422", 100 | "zh:aa9015926cd152425dbf86d1abdbc74bfe0e1ba3d26b3db35051d7b9ca9f72ae", 101 | "zh:bb04798b016e1e1d49bcc76d62c53b56c88c63d6f2dfe38821afef17c416a0e1", 102 | "zh:c23084e1b23577de22603cff752e59128d83cfecc2e6819edadd8cf7a10af11e", 103 | ] 104 | } 105 | 106 | provider "registry.terraform.io/hashicorp/random" { 107 | version = "3.6.1" 108 | hashes = [ 109 | "h1:1OlP753r4lOKlBprL0HdZGWerm5DCabD5Mli8k8lWAg=", 110 | "zh:2a0ec154e39911f19c8214acd6241e469157489fc56b6c739f45fbed5896a176", 111 | "zh:57f4e553224a5e849c99131f5e5294be3a7adcabe2d867d8a4fef8d0976e0e52", 112 | "zh:58f09948c608e601bd9d0a9e47dcb78e2b2c13b4bda4d8f097d09152ea9e91c5", 113 | "zh:5c2a297146ed6fb3fe934c800e78380f700f49ff24dbb5fb5463134948e3a65f", 114 | "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", 115 | "zh:7ce41e26f0603e31cdac849085fc99e5cd5b3b73414c6c6d955c0ceb249b593f", 116 | "zh:8c9e8d30c4ef08ee8bcc4294dbf3c2115cd7d9049c6ba21422bd3471d92faf8a", 117 | "zh:93e91be717a7ffbd6410120eb925ebb8658cc8f563de35a8b53804d33c51c8b0", 118 | "zh:982542e921970d727ce10ed64795bf36c4dec77a5db0741d4665230d12250a0d", 119 | "zh:b9d1873f14d6033e216510ef541c891f44d249464f13cc07d3f782d09c7d18de", 120 | "zh:cfe27faa0bc9556391c8803ade135a5856c34a3fe85b9ae3bdd515013c0c87c1", 121 | "zh:e4aabf3184bbb556b89e4b195eab1514c86a2914dd01c23ad9813ec17e863a8a", 122 | ] 123 | } 124 | 125 | provider "registry.terraform.io/hashicorp/time" { 126 | version = "0.11.1" 127 | constraints = ">= 0.9.0" 128 | hashes = [ 129 | "h1:IkDriv5C9G+kQQ+mP+8QGIahwKgbQcw1/mzh9U6q+ZI=", 130 | "zh:19a393db736ec4fd024d098d55aefaef07056c37a448ece3b55b3f5f4c2c7e4a", 131 | "zh:227fa1e221de2907f37be78d40c06ca6a6f7b243a1ec33ade014dfaf6d92cd9c", 132 | "zh:29970fecbf4a3ca23bacbb05d6b90cdd33dd379f90059fe39e08289951502d9f", 133 | "zh:65024596f22f10e7dcb5e0e4a75277f275b529daa0bc0daf34ca7901c678ab88", 134 | "zh:694d080cb5e3bf5ef08c7409208d061c135a4f5f4cdc93ea8607860995264b2e", 135 | "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", 136 | "zh:b29d15d13e1b3412e6a4e1627d378dbd102659132f7488f64017dd6b6d5216d3", 137 | "zh:bb79f4cae9f8c17c73998edc54aa16c2130a03227f7f4e71fc6ac87e230575ec", 138 | "zh:ceccf80e95929d97f62dcf1bb3c7c7553d5757b2d9e7d222518722fc934f7ad5", 139 | "zh:f40e638336527490e294d9c938ae55919069e6987e85a80506784ba90348792a", 140 | "zh:f99ef33b1629a3b2278201142a3011a8489e66d92da832a5b99e442204de18fb", 141 | "zh:fded14754ea46fdecc62a52cd970126420d4cd190e598cb61190b4724a727edb", 142 | ] 143 | } 144 | 145 | provider "registry.terraform.io/hashicorp/tls" { 146 | version = "4.0.5" 147 | constraints = ">= 3.0.0" 148 | hashes = [ 149 | "h1:e4LBdJoZJNOQXPWgOAG0UuPBVhCStu98PieNlqJTmeU=", 150 | "zh:01cfb11cb74654c003f6d4e32bbef8f5969ee2856394a96d127da4949c65153e", 151 | "zh:0472ea1574026aa1e8ca82bb6df2c40cd0478e9336b7a8a64e652119a2fa4f32", 152 | "zh:1a8ddba2b1550c5d02003ea5d6cdda2eef6870ece86c5619f33edd699c9dc14b", 153 | "zh:1e3bb505c000adb12cdf60af5b08f0ed68bc3955b0d4d4a126db5ca4d429eb4a", 154 | "zh:6636401b2463c25e03e68a6b786acf91a311c78444b1dc4f97c539f9f78de22a", 155 | "zh:76858f9d8b460e7b2a338c477671d07286b0d287fd2d2e3214030ae8f61dd56e", 156 | "zh:a13b69fb43cb8746793b3069c4d897bb18f454290b496f19d03c3387d1c9a2dc", 157 | "zh:a90ca81bb9bb509063b736842250ecff0f886a91baae8de65c8430168001dad9", 158 | "zh:c4de401395936e41234f1956ebadbd2ed9f414e6908f27d578614aaa529870d4", 159 | "zh:c657e121af8fde19964482997f0de2d5173217274f6997e16389e7707ed8ece8", 160 | "zh:d68b07a67fbd604c38ec9733069fbf23441436fecf554de6c75c032f82e1ef19", 161 | "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", 162 | ] 163 | } 164 | -------------------------------------------------------------------------------- /example/main.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = "us-east-2" 3 | } 4 | 5 | data "aws_region" "current" {} 6 | 7 | locals { 8 | cluster_name = "test" 9 | admin_email = "test@test.com" 10 | ingress_domain = "cluster.local" 11 | ingress_class_name = "apisix" # or "nginx" 12 | cert_manager_issuer = "" # you can set to "letsencrypt-staging" or "letsencrypt-prod" after configuring dns records 13 | 14 | cluster_version = "1.29" 15 | 16 | vpc_name = "eks_${local.cluster_name}" 17 | azs = data.aws_availability_zones.available.names 18 | cidr = "10.0.0.0/16" 19 | public_subnet_suffix = "public" 20 | private_subnet_suffix = "private" 21 | 22 | # you can limit number of used availability zones, min 2 is required by eks 23 | number_of_multi_az = length(local.azs) 24 | 25 | # Limit number of availability zones in generating from templates. 26 | # Could be from 0 and up to ${number_of_multi_az} 27 | # In given example 2 AZ would be used for each node group for fault tolerance. 28 | # The price for that would be to pay for multi AZ traffic 29 | self_managed_node_group_number_of_multi_az = 2 30 | eks_managed_node_group_number_of_multi_az = 2 31 | fargate_profile_number_of_multi_az = 2 32 | 33 | # you can use templates for generating node groups and fargate profiles 34 | # one per each availability zone, limited by *number_of_multi_az variables 35 | self_managed_node_group_templates_for_multi_az = {} 36 | 37 | eks_managed_node_group_templates_for_multi_az = { 38 | management = { 39 | min_size = 1 40 | desired_size = 1 41 | max_size = 3 42 | 43 | instance_types = ["m6a.large"] # 2cpu 8gb ram 63$\mo https://instances.vantage.sh/aws/ec2/m6a.large 44 | 45 | labels = { 46 | "node.kubernetes.io/purpose" = "management" 47 | } 48 | 49 | # multiple pods don't have tolerations yet 50 | # including snapshot-controller plugin that can't be changed at all 51 | # taints = { 52 | # purpose = { 53 | # key = "node.kubernetes.io/purpose" 54 | # value = "management" 55 | # effect = "NO_SCHEDULE" 56 | # } 57 | # } 58 | 59 | } 60 | } 61 | 62 | # Disable this as coredns and some other addons 63 | # had untolerated taint {eks.amazonaws.com/compute-type: fargate}. 64 | # Also EKS has quote for 10 fargate profiles by default. 65 | # And also all fargate instances was started in one AZ instead of splitting by AZs 66 | fargate_profile_templates_for_multi_az = { 67 | # default = {} 68 | # kube-system = {} 69 | # kube-node-lease = {} 70 | # kube-public = {} 71 | # cert-manager = {} 72 | # external-dns = {} 73 | # external-secrets = {} 74 | # vpa = {} 75 | # aws-node-termination-handler = {} 76 | } 77 | 78 | # Groups in all cluster networks and availability zones 79 | self_managed_node_groups = { 80 | # nth_test = { 81 | # min_size = 0 82 | # desired_size = 0 83 | # max_size = 1 84 | # instance_types = ["t3.nano"] 85 | # } 86 | } 87 | eks_managed_node_groups = {} 88 | fargate_profiles = {} 89 | 90 | tags = { 91 | Environment = "test" 92 | EKS = local.cluster_name 93 | Terraform = "true" 94 | } 95 | 96 | } 97 | 98 | data "aws_availability_zones" "available" {} 99 | 100 | # https://github.com/terraform-aws-modules/terraform-aws-vpc/tree/master 101 | module "vpc" { 102 | source = "terraform-aws-modules/vpc/aws" 103 | 104 | name = local.vpc_name 105 | cidr = local.cidr 106 | 107 | azs = local.azs 108 | public_subnets = [for k, v in local.azs : cidrsubnet(local.cidr, 8, k*2)] 109 | private_subnets = [for k, v in local.azs : cidrsubnet(local.cidr, 8, k*2+1)] 110 | 111 | public_subnet_suffix = local.public_subnet_suffix 112 | private_subnet_suffix = local.private_subnet_suffix 113 | 114 | # using for filter private subnets 115 | map_public_ip_on_launch = true 116 | 117 | enable_nat_gateway = true 118 | single_nat_gateway = false 119 | one_nat_gateway_per_az = true 120 | 121 | enable_vpn_gateway = false 122 | 123 | tags = local.tags 124 | } 125 | 126 | resource "aws_vpc_endpoint" "s3" { 127 | vpc_id = module.vpc.vpc_id 128 | service_name = "com.amazonaws.${data.aws_region.current.name}.s3" 129 | route_table_ids = concat( 130 | module.vpc.public_route_table_ids, 131 | module.vpc.private_route_table_ids, 132 | module.vpc.intra_route_table_ids 133 | ) 134 | 135 | tags = merge( 136 | local.tags, 137 | { 138 | Name = "${module.vpc.vpc_id} S3 Gateway Endpoint" 139 | } 140 | ) 141 | } 142 | 143 | module "eks" { 144 | # source = "../" 145 | source = "github.com/tldr-devops/aws-eks-terraform?ref=1.2" 146 | 147 | cluster_name = local.cluster_name 148 | cluster_version = local.cluster_version 149 | admin_email = local.admin_email 150 | ingress_domain = local.ingress_domain 151 | ingress_class_name = local.ingress_class_name 152 | cert_manager_issuer = local.cert_manager_issuer 153 | vpc_id = module.vpc.vpc_id 154 | number_of_multi_az = local.number_of_multi_az 155 | self_managed_node_group_number_of_multi_az = local.self_managed_node_group_number_of_multi_az 156 | eks_managed_node_group_number_of_multi_az = local.eks_managed_node_group_number_of_multi_az 157 | fargate_profile_number_of_multi_az = local.fargate_profile_number_of_multi_az 158 | self_managed_node_group_templates_for_multi_az = local.self_managed_node_group_templates_for_multi_az 159 | eks_managed_node_group_templates_for_multi_az = local.eks_managed_node_group_templates_for_multi_az 160 | fargate_profile_templates_for_multi_az = local.fargate_profile_templates_for_multi_az 161 | self_managed_node_groups = local.self_managed_node_groups 162 | eks_managed_node_groups = local.eks_managed_node_groups 163 | fargate_profiles = local.fargate_profiles 164 | tags = local.tags 165 | 166 | enable_aws_efs_csi_driver = true 167 | enable_aws_node_termination_handler = true 168 | enable_cert_manager = true 169 | enable_cluster_autoscaler = true 170 | enable_metrics_server = true 171 | enable_vpa = true 172 | enable_ingress_apisix = true 173 | enable_ingress_nginx = false 174 | enable_victoriametrics_operator = true 175 | enable_opentelemetry_operator = false 176 | enable_clickhouse_operator = false 177 | enable_grafana_operator = true 178 | enable_victoriametrics = true 179 | enable_grafana = true 180 | enable_uptrace = true 181 | enable_vector_agent = true 182 | enable_qryn = false 183 | enable_openobserve = false 184 | enable_openobserve_collector = false 185 | enable_kubernetes_dashboard = false 186 | 187 | 188 | # disable versions for install latest one 189 | # and then set it from the terraform output 190 | # to prevent unplanned upgrades 191 | 192 | eks_addons = { 193 | coredns = {addon_version = "v1.11.1-eksbuild.9"} 194 | kube-proxy = {addon_version = "v1.29.3-eksbuild.2"} 195 | vpc-cni = {addon_version = "v1.18.1-eksbuild.3"} 196 | aws-ebs-csi-driver = {addon_version = "v1.30.0-eksbuild.1"} 197 | snapshot-controller = {addon_version = "v7.0.1-eksbuild.1"} 198 | } 199 | 200 | aws_efs_csi_driver_config = {chart_version = "3.0.3"} 201 | aws_node_termination_handler_config = {chart_version = "0.21.0"} 202 | cert_manager_config = {chart_version = "v1.14.5"} 203 | cluster_autoscaler_config = {chart_version = "9.37.0"} 204 | metrics_server_config = {chart_version = "3.12.1"} 205 | vpa_config = {chart_version = "4.4.6"} 206 | 207 | ingress_apisix_chart_version = "0.14.0" 208 | ingress_nginx_chart_version = "4.10.1" 209 | victoriametrics_operator_chart_version = "0.31.2" 210 | opentelemetry_operator_chart_version = "0.58.2" 211 | clickhouse_operator_chart_version = "0.23.5" 212 | grafana_operator_chart_version = "4.2.4" 213 | victoriametrics_chart_version = "0.22.1" 214 | victoriametrics_auth_chart_version = "0.4.12" 215 | grafana_chart_version = "7.3.11" 216 | uptrace_chart_version = "1.7.4" 217 | uptrace_clickhouse_chart_version = "6.0.7" 218 | uptrace_postgresql_chart_version = "15.3.3" 219 | qryn_chart_version = "0.1.1" 220 | qryn_clickhouse_chart_version = "6.0.7" 221 | vector_agent_chart_version = "0.33.0" 222 | openobserve_chart_name = "0.10.5" 223 | openobserve_collector_chart_version = "0.3.6" 224 | kubernetes_dashboard_chart_version = "7.4.0" 225 | } 226 | -------------------------------------------------------------------------------- /example/outputs.tf: -------------------------------------------------------------------------------- 1 | output "all" { 2 | value = module.eks 3 | sensitive = true 4 | } 5 | -------------------------------------------------------------------------------- /example/top.example: -------------------------------------------------------------------------------- 1 | $ kubectl top node 2 | NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% 3 | ip-10-0-1-18.us-east-2.compute.internal 1420m 73% 2866Mi 40% 4 | ip-10-0-3-81.us-east-2.compute.internal 421m 21% 2070Mi 29% 5 | 6 | $ kubectl top pod --all-namespaces 7 | NAMESPACE NAME CPU(cores) MEMORY(bytes) 8 | cert-manager cert-manager-796cbd6574-2t4ck 1m 21Mi 9 | cert-manager cert-manager-cainjector-6b6c9ff467-vfxzm 2m 40Mi 10 | cert-manager cert-manager-webhook-d969fd76f-vxwzz 1m 8Mi 11 | clickhouse altinity-clickhouse-operator-6c64dbbd87-lfl82 1m 17Mi 12 | ingress-apisix apisix-ingress-controller-75579d89db-rlzjq 4m 89Mi 13 | kube-system aws-node-hrd4s 4m 60Mi 14 | kube-system aws-node-msngk 4m 60Mi 15 | kube-system cluster-autoscaler-aws-cluster-autoscaler-69b4dcd58f-q5drj 2m 34Mi 16 | kube-system coredns-656f8bb969-gl8j2 2m 16Mi 17 | kube-system coredns-656f8bb969-lm69l 2m 15Mi 18 | kube-system ebs-csi-controller-7f8c48d5b9-6gttw 2m 47Mi 19 | kube-system ebs-csi-controller-7f8c48d5b9-rv7zk 2m 53Mi 20 | kube-system ebs-csi-node-6s7b6 1m 19Mi 21 | kube-system ebs-csi-node-czdzb 1m 19Mi 22 | kube-system efs-csi-controller-7c77bfcd6b-bkwx9 2m 42Mi 23 | kube-system efs-csi-controller-7c77bfcd6b-fp5tz 2m 40Mi 24 | kube-system efs-csi-node-hzdbf 3m 41Mi 25 | kube-system efs-csi-node-w64r7 3m 39Mi 26 | kube-system kube-proxy-j4z7p 1m 14Mi 27 | kube-system kube-proxy-vt95s 1m 15Mi 28 | kube-system metrics-server-b7f8d757d-6tjgm 4m 19Mi 29 | kube-system snapshot-controller-85bbdcdf64-4jnct 1m 6Mi 30 | kube-system snapshot-controller-85bbdcdf64-6rz7p 1m 7Mi 31 | kubernetes-dashboard kubernetes-dashboard-api-7ff949576d-4knct 1m 8Mi 32 | kubernetes-dashboard kubernetes-dashboard-auth-7b6cfb784d-vdcsk 1m 7Mi 33 | kubernetes-dashboard kubernetes-dashboard-kong-75bb76dd5f-tvgm9 2m 74Mi 34 | kubernetes-dashboard kubernetes-dashboard-metrics-scraper-7f6f977dc9-pp8sl 1m 7Mi 35 | kubernetes-dashboard kubernetes-dashboard-web-7cccf8c454-x75gm 0m 7Mi 36 | monitoring grafana-6fbfd67f58-whkmm 3m 47Mi 37 | monitoring grafana-operator-67db8569bd-pg6sb 2m 28Mi 38 | monitoring opentelemetry-operator-769898647b-2nqhr 1m 31Mi 39 | monitoring qryn-clickhouse-shard0-0 422m 459Mi 40 | monitoring qryn-helm-877cc59c-cds4d 2m 113Mi 41 | monitoring qryn-helm-877cc59c-dclxn 2m 104Mi 42 | monitoring qryn-helm-877cc59c-lv4zk 952m 449Mi 43 | monitoring qryn-helm-877cc59c-tnsbj 2m 114Mi 44 | monitoring qryn-helm-877cc59c-trh4b 2m 115Mi 45 | monitoring uptrace-0 132m 125Mi 46 | monitoring uptrace-clickhouse-shard0-0 640m 609Mi 47 | monitoring uptrace-postgresql-0 6m 41Mi 48 | monitoring vector-77h76 6m 26Mi 49 | monitoring vector-vznj2 2m 29Mi 50 | monitoring victoria-metrics-auth-574d6768dc-zhbgv 1m 4Mi 51 | monitoring victoria-metrics-k8s-stack-kube-state-metrics-889cfcf97-9rfrk 3m 14Mi 52 | monitoring victoria-metrics-k8s-stack-prometheus-node-exporter-c85sm 1m 7Mi 53 | monitoring victoria-metrics-k8s-stack-prometheus-node-exporter-cd9vk 1m 7Mi 54 | monitoring victoria-metrics-operator-677fdb8948-bv9kx 2m 21Mi 55 | monitoring vmagent-victoria-metrics-k8s-stack-6d4655df46-67pv6 50m 125Mi 56 | monitoring vmalert-victoria-metrics-k8s-stack-6b9496f4f-6dxd5 17m 21Mi 57 | monitoring vmalertmanager-victoria-metrics-k8s-stack-0 1m 23Mi 58 | monitoring vmsingle-victoria-metrics-k8s-stack-59d857bcd4-4z8gl 54m 249Mi 59 | vpa vpa-admission-controller-7ffd6d94f9-l6l7x 1m 11Mi 60 | vpa vpa-recommender-75bf5fbc55-g9fmw 1m 14Mi 61 | vpa vpa-updater-64c774dbb6-mjk28 1m 16Mi 62 | -------------------------------------------------------------------------------- /modules/apisix/main.tf: -------------------------------------------------------------------------------- 1 | # https://github.com/apache/apisix-ingress-controller/blob/master/docs/en/latest/deployments/aws.md 2 | # https://docs.google.com/spreadsheets/d/191WWNpjJ2za6-nbG4ZoUMXMpUK8KlCIosvQB0f-oq3k/edit#gid=907731238 3 | # https://github.com/apache/apisix-helm-chart/blob/master/charts/apisix-ingress-controller/values.yaml 4 | 5 | # https://apisix.apache.org/docs/ingress-controller/getting-started/ 6 | # https://navendu.me/series/hands-on-with-apache-apisix-ingress/ 7 | 8 | locals { 9 | # https://github.com/apache/apisix-helm-chart/blob/master/charts/apisix-ingress-controller/values.yaml 10 | values = [ 11 | <<-EOT 12 | config: 13 | etcdserver: 14 | enabled: true 15 | apisix: 16 | # -- Enabling this value, overrides serviceName and serviceNamespace. 17 | clusterName: "default" 18 | # -- the APISIX admin API version. can be "v2" or "v3", default is "v2". 19 | adminAPIVersion: "v2" 20 | # -- The APISIX Helm chart supports storing user credentials in a secret. 21 | # The secret needs to contain a single key for admin token with key adminKey by default. 22 | existingSecret: "apisix-admin-password" 23 | gateway: 24 | # -- Apache APISIX service type for user access itself 25 | type: LoadBalancer 26 | annotations: 27 | service.beta.kubernetes.io/aws-load-balancer-type: nlb 28 | tls: 29 | enabled: true 30 | EOT 31 | ] 32 | set = [] 33 | } 34 | 35 | resource "random_password" "apisix_admin_key" { 36 | length = 32 37 | special = false 38 | } 39 | 40 | module "kubernetes_manifests" { 41 | source = "../kubernetes-manifests" 42 | 43 | create = var.create 44 | name = "apisix-manifests" 45 | namespace = var.namespace 46 | tags = var.tags 47 | 48 | values = [ 49 | <<-EOT 50 | resources: 51 | - kind: Secret 52 | apiVersion: v1 53 | metadata: 54 | name: "apisix-admin-password" 55 | namespace: "${var.namespace}" 56 | stringData: 57 | adminKey: "${random_password.apisix_admin_key.result}" 58 | type: Opaque 59 | EOT 60 | ] 61 | } 62 | 63 | module "ingress_apisix" { 64 | source = "aws-ia/eks-blueprints-addon/aws" 65 | version = "~> 1.1" 66 | 67 | set = concat( 68 | local.set, 69 | var.set 70 | ) 71 | 72 | values = concat( 73 | local.values, 74 | var.values 75 | ) 76 | 77 | create = var.create 78 | tags = var.tags 79 | create_release = var.create_release 80 | name = var.name 81 | description = var.description 82 | namespace = var.namespace 83 | create_namespace = var.create_namespace 84 | chart = var.chart 85 | chart_version = var.chart_version 86 | repository = var.repository 87 | timeout = var.timeout 88 | repository_key_file = var.repository_key_file 89 | repository_cert_file = var.repository_cert_file 90 | repository_ca_file = var.repository_ca_file 91 | repository_username = var.repository_username 92 | repository_password = var.repository_password 93 | devel = var.devel 94 | verify = var.verify 95 | keyring = var.keyring 96 | disable_webhooks = var.disable_webhooks 97 | reuse_values = var.reuse_values 98 | reset_values = var.reset_values 99 | force_update = var.force_update 100 | recreate_pods = var.recreate_pods 101 | cleanup_on_fail = var.cleanup_on_fail 102 | max_history = var.max_history 103 | atomic = var.atomic 104 | skip_crds = var.skip_crds 105 | render_subchart_notes = var.render_subchart_notes 106 | disable_openapi_validation = var.disable_openapi_validation 107 | wait = var.wait 108 | wait_for_jobs = var.wait_for_jobs 109 | dependency_update = var.dependency_update 110 | replace = var.replace 111 | lint = var.lint 112 | postrender = var.postrender 113 | set_sensitive = var.set_sensitive 114 | set_irsa_names = var.set_irsa_names 115 | create_role = var.create_role 116 | role_name = var.role_name 117 | role_name_use_prefix = var.role_name_use_prefix 118 | role_path = var.role_path 119 | role_permissions_boundary_arn = var.role_permissions_boundary_arn 120 | role_description = var.role_description 121 | role_policies = var.role_policies 122 | oidc_providers = var.oidc_providers 123 | max_session_duration = var.max_session_duration 124 | assume_role_condition_test = var.assume_role_condition_test 125 | allow_self_assume_role = var.allow_self_assume_role 126 | create_policy = var.create_policy 127 | source_policy_documents = var.source_policy_documents 128 | override_policy_documents = var.override_policy_documents 129 | policy_statements = var.policy_statements 130 | policy_name = var.policy_name 131 | policy_name_use_prefix = var.policy_name_use_prefix 132 | policy_path = var.policy_path 133 | policy_description = var.policy_description 134 | } 135 | -------------------------------------------------------------------------------- /modules/apisix/outputs.tf: -------------------------------------------------------------------------------- 1 | output "chart" { 2 | description = "The name of the chart" 3 | value = try(module.ingress_apisix.chart, null) 4 | } 5 | 6 | output "name" { 7 | description = "Name is the name of the release" 8 | value = try(module.ingress_apisix.name, null) 9 | } 10 | 11 | output "namespace" { 12 | description = "Name of Kubernetes namespace" 13 | value = try(module.ingress_apisix.namespace, null) 14 | } 15 | 16 | output "revision" { 17 | description = "Version is an int32 which represents the version of the release" 18 | value = try(module.ingress_apisix.revision, null) 19 | } 20 | 21 | output "version" { 22 | description = "A SemVer 2 conformant version string of the chart" 23 | value = try(module.ingress_apisix.version, null) 24 | } 25 | 26 | output "app_version" { 27 | description = "The version number of the application being deployed" 28 | value = try(module.ingress_apisix.app_version, null) 29 | } 30 | 31 | output "apisix_admin_key" { 32 | description = "The apisix admin key" 33 | value = random_password.apisix_admin_key.result 34 | } 35 | -------------------------------------------------------------------------------- /modules/apisix/variables.tf: -------------------------------------------------------------------------------- 1 | variable "create" { 2 | description = "Controls if resources should be created (affects all resources)" 3 | type = bool 4 | default = true 5 | } 6 | 7 | variable "tags" { 8 | description = "A map of tags to add to all resources" 9 | type = map(string) 10 | default = {} 11 | } 12 | 13 | ################################################################################ 14 | # Helm Release 15 | ################################################################################ 16 | 17 | variable "create_release" { 18 | description = "Determines whether the Helm release is created" 19 | type = bool 20 | default = true 21 | } 22 | 23 | variable "name" { 24 | description = "Name of the Helm release" 25 | type = string 26 | default = "" 27 | } 28 | 29 | variable "description" { 30 | description = "Set release description attribute (visible in the history)" 31 | type = string 32 | default = "Apisix ingress helm Chart deployment configuration" 33 | } 34 | 35 | variable "namespace" { 36 | description = "The namespace to install the release into. Defaults to `default`" 37 | type = string 38 | default = "ingress-apisix" 39 | } 40 | 41 | variable "create_namespace" { 42 | description = "Create the namespace if it does not yet exist. Defaults to `false`" 43 | type = bool 44 | default = true 45 | } 46 | 47 | variable "chart" { 48 | description = "Chart name to be installed. The chart name can be local path, a URL to a chart, or the name of the chart if `repository` is specified" 49 | type = string 50 | default = "apisix-ingress-controller" 51 | } 52 | 53 | variable "chart_version" { 54 | description = "Specify the exact chart version to install. If this is not specified, the latest version is installed" 55 | type = string 56 | default = null 57 | } 58 | 59 | variable "repository" { 60 | description = "Repository URL where to locate the requested chart" 61 | type = string 62 | default = "https://charts.apiseven.com" 63 | } 64 | 65 | variable "values" { 66 | description = "List of values in raw yaml to pass to helm. Values will be merged, in order, as Helm does with multiple `-f` options" 67 | type = list(string) 68 | default = null 69 | } 70 | 71 | variable "timeout" { 72 | description = "Time in seconds to wait for any individual kubernetes operation (like Jobs for hooks). Defaults to `300` seconds" 73 | type = number 74 | default = null 75 | } 76 | 77 | variable "repository_key_file" { 78 | description = "The repositories cert key file" 79 | type = string 80 | default = null 81 | } 82 | 83 | variable "repository_cert_file" { 84 | description = "The repositories cert file" 85 | type = string 86 | default = null 87 | } 88 | 89 | variable "repository_ca_file" { 90 | description = "The Repositories CA File" 91 | type = string 92 | default = null 93 | } 94 | 95 | variable "repository_username" { 96 | description = "Username for HTTP basic authentication against the repository" 97 | type = string 98 | default = null 99 | } 100 | 101 | variable "repository_password" { 102 | description = "Password for HTTP basic authentication against the repository" 103 | type = string 104 | default = null 105 | } 106 | 107 | variable "devel" { 108 | description = "Use chart development versions, too. Equivalent to version '>0.0.0-0'. If version is set, this is ignored" 109 | type = bool 110 | default = null 111 | } 112 | 113 | variable "verify" { 114 | description = "Verify the package before installing it. Helm uses a provenance file to verify the integrity of the chart; this must be hosted alongside the chart. For more information see the Helm Documentation. Defaults to `false`" 115 | type = bool 116 | default = null 117 | } 118 | 119 | variable "keyring" { 120 | description = "Location of public keys used for verification. Used only if verify is true. Defaults to `/.gnupg/pubring.gpg` in the location set by `home`" 121 | type = string 122 | default = null 123 | } 124 | 125 | variable "disable_webhooks" { 126 | description = "Prevent hooks from running. Defaults to `false`" 127 | type = bool 128 | default = null 129 | } 130 | 131 | variable "reuse_values" { 132 | description = "When upgrading, reuse the last release's values and merge in any overrides. If `reset_values` is specified, this is ignored. Defaults to `false`" 133 | type = bool 134 | default = null 135 | } 136 | 137 | variable "reset_values" { 138 | description = "When upgrading, reset the values to the ones built into the chart. Defaults to `false`" 139 | type = bool 140 | default = true 141 | } 142 | 143 | variable "force_update" { 144 | description = "Force resource update through delete/recreate if needed. Defaults to `false`" 145 | type = bool 146 | default = null 147 | } 148 | 149 | variable "recreate_pods" { 150 | description = "Perform pods restart during upgrade/rollback. Defaults to `false`" 151 | type = bool 152 | default = null 153 | } 154 | 155 | variable "cleanup_on_fail" { 156 | description = "Allow deletion of new resources created in this upgrade when upgrade fails. Defaults to `false`" 157 | type = bool 158 | default = null 159 | } 160 | 161 | variable "max_history" { 162 | description = "Maximum number of release versions stored per release. Defaults to `0` (no limit)" 163 | type = number 164 | default = null 165 | } 166 | 167 | variable "atomic" { 168 | description = "If set, installation process purges chart on fail. The wait flag will be set automatically if atomic is used. Defaults to `false`" 169 | type = bool 170 | default = null 171 | } 172 | 173 | variable "skip_crds" { 174 | description = "If set, no CRDs will be installed. By default, CRDs are installed if not already present. Defaults to `false`" 175 | type = bool 176 | default = null 177 | } 178 | 179 | variable "render_subchart_notes" { 180 | description = "If set, render subchart notes along with the parent. Defaults to `true`" 181 | type = bool 182 | default = null 183 | } 184 | 185 | variable "disable_openapi_validation" { 186 | description = "If set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema. Defaults to `false`" 187 | type = bool 188 | default = null 189 | } 190 | 191 | variable "wait" { 192 | description = "Will wait until all resources are in a ready state before marking the release as successful. If set to `true`, it will wait for as long as `timeout`. If set to `null` fallback on `300s` timeout. Defaults to `false`" 193 | type = bool 194 | default = false 195 | } 196 | 197 | variable "wait_for_jobs" { 198 | description = "If wait is enabled, will wait until all Jobs have been completed before marking the release as successful. It will wait for as long as `timeout`. Defaults to `false`" 199 | type = bool 200 | default = null 201 | } 202 | 203 | variable "dependency_update" { 204 | description = "Runs helm dependency update before installing the chart. Defaults to `false`" 205 | type = bool 206 | default = null 207 | } 208 | 209 | variable "replace" { 210 | description = "Re-use the given name, only if that name is a deleted release which remains in the history. This is unsafe in production. Defaults to `false`" 211 | type = bool 212 | default = null 213 | } 214 | 215 | variable "lint" { 216 | description = "Run the helm chart linter during the plan. Defaults to `false`" 217 | type = bool 218 | default = null 219 | } 220 | 221 | variable "postrender" { 222 | description = "Configure a command to run after helm renders the manifest which can alter the manifest contents" 223 | type = any 224 | default = {} 225 | } 226 | 227 | variable "set" { 228 | description = "Value block with custom values to be merged with the values yaml" 229 | type = any 230 | default = [] 231 | } 232 | 233 | variable "set_sensitive" { 234 | description = "Value block with custom sensitive values to be merged with the values yaml that won't be exposed in the plan's diff" 235 | type = any 236 | default = [] 237 | } 238 | 239 | variable "set_irsa_names" { 240 | description = "Value annotations name where IRSA role ARN created by module will be assigned to the `value`" 241 | type = list(string) 242 | default = [] 243 | } 244 | 245 | ################################################################################ 246 | # IAM Role for Service Account(s) (IRSA) 247 | ################################################################################ 248 | 249 | variable "create_role" { 250 | description = "Determines whether to create an IAM role" 251 | type = bool 252 | default = false 253 | } 254 | 255 | variable "role_name" { 256 | description = "Name of IAM role" 257 | type = string 258 | default = null 259 | } 260 | 261 | variable "role_name_use_prefix" { 262 | description = "Determines whether the IAM role name (`role_name`) is used as a prefix" 263 | type = bool 264 | default = true 265 | } 266 | 267 | variable "role_path" { 268 | description = "Path of IAM role" 269 | type = string 270 | default = "/" 271 | } 272 | 273 | variable "role_permissions_boundary_arn" { 274 | description = "Permissions boundary ARN to use for IAM role" 275 | type = string 276 | default = null 277 | } 278 | 279 | variable "role_description" { 280 | description = "IAM Role description" 281 | type = string 282 | default = null 283 | } 284 | 285 | variable "role_policies" { 286 | description = "Policies to attach to the IAM role in `{'static_name' = 'policy_arn'}` format" 287 | type = map(string) 288 | default = {} 289 | } 290 | 291 | variable "oidc_providers" { 292 | description = "Map of OIDC providers where each provider map should contain the `provider_arn`, and `service_accounts`" 293 | type = any 294 | default = {} 295 | } 296 | 297 | variable "max_session_duration" { 298 | description = "Maximum CLI/API session duration in seconds between 3600 and 43200" 299 | type = number 300 | default = null 301 | } 302 | 303 | variable "assume_role_condition_test" { 304 | description = "Name of the [IAM condition operator](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html) to evaluate when assuming the role" 305 | type = string 306 | default = "StringEquals" 307 | } 308 | 309 | variable "allow_self_assume_role" { 310 | description = "Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/)" 311 | type = bool 312 | default = false 313 | } 314 | 315 | ################################################################################ 316 | # IAM Policy 317 | ################################################################################ 318 | 319 | variable "create_policy" { 320 | description = "Whether to create an IAM policy that is attached to the IAM role created" 321 | type = bool 322 | default = true 323 | } 324 | 325 | variable "source_policy_documents" { 326 | description = "List of IAM policy documents that are merged together into the exported document. Statements must have unique `sid`s" 327 | type = list(string) 328 | default = [] 329 | } 330 | 331 | variable "override_policy_documents" { 332 | description = "List of IAM policy documents that are merged together into the exported document. In merging, statements with non-blank `sid`s will override statements with the same `sid`" 333 | type = list(string) 334 | default = [] 335 | } 336 | 337 | variable "policy_statements" { 338 | description = "List of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement)" 339 | type = any 340 | default = [] 341 | } 342 | 343 | variable "policy_name" { 344 | description = "Name of IAM policy" 345 | type = string 346 | default = null 347 | } 348 | 349 | variable "policy_name_use_prefix" { 350 | description = "Determines whether the IAM policy name (`policy_name`) is used as a prefix" 351 | type = bool 352 | default = true 353 | } 354 | 355 | variable "policy_path" { 356 | description = "Path of IAM policy" 357 | type = string 358 | default = null 359 | } 360 | 361 | variable "policy_description" { 362 | description = "IAM policy description" 363 | type = string 364 | default = null 365 | } 366 | -------------------------------------------------------------------------------- /modules/clickhouse-operator/main.tf: -------------------------------------------------------------------------------- 1 | module "clickhouse_operator" { 2 | source = "aws-ia/eks-blueprints-addon/aws" 3 | version = "~> 1.1" 4 | 5 | set = var.set 6 | 7 | create = var.create 8 | tags = var.tags 9 | create_release = var.create_release 10 | name = var.name 11 | description = var.description 12 | namespace = var.namespace 13 | create_namespace = var.create_namespace 14 | chart = var.chart 15 | chart_version = var.chart_version 16 | repository = var.repository 17 | values = var.values 18 | timeout = var.timeout 19 | repository_key_file = var.repository_key_file 20 | repository_cert_file = var.repository_cert_file 21 | repository_ca_file = var.repository_ca_file 22 | repository_username = var.repository_username 23 | repository_password = var.repository_password 24 | devel = var.devel 25 | verify = var.verify 26 | keyring = var.keyring 27 | disable_webhooks = var.disable_webhooks 28 | reuse_values = var.reuse_values 29 | reset_values = var.reset_values 30 | force_update = var.force_update 31 | recreate_pods = var.recreate_pods 32 | cleanup_on_fail = var.cleanup_on_fail 33 | max_history = var.max_history 34 | atomic = var.atomic 35 | skip_crds = var.skip_crds 36 | render_subchart_notes = var.render_subchart_notes 37 | disable_openapi_validation = var.disable_openapi_validation 38 | wait = var.wait 39 | wait_for_jobs = var.wait_for_jobs 40 | dependency_update = var.dependency_update 41 | replace = var.replace 42 | lint = var.lint 43 | postrender = var.postrender 44 | set_sensitive = var.set_sensitive 45 | set_irsa_names = var.set_irsa_names 46 | create_role = var.create_role 47 | role_name = var.role_name 48 | role_name_use_prefix = var.role_name_use_prefix 49 | role_path = var.role_path 50 | role_permissions_boundary_arn = var.role_permissions_boundary_arn 51 | role_description = var.role_description 52 | role_policies = var.role_policies 53 | oidc_providers = var.oidc_providers 54 | max_session_duration = var.max_session_duration 55 | assume_role_condition_test = var.assume_role_condition_test 56 | allow_self_assume_role = var.allow_self_assume_role 57 | create_policy = var.create_policy 58 | source_policy_documents = var.source_policy_documents 59 | override_policy_documents = var.override_policy_documents 60 | policy_statements = var.policy_statements 61 | policy_name = var.policy_name 62 | policy_name_use_prefix = var.policy_name_use_prefix 63 | policy_path = var.policy_path 64 | policy_description = var.policy_description 65 | } 66 | -------------------------------------------------------------------------------- /modules/clickhouse-operator/outputs.tf: -------------------------------------------------------------------------------- 1 | output "chart" { 2 | description = "The name of the chart" 3 | value = try(module.clickhouse_operator.chart, null) 4 | } 5 | 6 | output "name" { 7 | description = "Name is the name of the release" 8 | value = try(module.clickhouse_operator.name, null) 9 | } 10 | 11 | output "namespace" { 12 | description = "Name of Kubernetes namespace" 13 | value = try(module.clickhouse_operator.namespace, null) 14 | } 15 | 16 | output "revision" { 17 | description = "Version is an int32 which represents the version of the release" 18 | value = try(module.clickhouse_operator.revision, null) 19 | } 20 | 21 | output "version" { 22 | description = "A SemVer 2 conformant version string of the chart" 23 | value = try(module.clickhouse_operator.version, null) 24 | } 25 | 26 | output "app_version" { 27 | description = "The version number of the application being deployed" 28 | value = try(module.clickhouse_operator.app_version, null) 29 | } 30 | -------------------------------------------------------------------------------- /modules/eks/README.md: -------------------------------------------------------------------------------- 1 | # aws-eks-terraform 2 | 3 | [![#StandWithBelarus](https://img.shields.io/badge/Belarus-red?label=%23%20Stand%20With&labelColor=white&color=red) 4 | Voices From Belarus](https://bysol.org/en/) [![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://vshymanskyy.github.io/StandWithUkraine) 5 | 6 | Sugar for [terraform-aws-eks](https://github.com/terraform-aws-modules/terraform-aws-eks). Examples for further configuring the EKS cluster can be found in [eks blueprints](https://github.com/aws-ia/terraform-aws-eks-blueprints/tree/main), [tEKS](https://github.com/particuleio/teks) and [eks demo](https://github.com/awslabs/eksdemo) repos. 7 | 8 | ## Variables 9 | 10 | |Name|Description|Type|Required| 11 | |----|-----------|----|:------:| 12 | |vpc_id|ID of target VPC, 'default' will be used by default|string|no| 13 | |subnet_ids|List of networks for using for control plane and nodes|list(string)|no| 14 | |cluster_name|AWS EKS cluster name|string|yes| 15 | |cluster_version|AWS EKS cluster version|string|no| 16 | |cluster_addons|AWS EKS cluster addons map, default is latest coredns, kube-proxy, vpc-cni, aws-ebs-csi-driver, snapshot-controller|map(any)|no| 17 | |self_managed_node_group_defaults|Defaults configs for self_managed_node_groups|map(string)|no| 18 | |eks_managed_node_group_defaults|Defaults configs for eks_managed_node_groups|map(string)|no| 19 | |fargate_profile_defaults|Defaults configs for fargate_profiles|map(string)|no| 20 | |group_defaults|Defaults configs for self_managed_node_groups, eks_managed_node_groups and fargate_profiles|map(string)|no| 21 | |self_managed_node_groups|Configs for self_managed_node_groups|map(string)|no| 22 | |eks_managed_node_groups|Configs for eks_managed_node_groups|map(string)|no| 23 | |fargate_profiles|Configs for fargate_profiles|map(string)|no| 24 | |admin_iam_roles|List of account roles that should have EKS amdin permissions|list(string)|no| 25 | |admin_iam_users|List of account users that should have EKS amdin permissions|list(string)|no| 26 | |eks_iam_roles|List of maps with iam roles that should map eks service accounts|list(object)|no| 27 | |tags|Tags for EKS|map(string)|no| 28 | 29 | ## Outputs 30 | 31 | |Name|Description| 32 | |----|-----------| 33 | |region|The AWS region| 34 | |vpc_id|The ID of the target VPC| 35 | |cloudwatch_log_group_arn|Arn of cloudwatch log group created| 36 | |cloudwatch_log_group_name|Name of cloudwatch log group created| 37 | |cluster_addons|Map of attribute maps for all EKS cluster addons enabled| 38 | |cluster_arn|The Amazon Resource Name (ARN) of the cluster| 39 | |cluster_certificate_authority_data|Base64 encoded certificate data required to communicate with the cluster| 40 | |cluster_endpoint|Endpoint for your Kubernetes API server| 41 | |cluster_iam_role_arn|IAM role ARN of the EKS cluster| 42 | |cluster_iam_role_name|IAM role name of the EKS cluster| 43 | |cluster_iam_role_unique_id|Stable and unique string identifying the IAM role| 44 | |cluster_id|The ID of the EKS cluster. Note: currently a value is returned only for local EKS clusters created on Outposts| 45 | |cluster_identity_providers|Map of attribute maps for all EKS identity providers enabled| 46 | |cluster_name|The name of the EKS cluster| 47 | |cluster_oidc_issuer_url|The URL on the EKS cluster for the OpenID Connect identity provider| 48 | |cluster_platform_version|Platform version for the cluster| 49 | |cluster_primary_security_group_id|Cluster security group that was created by Amazon EKS for the cluster. Managed node groups use this security group for control-plane-to-data-plane communication. Referred to as 'Cluster security group' in the EKS console| 50 | |cluster_security_group_arn|Amazon Resource Name (ARN) of the cluster security group| 51 | |cluster_security_group_id|ID of the cluster security group| 52 | |cluster_status|Status of the EKS cluster. One of CREATING, ACTIVE, DELETING, FAILED| 53 | |cluster_tls_certificate_sha1_fingerprint|The SHA1 fingerprint of the public key of the cluster's certificate| 54 | |cluster_version|The Kubernetes version for the cluster| 55 | |eks_managed_node_groups|Map of attribute maps for all EKS managed node groups created| 56 | |eks_managed_node_groups_autoscaling_group_names|List of the autoscaling group names created by EKS managed node groups| 57 | |fargate_profiles|Map of attribute maps for all EKS Fargate Profiles created| 58 | |kms_key_arn|The Amazon Resource Name (ARN) of the key| 59 | |kms_key_id|The globally unique identifier for the key| 60 | |kms_key_policy|The IAM resource policy set on the key| 61 | |node_security_group_arn|Amazon Resource Name (ARN) of the node shared security group| 62 | |node_security_group_id|ID of the node shared security group| 63 | |oidc_provider|The OpenID Connect identity provider (issuer URL without leading https://)| 64 | |oidc_provider_arn|The ARN of the OIDC Provider if enable_irsa = true| 65 | |self_managed_node_groups|Map of attribute maps for all self managed node groups created| 66 | |self_managed_node_groups_autoscaling_group_names|List of the autoscaling group names created by self-managed node groups| 67 | 68 | Also `~/.kube/eks-${data.aws_region.current"}-${module.eks.cluster_name}` will be created by `aws eks` utility. 69 | 70 | ## About the Author 71 | 72 | Hello, everyone! My name is Filipp, and I have been working with high load distribution systems and services, security, monitoring, continuous deployment and release management (DevOps domain) since 2012. 73 | 74 | One of my passions is developing DevOps solutions and contributing to the open-source community. By sharing my knowledge and experiences, I strive to save time for both myself and others while fostering a culture of collaboration and learning. 75 | 76 | I had to leave my home country, Belarus, due to my participation in [protests against the oppressive regime of dictator Lukashenko](https://en.wikipedia.org/wiki/2020%E2%80%932021_Belarusian_protests), who maintains a close affiliation with Putin. Since then, I'm trying to build my life from zero in other countries. 77 | 78 | If you are seeking a skilled DevOps lead or architect to enhance your project, I invite you to connect with me on [LinkedIn](https://www.linkedin.com/in/filipp-frizzy-289a0360/) or explore my valuable contributions on [GitHub](https://github.com/Friz-zy/). Let's collaborate and create some cool solutions together :) 79 | 80 | ## Support 81 | 82 | You can support this or any other of my projects 83 | - [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/filipp_frizzy) 84 | - [donationalerts.com/r/filipp_frizzy](https://www.donationalerts.com/r/filipp_frizzy) 85 | - ETH 0xCD9fC1719b9E174E911f343CA2B391060F931ff7 86 | - BTC bc1q8fhsj24f5ncv3995zk9v3jhwwmscecc6w0tdw3 87 | -------------------------------------------------------------------------------- /modules/eks/main.tf: -------------------------------------------------------------------------------- 1 | provider "kubernetes" { 2 | host = module.eks.cluster_endpoint 3 | cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data) 4 | 5 | # This requires the awscli to be installed locally where Terraform is executed 6 | exec { 7 | api_version = "client.authentication.k8s.io/v1beta1" 8 | command = "aws" 9 | args = ["eks", "get-token", "--cluster-name", module.eks.cluster_name] 10 | } 11 | } 12 | 13 | data "aws_region" "current" {} 14 | 15 | data "aws_caller_identity" "current" {} 16 | 17 | data "aws_vpc" "default" { 18 | default = true 19 | } 20 | 21 | data "aws_vpc" "target" { 22 | id = local.vpc_id 23 | } 24 | 25 | data "aws_subnets" "vpc_subnets" { 26 | filter { 27 | name = "vpc-id" 28 | values = [local.vpc_id] 29 | } 30 | 31 | filter { 32 | name = "state" 33 | values = ["available"] 34 | } 35 | } 36 | 37 | locals { 38 | kubeconfig = pathexpand("~/.kube/eks-${data.aws_caller_identity.current.account_id}-${data.aws_region.current.name}-${module.eks.cluster_name}") 39 | 40 | vpc_id = coalesce(var.vpc_id, data.aws_vpc.default.id) 41 | 42 | subnet_ids = coalesce(var.subnet_ids, data.aws_subnets.vpc_subnets.ids) 43 | 44 | self_managed_node_group_defaults = merge(var.group_defaults, var.self_managed_node_group_defaults) 45 | eks_managed_node_group_defaults = merge(var.group_defaults, var.eks_managed_node_group_defaults) 46 | fargate_profile_defaults = merge(var.group_defaults, var.fargate_profile_defaults) 47 | 48 | aws_auth_users = [ 49 | for u in var.admin_iam_users : { 50 | userarn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:user/${u}" 51 | username = u 52 | groups = ["system:masters"] 53 | } 54 | ] 55 | 56 | aws_auth_roles = [ 57 | for u in var.admin_iam_roles : { 58 | userarn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${u}" 59 | username = u 60 | groups = ["system:masters"] 61 | } 62 | ] 63 | } 64 | 65 | ################################################################################ 66 | # EKS 67 | # Full example https://github.com/terraform-aws-modules/terraform-aws-eks/blob/master/examples/complete/main.tf 68 | ################################################################################ 69 | 70 | module "eks" { 71 | source = "terraform-aws-modules/eks/aws" 72 | version = "~> 19.0" 73 | 74 | cluster_name = var.cluster_name 75 | # https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html 76 | cluster_version = var.cluster_version 77 | 78 | cluster_endpoint_public_access = true 79 | enable_irsa = true 80 | 81 | # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_addon 82 | cluster_addons = var.cluster_addons 83 | 84 | vpc_id = local.vpc_id 85 | subnet_ids = local.subnet_ids 86 | # control_plane_subnet_ids = data.aws_subnets.vpc_subnets.ids 87 | 88 | self_managed_node_group_defaults = local.self_managed_node_group_defaults 89 | eks_managed_node_group_defaults = local.eks_managed_node_group_defaults 90 | fargate_profile_defaults = local.fargate_profile_defaults 91 | 92 | self_managed_node_groups = var.self_managed_node_groups 93 | eks_managed_node_groups = var.eks_managed_node_groups 94 | fargate_profiles = var.fargate_profiles 95 | 96 | # aws-auth configmap 97 | manage_aws_auth_configmap = false 98 | create_aws_auth_configmap = false 99 | 100 | # https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html 101 | cloudwatch_log_group_retention_in_days = 30 # default is 90 102 | 103 | aws_auth_roles = local.aws_auth_roles 104 | aws_auth_users = local.aws_auth_users 105 | aws_auth_accounts = [ 106 | data.aws_caller_identity.current.account_id 107 | ] 108 | 109 | tags = var.tags 110 | } 111 | 112 | resource "kubernetes_service_account" "accounts" { 113 | count = length(var.eks_iam_roles) 114 | 115 | metadata { 116 | name = var.eks_iam_roles[count.index].role_name 117 | namespace = var.eks_iam_roles[count.index].role_namespace 118 | annotations = { 119 | "eks.amazonaws.com/role-arn" = var.eks_iam_roles[count.index].role_arn 120 | } 121 | } 122 | automount_service_account_token = true 123 | } 124 | 125 | module "iam_eks_role" { 126 | source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" 127 | count = length(var.eks_iam_roles) 128 | 129 | role_name = var.eks_iam_roles[count.index].role_name 130 | 131 | role_policy_arns = var.eks_iam_roles[count.index].role_policy_arns 132 | 133 | oidc_providers = { 134 | default = { 135 | provider_arn = module.eks.oidc_provider_arn 136 | namespace_service_accounts = ["${var.eks_iam_roles[count.index].role_namespace}:${var.eks_iam_roles[count.index].role_name}"] 137 | } 138 | } 139 | } 140 | 141 | resource "null_resource" "kubectl" { 142 | provisioner "local-exec" { 143 | command = "aws eks --region ${data.aws_region.current.name} update-kubeconfig --name ${module.eks.cluster_name} --kubeconfig ${local.kubeconfig}" 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /modules/eks/outputs.tf: -------------------------------------------------------------------------------- 1 | output "region" { 2 | value = data.aws_region.current.name 3 | description = "The AWS region" 4 | } 5 | 6 | output "vpc_id" { 7 | value = data.aws_vpc.target.id 8 | description = "The ID of the target VPC" 9 | } 10 | 11 | output "cloudwatch_log_group_arn" { 12 | value = module.eks.cloudwatch_log_group_arn 13 | description = "Arn of cloudwatch log group created" 14 | } 15 | 16 | output "cloudwatch_log_group_name" { 17 | value = module.eks.cloudwatch_log_group_name 18 | description = "Name of cloudwatch log group created" 19 | } 20 | 21 | output "cluster_addons" { 22 | value = module.eks.cluster_addons 23 | description = "Map of attribute maps for all EKS cluster addons enabled" 24 | } 25 | 26 | output "cluster_arn" { 27 | value = module.eks.cluster_arn 28 | description = "The Amazon Resource Name (ARN) of the cluster" 29 | } 30 | 31 | output "cluster_certificate_authority_data" { 32 | value = module.eks.cluster_certificate_authority_data 33 | description = "Base64 encoded certificate data required to communicate with the cluster" 34 | } 35 | 36 | output "cluster_endpoint" { 37 | value = module.eks.cluster_endpoint 38 | description = "Endpoint for your Kubernetes API server" 39 | } 40 | 41 | output "cluster_iam_role_arn" { 42 | value = module.eks.cluster_iam_role_arn 43 | description = "IAM role ARN of the EKS cluster" 44 | } 45 | 46 | output "cluster_iam_role_name" { 47 | value = module.eks.cluster_iam_role_name 48 | description = "IAM role name of the EKS cluster" 49 | } 50 | 51 | output "cluster_iam_role_unique_id" { 52 | value = module.eks.cluster_iam_role_unique_id 53 | description = "Stable and unique string identifying the IAM role" 54 | } 55 | 56 | output "cluster_id" { 57 | value = module.eks.cluster_id 58 | description = "The ID of the EKS cluster. Note: currently a value is returned only for local EKS clusters created on Outposts" 59 | } 60 | 61 | output "cluster_identity_providers" { 62 | value = module.eks.cluster_identity_providers 63 | description = "Map of attribute maps for all EKS identity providers enabled" 64 | } 65 | 66 | output "cluster_name" { 67 | value = module.eks.cluster_name 68 | description = "The name of the EKS cluster" 69 | } 70 | 71 | output "cluster_oidc_issuer_url" { 72 | value = module.eks.cluster_oidc_issuer_url 73 | description = "The URL on the EKS cluster for the OpenID Connect identity provider" 74 | } 75 | 76 | output "cluster_platform_version" { 77 | value = module.eks.cluster_platform_version 78 | description = "Platform version for the cluster" 79 | } 80 | 81 | output "cluster_primary_security_group_id" { 82 | value = module.eks.cluster_primary_security_group_id 83 | description = "Cluster security group that was created by Amazon EKS for the cluster. Managed node groups use this security group for control-plane-to-data-plane communication. Referred to as 'Cluster security group' in the EKS console" 84 | } 85 | 86 | output "cluster_security_group_arn" { 87 | value = module.eks.cluster_security_group_arn 88 | description = "Amazon Resource Name (ARN) of the cluster security group" 89 | } 90 | 91 | output "cluster_security_group_id" { 92 | value = module.eks.cluster_security_group_id 93 | description = "ID of the cluster security group" 94 | } 95 | 96 | output "cluster_status" { 97 | value = module.eks.cluster_status 98 | description = "Status of the EKS cluster. One of CREATING, ACTIVE, DELETING, FAILED" 99 | } 100 | 101 | output "cluster_tls_certificate_sha1_fingerprint" { 102 | value = module.eks.cluster_tls_certificate_sha1_fingerprint 103 | description = "The SHA1 fingerprint of the public key of the cluster's certificate" 104 | } 105 | 106 | output "cluster_version" { 107 | value = module.eks.cluster_version 108 | description = "The Kubernetes version for the cluster" 109 | } 110 | 111 | output "eks_managed_node_groups" { 112 | value = module.eks.eks_managed_node_groups 113 | description = "Map of attribute maps for all EKS managed node groups created" 114 | } 115 | 116 | output "eks_managed_node_groups_autoscaling_group_names" { 117 | value = module.eks.eks_managed_node_groups_autoscaling_group_names 118 | description = "List of the autoscaling group names created by EKS managed node groups" 119 | } 120 | 121 | output "fargate_profiles" { 122 | value = module.eks.fargate_profiles 123 | description = "Map of attribute maps for all EKS Fargate Profiles created" 124 | } 125 | 126 | output "kms_key_arn" { 127 | value = module.eks.kms_key_arn 128 | description = "The Amazon Resource Name (ARN) of the key" 129 | } 130 | 131 | output "kms_key_id" { 132 | value = module.eks.kms_key_id 133 | description = "The globally unique identifier for the key" 134 | } 135 | 136 | output "kms_key_policy" { 137 | value = module.eks.kms_key_policy 138 | description = "The IAM resource policy set on the key" 139 | } 140 | 141 | output "node_security_group_arn" { 142 | value = module.eks.node_security_group_arn 143 | description = "Amazon Resource Name (ARN) of the node shared security group" 144 | } 145 | 146 | output "node_security_group_id" { 147 | value = module.eks.node_security_group_id 148 | description = "ID of the node shared security group" 149 | } 150 | 151 | output "oidc_provider" { 152 | value = module.eks.oidc_provider 153 | description = "The OpenID Connect identity provider (issuer URL without leading https://)" 154 | } 155 | 156 | output "oidc_provider_arn" { 157 | value = module.eks.oidc_provider_arn 158 | description = "The ARN of the OIDC Provider if enable_irsa = true" 159 | } 160 | 161 | output "self_managed_node_groups" { 162 | value = module.eks.self_managed_node_groups 163 | description = "Map of attribute maps for all self managed node groups created" 164 | } 165 | 166 | output "self_managed_node_groups_autoscaling_group_names" { 167 | value = module.eks.self_managed_node_groups_autoscaling_group_names 168 | description = "List of the autoscaling group names created by self-managed node groups" 169 | } 170 | 171 | output "kubeconfig" { 172 | value = local.kubeconfig 173 | description = "Path to generated kube config file" 174 | } 175 | -------------------------------------------------------------------------------- /modules/eks/variables.tf: -------------------------------------------------------------------------------- 1 | variable "vpc_id" { 2 | description = "ID of target VPC, 'default' will be used by default" 3 | type = string 4 | default = "" 5 | } 6 | 7 | variable "subnet_ids" { 8 | description = "List of networks for using for control plane and nodes" 9 | type = list(string) 10 | default = null 11 | } 12 | 13 | variable "cluster_name" { 14 | description = "AWS EKS cluster name" 15 | type = string 16 | } 17 | 18 | variable "cluster_version" { 19 | description = "AWS EKS cluster version" 20 | type = string 21 | default = "1.28" 22 | } 23 | 24 | variable "cluster_addons" { 25 | description = "AWS EKS cluster addons map, default is latest coredns, kube-proxy, vpc-cni, aws-ebs-csi-driver, snapshot-controller" 26 | type = any 27 | default = { 28 | coredns = { 29 | most_recent = true 30 | } 31 | kube-proxy = { 32 | most_recent = true 33 | } 34 | vpc-cni = { 35 | most_recent = true 36 | } 37 | aws-ebs-csi-driver = { 38 | most_recent = true 39 | } 40 | snapshot-controller = { 41 | most_recent = true 42 | } 43 | } 44 | } 45 | 46 | variable "self_managed_node_group_defaults" { 47 | description = "Defaults configs for self_managed_node_groups" 48 | type = any 49 | default = {} 50 | } 51 | 52 | variable "eks_managed_node_group_defaults" { 53 | description = "Defaults configs for eks_managed_node_groups" 54 | type = any 55 | default = {} 56 | } 57 | 58 | variable "fargate_profile_defaults" { 59 | description = "Defaults configs for fargate_profiles" 60 | type = any 61 | default = {} 62 | } 63 | 64 | # https://docs.aws.amazon.com/eks/latest/APIReference/API_Nodegroup.html 65 | # https://registry.terraform.io/modules/terraform-aws-modules/eks/aws/latest/submodules/eks-managed-node-group 66 | variable "group_defaults" { 67 | description = "Defaults configs for self_managed_node_groups, eks_managed_node_groups and fargate_profiles" 68 | type = any 69 | default = { 70 | min_size = 0 71 | max_size = 5 72 | desired_size = 0 73 | 74 | instance_types = ["m6a.large", "m5a.large", "m7i-flex.large"] # , "m6i.large", "m5.large", "m4.large", "m7i.large"] # 2cpu 8gb 75 | # instance_types = ["c6a.large", "c5a.large", "c6i.large", "c5.large", "c5ad.large", "c5ad.large"] # 2cpu 4gb 76 | 77 | capacity_type = "ON_DEMAND" # "SPOT" 78 | platform = "linux" # "bottlerocket" 79 | ami_type = "AL2_x86_64" # "BOTTLEROCKET_x86_64" 80 | disk_size = 20 81 | # ebs_optimized = true # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-optimized.html 82 | enclave_options = {} 83 | 84 | update_config = { 85 | max_unavailable_percentage = 33 # or set `max_unavailable` 86 | } 87 | 88 | # Needed by the aws-ebs-csi-driver 89 | iam_role_additional_policies = { 90 | AmazonEBSCSIDriverPolicy = "arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy" 91 | AmazonSSMManagedInstanceCore = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" 92 | } 93 | 94 | tags = { 95 | Terraform = "true" 96 | Managed = "eks" 97 | } 98 | } 99 | } 100 | 101 | variable "self_managed_node_groups" { 102 | description = "Configs for self_managed_node_groups" 103 | type = any 104 | default = {} 105 | } 106 | 107 | variable "eks_managed_node_groups" { 108 | description = "Configs for eks_managed_node_groups" 109 | type = any 110 | default = {} 111 | } 112 | 113 | variable "fargate_profiles" { 114 | description = "Configs for fargate_profiles" 115 | type = any 116 | default = {} 117 | } 118 | 119 | variable "admin_iam_roles" { 120 | description = "List of account roles that should have EKS amdin permissions" 121 | type = list(string) 122 | default = [] 123 | } 124 | 125 | variable "admin_iam_users" { 126 | description = "List of account users that should have EKS amdin permissions" 127 | type = list(string) 128 | default = [] 129 | } 130 | 131 | variable "eks_iam_roles" { 132 | description = "List of maps with iam roles that should map eks service accounts" 133 | type = list(object({ 134 | role_name = string 135 | role_arn = string 136 | role_namespace = string 137 | role_policy_arns = any 138 | })) 139 | default = [] 140 | } 141 | 142 | variable "tags" { 143 | description = "Tags for EKS" 144 | type = map(any) 145 | default = { Terraform = "true" } 146 | } 147 | -------------------------------------------------------------------------------- /modules/grafana-operator/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | # https://github.com/bitnami/charts/blob/main/bitnami/grafana-operator/values.yaml 3 | values = [ 4 | <<-EOT 5 | prometheus: 6 | serviceMonitor: 7 | enabled: true 8 | grafana: 9 | enabled: false 10 | operator: 11 | resourcesPreset: "none" 12 | EOT 13 | ] 14 | } 15 | 16 | module "grafana_operator" { 17 | source = "aws-ia/eks-blueprints-addon/aws" 18 | version = "~> 1.1" 19 | 20 | values = concat( 21 | local.values, 22 | var.values 23 | ) 24 | set = var.set 25 | 26 | create = var.create 27 | tags = var.tags 28 | create_release = var.create_release 29 | name = var.name 30 | description = var.description 31 | namespace = var.namespace 32 | create_namespace = var.create_namespace 33 | chart = var.chart 34 | chart_version = var.chart_version 35 | repository = var.repository 36 | timeout = var.timeout 37 | repository_key_file = var.repository_key_file 38 | repository_cert_file = var.repository_cert_file 39 | repository_ca_file = var.repository_ca_file 40 | repository_username = var.repository_username 41 | repository_password = var.repository_password 42 | devel = var.devel 43 | verify = var.verify 44 | keyring = var.keyring 45 | disable_webhooks = var.disable_webhooks 46 | reuse_values = var.reuse_values 47 | reset_values = var.reset_values 48 | force_update = var.force_update 49 | recreate_pods = var.recreate_pods 50 | cleanup_on_fail = var.cleanup_on_fail 51 | max_history = var.max_history 52 | atomic = var.atomic 53 | skip_crds = var.skip_crds 54 | render_subchart_notes = var.render_subchart_notes 55 | disable_openapi_validation = var.disable_openapi_validation 56 | wait = var.wait 57 | wait_for_jobs = var.wait_for_jobs 58 | dependency_update = var.dependency_update 59 | replace = var.replace 60 | lint = var.lint 61 | postrender = var.postrender 62 | set_sensitive = var.set_sensitive 63 | set_irsa_names = var.set_irsa_names 64 | create_role = var.create_role 65 | role_name = var.role_name 66 | role_name_use_prefix = var.role_name_use_prefix 67 | role_path = var.role_path 68 | role_permissions_boundary_arn = var.role_permissions_boundary_arn 69 | role_description = var.role_description 70 | role_policies = var.role_policies 71 | oidc_providers = var.oidc_providers 72 | max_session_duration = var.max_session_duration 73 | assume_role_condition_test = var.assume_role_condition_test 74 | allow_self_assume_role = var.allow_self_assume_role 75 | create_policy = var.create_policy 76 | source_policy_documents = var.source_policy_documents 77 | override_policy_documents = var.override_policy_documents 78 | policy_statements = var.policy_statements 79 | policy_name = var.policy_name 80 | policy_name_use_prefix = var.policy_name_use_prefix 81 | policy_path = var.policy_path 82 | policy_description = var.policy_description 83 | } 84 | -------------------------------------------------------------------------------- /modules/grafana-operator/outputs.tf: -------------------------------------------------------------------------------- 1 | output "chart" { 2 | description = "The name of the chart" 3 | value = try(module.grafana_operator.chart, null) 4 | } 5 | 6 | output "name" { 7 | description = "Name is the name of the release" 8 | value = try(module.grafana_operator.name, null) 9 | } 10 | 11 | output "namespace" { 12 | description = "Name of Kubernetes namespace" 13 | value = try(module.grafana_operator.namespace, null) 14 | } 15 | 16 | output "revision" { 17 | description = "Version is an int32 which represents the version of the release" 18 | value = try(module.grafana_operator.revision, null) 19 | } 20 | 21 | output "version" { 22 | description = "A SemVer 2 conformant version string of the chart" 23 | value = try(module.grafana_operator.version, null) 24 | } 25 | 26 | output "app_version" { 27 | description = "The version number of the application being deployed" 28 | value = try(module.grafana_operator.app_version, null) 29 | } 30 | -------------------------------------------------------------------------------- /modules/grafana-operator/variables.tf: -------------------------------------------------------------------------------- 1 | variable "create" { 2 | description = "Controls if resources should be created (affects all resources)" 3 | type = bool 4 | default = true 5 | } 6 | 7 | variable "tags" { 8 | description = "A map of tags to add to all resources" 9 | type = map(string) 10 | default = {} 11 | } 12 | 13 | ################################################################################ 14 | # Helm Release 15 | ################################################################################ 16 | 17 | variable "create_release" { 18 | description = "Determines whether the Helm release is created" 19 | type = bool 20 | default = true 21 | } 22 | 23 | variable "name" { 24 | description = "Name of the Helm release" 25 | type = string 26 | default = "" 27 | } 28 | 29 | variable "description" { 30 | description = "Set release description attribute (visible in the history)" 31 | type = string 32 | default = "Kubernetes operator that manages Grafana" 33 | } 34 | 35 | variable "namespace" { 36 | description = "The namespace to install the release into. Defaults to `default`" 37 | type = string 38 | default = "grafana" 39 | } 40 | 41 | variable "create_namespace" { 42 | description = "Create the namespace if it does not yet exist. Defaults to `false`" 43 | type = bool 44 | default = true 45 | } 46 | 47 | variable "chart" { 48 | description = "Chart name to be installed. The chart name can be local path, a URL to a chart, or the name of the chart if `repository` is specified" 49 | type = string 50 | default = "grafana-operator" 51 | } 52 | 53 | variable "chart_version" { 54 | description = "Specify the exact chart version to install. If this is not specified, the latest version is installed" 55 | type = string 56 | default = "" 57 | } 58 | 59 | variable "repository" { 60 | description = "Repository URL where to locate the requested chart" 61 | type = string 62 | default = "https://charts.bitnami.com/bitnami" 63 | } 64 | 65 | variable "values" { 66 | description = "List of values in raw yaml to pass to helm. Values will be merged, in order, as Helm does with multiple `-f` options" 67 | type = list(string) 68 | default = null 69 | } 70 | 71 | variable "timeout" { 72 | description = "Time in seconds to wait for any individual kubernetes operation (like Jobs for hooks). Defaults to `300` seconds" 73 | type = number 74 | default = null 75 | } 76 | 77 | variable "repository_key_file" { 78 | description = "The repositories cert key file" 79 | type = string 80 | default = null 81 | } 82 | 83 | variable "repository_cert_file" { 84 | description = "The repositories cert file" 85 | type = string 86 | default = null 87 | } 88 | 89 | variable "repository_ca_file" { 90 | description = "The Repositories CA File" 91 | type = string 92 | default = null 93 | } 94 | 95 | variable "repository_username" { 96 | description = "Username for HTTP basic authentication against the repository" 97 | type = string 98 | default = null 99 | } 100 | 101 | variable "repository_password" { 102 | description = "Password for HTTP basic authentication against the repository" 103 | type = string 104 | default = null 105 | } 106 | 107 | variable "devel" { 108 | description = "Use chart development versions, too. Equivalent to version '>0.0.0-0'. If version is set, this is ignored" 109 | type = bool 110 | default = null 111 | } 112 | 113 | variable "verify" { 114 | description = "Verify the package before installing it. Helm uses a provenance file to verify the integrity of the chart; this must be hosted alongside the chart. For more information see the Helm Documentation. Defaults to `false`" 115 | type = bool 116 | default = null 117 | } 118 | 119 | variable "keyring" { 120 | description = "Location of public keys used for verification. Used only if verify is true. Defaults to `/.gnupg/pubring.gpg` in the location set by `home`" 121 | type = string 122 | default = null 123 | } 124 | 125 | variable "disable_webhooks" { 126 | description = "Prevent hooks from running. Defaults to `false`" 127 | type = bool 128 | default = null 129 | } 130 | 131 | variable "reuse_values" { 132 | description = "When upgrading, reuse the last release's values and merge in any overrides. If `reset_values` is specified, this is ignored. Defaults to `false`" 133 | type = bool 134 | default = null 135 | } 136 | 137 | variable "reset_values" { 138 | description = "When upgrading, reset the values to the ones built into the chart. Defaults to `false`" 139 | type = bool 140 | default = true 141 | } 142 | 143 | variable "force_update" { 144 | description = "Force resource update through delete/recreate if needed. Defaults to `false`" 145 | type = bool 146 | default = null 147 | } 148 | 149 | variable "recreate_pods" { 150 | description = "Perform pods restart during upgrade/rollback. Defaults to `false`" 151 | type = bool 152 | default = null 153 | } 154 | 155 | variable "cleanup_on_fail" { 156 | description = "Allow deletion of new resources created in this upgrade when upgrade fails. Defaults to `false`" 157 | type = bool 158 | default = null 159 | } 160 | 161 | variable "max_history" { 162 | description = "Maximum number of release versions stored per release. Defaults to `0` (no limit)" 163 | type = number 164 | default = null 165 | } 166 | 167 | variable "atomic" { 168 | description = "If set, installation process purges chart on fail. The wait flag will be set automatically if atomic is used. Defaults to `false`" 169 | type = bool 170 | default = null 171 | } 172 | 173 | variable "skip_crds" { 174 | description = "If set, no CRDs will be installed. By default, CRDs are installed if not already present. Defaults to `false`" 175 | type = bool 176 | default = null 177 | } 178 | 179 | variable "render_subchart_notes" { 180 | description = "If set, render subchart notes along with the parent. Defaults to `true`" 181 | type = bool 182 | default = null 183 | } 184 | 185 | variable "disable_openapi_validation" { 186 | description = "If set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema. Defaults to `false`" 187 | type = bool 188 | default = null 189 | } 190 | 191 | variable "wait" { 192 | description = "Will wait until all resources are in a ready state before marking the release as successful. If set to `true`, it will wait for as long as `timeout`. If set to `null` fallback on `300s` timeout. Defaults to `false`" 193 | type = bool 194 | default = false 195 | } 196 | 197 | variable "wait_for_jobs" { 198 | description = "If wait is enabled, will wait until all Jobs have been completed before marking the release as successful. It will wait for as long as `timeout`. Defaults to `false`" 199 | type = bool 200 | default = null 201 | } 202 | 203 | variable "dependency_update" { 204 | description = "Runs helm dependency update before installing the chart. Defaults to `false`" 205 | type = bool 206 | default = null 207 | } 208 | 209 | variable "replace" { 210 | description = "Re-use the given name, only if that name is a deleted release which remains in the history. This is unsafe in production. Defaults to `false`" 211 | type = bool 212 | default = null 213 | } 214 | 215 | variable "lint" { 216 | description = "Run the helm chart linter during the plan. Defaults to `false`" 217 | type = bool 218 | default = null 219 | } 220 | 221 | variable "postrender" { 222 | description = "Configure a command to run after helm renders the manifest which can alter the manifest contents" 223 | type = any 224 | default = {} 225 | } 226 | 227 | variable "set" { 228 | description = "Value block with custom values to be merged with the values yaml" 229 | type = any 230 | default = [] 231 | } 232 | 233 | variable "set_sensitive" { 234 | description = "Value block with custom sensitive values to be merged with the values yaml that won't be exposed in the plan's diff" 235 | type = any 236 | default = [] 237 | } 238 | 239 | variable "set_irsa_names" { 240 | description = "Value annotations name where IRSA role ARN created by module will be assigned to the `value`" 241 | type = list(string) 242 | default = [] 243 | } 244 | 245 | ################################################################################ 246 | # IAM Role for Service Account(s) (IRSA) 247 | ################################################################################ 248 | 249 | variable "create_role" { 250 | description = "Determines whether to create an IAM role" 251 | type = bool 252 | default = false 253 | } 254 | 255 | variable "role_name" { 256 | description = "Name of IAM role" 257 | type = string 258 | default = null 259 | } 260 | 261 | variable "role_name_use_prefix" { 262 | description = "Determines whether the IAM role name (`role_name`) is used as a prefix" 263 | type = bool 264 | default = true 265 | } 266 | 267 | variable "role_path" { 268 | description = "Path of IAM role" 269 | type = string 270 | default = "/" 271 | } 272 | 273 | variable "role_permissions_boundary_arn" { 274 | description = "Permissions boundary ARN to use for IAM role" 275 | type = string 276 | default = null 277 | } 278 | 279 | variable "role_description" { 280 | description = "IAM Role description" 281 | type = string 282 | default = null 283 | } 284 | 285 | variable "role_policies" { 286 | description = "Policies to attach to the IAM role in `{'static_name' = 'policy_arn'}` format" 287 | type = map(string) 288 | default = {} 289 | } 290 | 291 | variable "oidc_providers" { 292 | description = "Map of OIDC providers where each provider map should contain the `provider_arn`, and `service_accounts`" 293 | type = any 294 | default = {} 295 | } 296 | 297 | variable "max_session_duration" { 298 | description = "Maximum CLI/API session duration in seconds between 3600 and 43200" 299 | type = number 300 | default = null 301 | } 302 | 303 | variable "assume_role_condition_test" { 304 | description = "Name of the [IAM condition operator](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html) to evaluate when assuming the role" 305 | type = string 306 | default = "StringEquals" 307 | } 308 | 309 | variable "allow_self_assume_role" { 310 | description = "Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/)" 311 | type = bool 312 | default = false 313 | } 314 | 315 | ################################################################################ 316 | # IAM Policy 317 | ################################################################################ 318 | 319 | variable "create_policy" { 320 | description = "Whether to create an IAM policy that is attached to the IAM role created" 321 | type = bool 322 | default = true 323 | } 324 | 325 | variable "source_policy_documents" { 326 | description = "List of IAM policy documents that are merged together into the exported document. Statements must have unique `sid`s" 327 | type = list(string) 328 | default = [] 329 | } 330 | 331 | variable "override_policy_documents" { 332 | description = "List of IAM policy documents that are merged together into the exported document. In merging, statements with non-blank `sid`s will override statements with the same `sid`" 333 | type = list(string) 334 | default = [] 335 | } 336 | 337 | variable "policy_statements" { 338 | description = "List of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement)" 339 | type = any 340 | default = [] 341 | } 342 | 343 | variable "policy_name" { 344 | description = "Name of IAM policy" 345 | type = string 346 | default = null 347 | } 348 | 349 | variable "policy_name_use_prefix" { 350 | description = "Determines whether the IAM policy name (`policy_name`) is used as a prefix" 351 | type = bool 352 | default = true 353 | } 354 | 355 | variable "policy_path" { 356 | description = "Path of IAM policy" 357 | type = string 358 | default = null 359 | } 360 | 361 | variable "policy_description" { 362 | description = "IAM policy description" 363 | type = string 364 | default = null 365 | } 366 | -------------------------------------------------------------------------------- /modules/grafana/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | admin_password = coalesce(var.admin_password, random_password.grafana_admin_password.result) 3 | 4 | # https://github.com/grafana/helm-charts/blob/main/charts/grafana/values.yaml 5 | values = [ 6 | <<-EOT 7 | persistence: 8 | enabled: true 9 | size: 1Gi 10 | admin: 11 | existingSecret: "grafana-admin-credentials" 12 | userKey: username 13 | passwordKey: password 14 | EOT 15 | ] 16 | } 17 | 18 | resource "random_password" "grafana_admin_password" { 19 | length = 32 20 | special = false 21 | } 22 | 23 | module "kubernetes_manifests" { 24 | source = "../kubernetes-manifests" 25 | 26 | create = var.create 27 | name = "grafana-${var.namespace}-manifests" 28 | namespace = var.namespace 29 | tags = var.tags 30 | 31 | values = [ 32 | <<-EOT 33 | resources: 34 | - kind: Secret 35 | apiVersion: v1 36 | metadata: 37 | name: "grafana-admin-credentials" 38 | namespace: "${var.namespace}" 39 | stringData: 40 | username: "${var.admin_user}" 41 | password: "${local.admin_password}" 42 | type: Opaque 43 | EOT 44 | ] 45 | } 46 | 47 | module "grafana" { 48 | source = "aws-ia/eks-blueprints-addon/aws" 49 | version = "~> 1.1" 50 | 51 | values = concat( 52 | local.values, 53 | var.values 54 | ) 55 | set = var.set 56 | 57 | create = var.create 58 | tags = var.tags 59 | create_release = var.create_release 60 | name = var.name 61 | description = var.description 62 | namespace = var.namespace 63 | create_namespace = var.create_namespace 64 | chart = var.chart 65 | chart_version = var.chart_version 66 | repository = var.repository 67 | timeout = var.timeout 68 | repository_key_file = var.repository_key_file 69 | repository_cert_file = var.repository_cert_file 70 | repository_ca_file = var.repository_ca_file 71 | repository_username = var.repository_username 72 | repository_password = var.repository_password 73 | devel = var.devel 74 | verify = var.verify 75 | keyring = var.keyring 76 | disable_webhooks = var.disable_webhooks 77 | reuse_values = var.reuse_values 78 | reset_values = var.reset_values 79 | force_update = var.force_update 80 | recreate_pods = var.recreate_pods 81 | cleanup_on_fail = var.cleanup_on_fail 82 | max_history = var.max_history 83 | atomic = var.atomic 84 | skip_crds = var.skip_crds 85 | render_subchart_notes = var.render_subchart_notes 86 | disable_openapi_validation = var.disable_openapi_validation 87 | wait = var.wait 88 | wait_for_jobs = var.wait_for_jobs 89 | dependency_update = var.dependency_update 90 | replace = var.replace 91 | lint = var.lint 92 | postrender = var.postrender 93 | set_sensitive = var.set_sensitive 94 | set_irsa_names = var.set_irsa_names 95 | create_role = var.create_role 96 | role_name = var.role_name 97 | role_name_use_prefix = var.role_name_use_prefix 98 | role_path = var.role_path 99 | role_permissions_boundary_arn = var.role_permissions_boundary_arn 100 | role_description = var.role_description 101 | role_policies = var.role_policies 102 | oidc_providers = var.oidc_providers 103 | max_session_duration = var.max_session_duration 104 | assume_role_condition_test = var.assume_role_condition_test 105 | allow_self_assume_role = var.allow_self_assume_role 106 | create_policy = var.create_policy 107 | source_policy_documents = var.source_policy_documents 108 | override_policy_documents = var.override_policy_documents 109 | policy_statements = var.policy_statements 110 | policy_name = var.policy_name 111 | policy_name_use_prefix = var.policy_name_use_prefix 112 | policy_path = var.policy_path 113 | policy_description = var.policy_description 114 | } 115 | 116 | # https://grafana.github.io/grafana-operator/docs/grafana/#external-grafana-instances 117 | module "grafana_operator_datasource" { 118 | source = "../kubernetes-manifests" 119 | count = var.grafana_operator_integration == true ? 1 : 0 120 | 121 | name = "grafana-${var.namespace}-integration" 122 | namespace = var.grafana_operator_namespace 123 | tags = var.tags 124 | 125 | values = [ 126 | <<-EOT 127 | resources: 128 | - kind: Secret 129 | apiVersion: v1 130 | metadata: 131 | name: "grafana-${var.namespace}-integration-credentials" 132 | namespace: "${var.grafana_operator_namespace}" 133 | stringData: 134 | username: "${var.admin_user}" 135 | password: "${local.admin_password}" 136 | type: Opaque 137 | - apiVersion: "grafana.integreatly.org/v1beta1" 138 | kind: "Grafana" 139 | metadata: 140 | name: "grafana-${var.namespace}" 141 | namespace: "${var.namespace}" 142 | labels: 143 | dashboards: "grafana" 144 | spec: 145 | external: 146 | url: "http://${module.grafana.name}.${module.grafana.namespace}.svc.cluster.local" 147 | adminPassword: 148 | name: "grafana-${var.namespace}-integration-credentials" 149 | key: "password" 150 | adminUser: 151 | name: "grafana-${var.namespace}-integration-credentials" 152 | key: "username" 153 | EOT 154 | ] 155 | } 156 | -------------------------------------------------------------------------------- /modules/grafana/outputs.tf: -------------------------------------------------------------------------------- 1 | output "chart" { 2 | description = "The name of the chart" 3 | value = try(module.grafana.chart, null) 4 | } 5 | 6 | output "name" { 7 | description = "Name is the name of the release" 8 | value = try(module.grafana.name, null) 9 | } 10 | 11 | output "namespace" { 12 | description = "Name of Kubernetes namespace" 13 | value = try(module.grafana.namespace, null) 14 | } 15 | 16 | output "revision" { 17 | description = "Version is an int32 which represents the version of the release" 18 | value = try(module.grafana.revision, null) 19 | } 20 | 21 | output "version" { 22 | description = "A SemVer 2 conformant version string of the chart" 23 | value = try(module.grafana.version, null) 24 | } 25 | 26 | output "app_version" { 27 | description = "The version number of the application being deployed" 28 | value = try(module.grafana.app_version, null) 29 | } 30 | 31 | # output "values" { 32 | # description = "The compounded values from `values` and `set*` attributes" 33 | # value = try(module.grafana.values, null) 34 | # } 35 | 36 | ################################################################################ 37 | # Grafana 38 | ################################################################################ 39 | 40 | output "admin_password" { 41 | description = "Grafana admin password" 42 | value = local.admin_password 43 | sensitive = true 44 | } 45 | 46 | output "admin_user" { 47 | description = "Grafana admin user" 48 | value = var.admin_user 49 | } 50 | 51 | output "grafana_operator_integration" { 52 | description = "Are integration with Grafana Operator is enabled" 53 | value = var.grafana_operator_integration 54 | } 55 | -------------------------------------------------------------------------------- /modules/kubernetes-dashboard/main.tf: -------------------------------------------------------------------------------- 1 | # https://github.com/kubernetes/dashboard 2 | # https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/README.md 3 | 4 | locals { 5 | # https://github.com/kubernetes/dashboard/blob/master/charts/kubernetes-dashboard/values.yaml 6 | values = [ 7 | <<-EOT 8 | app: 9 | ingress: 10 | enabled: false 11 | nginx: 12 | enabled: false 13 | cert-manager: 14 | enabled: false 15 | networkPolicy: 16 | enabled: true 17 | EOT 18 | ] 19 | set = [] 20 | } 21 | 22 | module "kubernetes_dashboard" { 23 | source = "aws-ia/eks-blueprints-addon/aws" 24 | version = "~> 1.1" 25 | 26 | set = concat( 27 | local.set, 28 | var.set 29 | ) 30 | 31 | values = concat( 32 | local.values, 33 | var.values 34 | ) 35 | 36 | create = var.create 37 | tags = var.tags 38 | create_release = var.create_release 39 | name = var.name 40 | description = var.description 41 | namespace = var.namespace 42 | create_namespace = var.create_namespace 43 | chart = var.chart 44 | chart_version = var.chart_version 45 | repository = var.repository 46 | timeout = var.timeout 47 | repository_key_file = var.repository_key_file 48 | repository_cert_file = var.repository_cert_file 49 | repository_ca_file = var.repository_ca_file 50 | repository_username = var.repository_username 51 | repository_password = var.repository_password 52 | devel = var.devel 53 | verify = var.verify 54 | keyring = var.keyring 55 | disable_webhooks = var.disable_webhooks 56 | reuse_values = var.reuse_values 57 | reset_values = var.reset_values 58 | force_update = var.force_update 59 | recreate_pods = var.recreate_pods 60 | cleanup_on_fail = var.cleanup_on_fail 61 | max_history = var.max_history 62 | atomic = var.atomic 63 | skip_crds = var.skip_crds 64 | render_subchart_notes = var.render_subchart_notes 65 | disable_openapi_validation = var.disable_openapi_validation 66 | wait = var.wait 67 | wait_for_jobs = var.wait_for_jobs 68 | dependency_update = var.dependency_update 69 | replace = var.replace 70 | lint = var.lint 71 | postrender = var.postrender 72 | set_sensitive = var.set_sensitive 73 | set_irsa_names = var.set_irsa_names 74 | create_role = var.create_role 75 | role_name = var.role_name 76 | role_name_use_prefix = var.role_name_use_prefix 77 | role_path = var.role_path 78 | role_permissions_boundary_arn = var.role_permissions_boundary_arn 79 | role_description = var.role_description 80 | role_policies = var.role_policies 81 | oidc_providers = var.oidc_providers 82 | max_session_duration = var.max_session_duration 83 | assume_role_condition_test = var.assume_role_condition_test 84 | allow_self_assume_role = var.allow_self_assume_role 85 | create_policy = var.create_policy 86 | source_policy_documents = var.source_policy_documents 87 | override_policy_documents = var.override_policy_documents 88 | policy_statements = var.policy_statements 89 | policy_name = var.policy_name 90 | policy_name_use_prefix = var.policy_name_use_prefix 91 | policy_path = var.policy_path 92 | policy_description = var.policy_description 93 | } 94 | -------------------------------------------------------------------------------- /modules/kubernetes-dashboard/outputs.tf: -------------------------------------------------------------------------------- 1 | output "chart" { 2 | description = "The name of the chart" 3 | value = try(module.kubernetes_dashboard.chart, null) 4 | } 5 | 6 | output "name" { 7 | description = "Name is the name of the release" 8 | value = try(module.kubernetes_dashboard.name, null) 9 | } 10 | 11 | output "namespace" { 12 | description = "Name of Kubernetes namespace" 13 | value = try(module.kubernetes_dashboard.namespace, null) 14 | } 15 | 16 | output "revision" { 17 | description = "Version is an int32 which represents the version of the release" 18 | value = try(module.kubernetes_dashboard.revision, null) 19 | } 20 | 21 | output "version" { 22 | description = "A SemVer 2 conformant version string of the chart" 23 | value = try(module.kubernetes_dashboard.version, null) 24 | } 25 | 26 | output "app_version" { 27 | description = "The version number of the application being deployed" 28 | value = try(module.kubernetes_dashboard.app_version, null) 29 | } 30 | -------------------------------------------------------------------------------- /modules/kubernetes-manifests/chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | description: A place for all the Kubernetes resources which don't already have a home 3 | name: raw 4 | version: v0.3.2 5 | kubeVersion: ">=1.16.0-0" 6 | home: https://github.com/dysnix/charts/blob/master/dysnix/raw 7 | keywords: 8 | - raw 9 | - incubator 10 | - incubator-raw 11 | sources: 12 | - https://github.com/dysnix/charts/blob/master/dysnix/raw 13 | maintainers: 14 | - email: services@dysnix.com 15 | name: Dysnix 16 | -------------------------------------------------------------------------------- /modules/kubernetes-manifests/chart/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020-2021 Dysnix 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /modules/kubernetes-manifests/chart/README.md: -------------------------------------------------------------------------------- 1 | # dysnix/raw 2 | 3 | The [dysnix/raw](https://github.com/dysnix/charts/tree/main/dysnix/raw) chart takes a list of Kubernetes resources and merges each resource with a default `metadata.labels` map and installs the result. Use this chart to generate arbitrary Kubernetes manifests instead of kubectl and scripts ;) 4 | 5 | The Kubernetes resources can be "raw" ones defined under the `resources` key, or "templated" ones defined under the `templates` key. 6 | 7 | ## Usage 8 | 9 | ### Raw resources 10 | 11 | #### STEP 1: Create a yaml file containing your raw resources. 12 | 13 | Resources list can contain mixed types, i.e. include strings and maps simultaneously. 14 | 15 | ``` 16 | # raw-priority-classes.yaml 17 | resources: 18 | - apiVersion: scheduling.k8s.io/v1beta1 19 | kind: PriorityClass 20 | metadata: 21 | name: common-critical 22 | value: 100000000 23 | globalDefault: false 24 | description: "This priority class should only be used for critical priority common pods." 25 | - | 26 | apiVersion: scheduling.k8s.io/v1beta1 27 | kind: PriorityClass 28 | metadata: 29 | name: common-critical-from-string 30 | value: 100000000 31 | globalDefault: false 32 | description: "This priority class should only be used for critical priority common pods." 33 | ``` 34 | 35 | #### STEP 2: Install your raw resources. 36 | 37 | ``` 38 | helm install raw-priority-classes dysnix/raw -f raw-priority-classes.yaml 39 | ``` 40 | 41 | ### Templated resources 42 | 43 | #### STEP 1: Create a yaml file containing your templated resources. 44 | 45 | ``` 46 | # values.yaml 47 | 48 | templates: 49 | - | 50 | apiVersion: v1 51 | kind: Secret 52 | metadata: 53 | name: common-secret 54 | stringData: 55 | mykey: {{ .Values.mysecret }} 56 | ``` 57 | 58 | #### STEP 2: Install your templated resources. 59 | 60 | ``` 61 | helm install mysecret dysnix/raw -f values.yaml 62 | ``` 63 | -------------------------------------------------------------------------------- /modules/kubernetes-manifests/chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "raw.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "raw.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "raw.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | 34 | {{/* 35 | raw.resource will create a resource template that can be 36 | merged with each item in `.Values.resources`. 37 | */}} 38 | {{- define "raw.metadata" -}} 39 | metadata: 40 | labels: 41 | app: {{ template "raw.name" . }} 42 | chart: {{ template "raw.chart" . }} 43 | release: {{ .Release.Name }} 44 | heritage: {{ .Release.Service }} 45 | {{- end }} 46 | -------------------------------------------------------------------------------- /modules/kubernetes-manifests/chart/templates/resources.yaml: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{- $metadata := fromYaml (include "raw.metadata" .) -}} 3 | 4 | {{- $resources := list -}} 5 | {{- range .Values.resources }} 6 | {{- if typeIs "string" . }} 7 | {{/* Handle multi-part */}} 8 | {{- range . | splitList "---\n" }} 9 | {{- with . | fromYaml }} 10 | {{- $resources = append $resources . }} 11 | {{- end }} 12 | {{- end }} 13 | {{- else }} 14 | {{- $resources = append $resources . }} 15 | {{- end }} 16 | {{- end }} 17 | 18 | {{- $templates := list -}} 19 | {{- range .Values.templates }} 20 | {{/* Handle multi-part */}} 21 | {{- range . | splitList "---\n" }} 22 | {{- if . | fromYaml }} 23 | {{- $templates = append $templates . }} 24 | {{- end }} 25 | {{- end }} 26 | {{- end }} 27 | 28 | {{- range $resources }} 29 | --- 30 | {{ merge . $metadata | toYaml }} 31 | {{- end }} 32 | 33 | {{- range $templates }} 34 | --- 35 | {{ merge (tpl . $ | fromYaml) $metadata | toYaml }} 36 | {{- end }} 37 | -------------------------------------------------------------------------------- /modules/kubernetes-manifests/chart/values.yaml: -------------------------------------------------------------------------------- 1 | resources: [] 2 | # - apiVersion: scheduling.k8s.io/v1beta1 3 | # kind: PriorityClass 4 | # metadata: 5 | # name: app-low 6 | # value: 70000 7 | # globalDefault: false 8 | # description: "This priority class should only be used for low priority app pods." 9 | 10 | templates: [] 11 | # - | 12 | # apiVersion: v1 13 | # kind: Secret 14 | # metadata: 15 | # name: common-secret 16 | # stringData: 17 | # mykey: {{ .Values.mysecret }} 18 | -------------------------------------------------------------------------------- /modules/kubernetes-manifests/main.tf: -------------------------------------------------------------------------------- 1 | module "kubernetes_manifests" { 2 | source = "aws-ia/eks-blueprints-addon/aws" 3 | version = "~> 1.1" 4 | 5 | chart = "${path.module}/chart" 6 | 7 | create = var.create 8 | tags = var.tags 9 | create_release = var.create_release 10 | name = var.name 11 | description = var.description 12 | namespace = var.namespace 13 | create_namespace = var.create_namespace 14 | values = var.values 15 | timeout = var.timeout 16 | disable_webhooks = var.disable_webhooks 17 | reuse_values = var.reuse_values 18 | reset_values = var.reset_values 19 | force_update = var.force_update 20 | recreate_pods = var.recreate_pods 21 | cleanup_on_fail = var.cleanup_on_fail 22 | max_history = var.max_history 23 | atomic = var.atomic 24 | skip_crds = var.skip_crds 25 | render_subchart_notes = var.render_subchart_notes 26 | disable_openapi_validation = var.disable_openapi_validation 27 | wait = var.wait 28 | wait_for_jobs = var.wait_for_jobs 29 | replace = var.replace 30 | lint = var.lint 31 | postrender = var.postrender 32 | set = var.set 33 | set_sensitive = var.set_sensitive 34 | } 35 | -------------------------------------------------------------------------------- /modules/kubernetes-manifests/outputs.tf: -------------------------------------------------------------------------------- 1 | output "chart" { 2 | description = "The name of the chart" 3 | value = try(module.kubernetes_manifests.chart, null) 4 | } 5 | 6 | output "name" { 7 | description = "Name is the name of the release" 8 | value = try(module.kubernetes_manifests.name, null) 9 | } 10 | 11 | output "namespace" { 12 | description = "Name of Kubernetes namespace" 13 | value = try(module.kubernetes_manifests.namespace, null) 14 | } 15 | 16 | output "revision" { 17 | description = "Version is an int32 which represents the version of the release" 18 | value = try(module.kubernetes_manifests.revision, null) 19 | } 20 | 21 | output "version" { 22 | description = "A SemVer 2 conformant version string of the chart" 23 | value = try(module.kubernetes_manifests.version, null) 24 | } 25 | 26 | output "app_version" { 27 | description = "The version number of the application being deployed" 28 | value = try(module.kubernetes_manifests.app_version, null) 29 | } 30 | -------------------------------------------------------------------------------- /modules/kubernetes-manifests/variables.tf: -------------------------------------------------------------------------------- 1 | variable "create" { 2 | description = "Controls if resources should be created (affects all resources)" 3 | type = bool 4 | default = true 5 | } 6 | 7 | variable "tags" { 8 | description = "A map of tags to add to all resources" 9 | type = map(string) 10 | default = {} 11 | } 12 | 13 | ################################################################################ 14 | # Helm Release 15 | ################################################################################ 16 | 17 | variable "create_release" { 18 | description = "Determines whether the Helm release is created" 19 | type = bool 20 | default = true 21 | } 22 | 23 | variable "name" { 24 | description = "Name of the Helm release" 25 | type = string 26 | default = "" 27 | } 28 | 29 | variable "description" { 30 | description = "Set release description attribute (visible in the history)" 31 | type = string 32 | default = "" 33 | } 34 | 35 | variable "namespace" { 36 | description = "The namespace to install the release into. Defaults to `default`" 37 | type = string 38 | default = "default" 39 | } 40 | 41 | variable "create_namespace" { 42 | description = "Create the namespace if it does not yet exist. Defaults to `false`" 43 | type = bool 44 | default = true 45 | } 46 | 47 | variable "values" { 48 | description = "List of values in raw yaml to pass to helm. Values will be merged, in order, as Helm does with multiple `-f` options" 49 | type = list(string) 50 | default = null 51 | } 52 | 53 | variable "timeout" { 54 | description = "Time in seconds to wait for any individual kubernetes operation (like Jobs for hooks). Defaults to `300` seconds" 55 | type = number 56 | default = null 57 | } 58 | 59 | variable "disable_webhooks" { 60 | description = "Prevent hooks from running. Defaults to `false`" 61 | type = bool 62 | default = null 63 | } 64 | 65 | variable "reuse_values" { 66 | description = "When upgrading, reuse the last release's values and merge in any overrides. If `reset_values` is specified, this is ignored. Defaults to `false`" 67 | type = bool 68 | default = null 69 | } 70 | 71 | variable "reset_values" { 72 | description = "When upgrading, reset the values to the ones built into the chart. Defaults to `false`" 73 | type = bool 74 | default = true 75 | } 76 | 77 | variable "force_update" { 78 | description = "Force resource update through delete/recreate if needed. Defaults to `false`" 79 | type = bool 80 | default = null 81 | } 82 | 83 | variable "recreate_pods" { 84 | description = "Perform pods restart during upgrade/rollback. Defaults to `false`" 85 | type = bool 86 | default = null 87 | } 88 | 89 | variable "cleanup_on_fail" { 90 | description = "Allow deletion of new resources created in this upgrade when upgrade fails. Defaults to `false`" 91 | type = bool 92 | default = null 93 | } 94 | 95 | variable "max_history" { 96 | description = "Maximum number of release versions stored per release. Defaults to `0` (no limit)" 97 | type = number 98 | default = null 99 | } 100 | 101 | variable "atomic" { 102 | description = "If set, installation process purges chart on fail. The wait flag will be set automatically if atomic is used. Defaults to `false`" 103 | type = bool 104 | default = null 105 | } 106 | 107 | variable "skip_crds" { 108 | description = "If set, no CRDs will be installed. By default, CRDs are installed if not already present. Defaults to `false`" 109 | type = bool 110 | default = null 111 | } 112 | 113 | variable "render_subchart_notes" { 114 | description = "If set, render subchart notes along with the parent. Defaults to `true`" 115 | type = bool 116 | default = null 117 | } 118 | 119 | variable "disable_openapi_validation" { 120 | description = "If set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema. Defaults to `false`" 121 | type = bool 122 | default = null 123 | } 124 | 125 | variable "wait" { 126 | description = "Will wait until all resources are in a ready state before marking the release as successful. If set to `true`, it will wait for as long as `timeout`. If set to `null` fallback on `300s` timeout. Defaults to `false`" 127 | type = bool 128 | default = false 129 | } 130 | 131 | variable "wait_for_jobs" { 132 | description = "If wait is enabled, will wait until all Jobs have been completed before marking the release as successful. It will wait for as long as `timeout`. Defaults to `false`" 133 | type = bool 134 | default = null 135 | } 136 | 137 | variable "replace" { 138 | description = "Re-use the given name, only if that name is a deleted release which remains in the history. This is unsafe in production. Defaults to `false`" 139 | type = bool 140 | default = null 141 | } 142 | 143 | variable "lint" { 144 | description = "Run the helm chart linter during the plan. Defaults to `false`" 145 | type = bool 146 | default = null 147 | } 148 | 149 | variable "postrender" { 150 | description = "Configure a command to run after helm renders the manifest which can alter the manifest contents" 151 | type = any 152 | default = {} 153 | } 154 | 155 | variable "set" { 156 | description = "Value block with custom values to be merged with the values yaml" 157 | type = any 158 | default = [] 159 | } 160 | 161 | variable "set_sensitive" { 162 | description = "Value block with custom sensitive values to be merged with the values yaml that won't be exposed in the plan's diff" 163 | type = any 164 | default = [] 165 | } 166 | -------------------------------------------------------------------------------- /modules/nginx/main.tf: -------------------------------------------------------------------------------- 1 | # https://github.com/kubernetes/ingress-nginx/tree/main 2 | # https://kubernetes.github.io/ingress-nginx/ 3 | 4 | locals { 5 | # https://github.com/kubernetes/ingress-nginx/blob/main/charts/ingress-nginx/values.yaml 6 | values = [ 7 | <<-EOT 8 | controller: 9 | networkPolicy: 10 | enabled: true # default is false 11 | terminationGracePeriodSeconds: 300 12 | replicaCount: 1 # not HA, need to add autoscaling 13 | service: 14 | enabled: true 15 | external: 16 | enabled: true 17 | annotations: 18 | service.beta.kubernetes.io/aws-load-balancer-type: nlb 19 | type: LoadBalancer 20 | metrics: 21 | enabled: true 22 | EOT 23 | ] 24 | set = [] 25 | } 26 | 27 | module "ingress_nginx" { 28 | source = "aws-ia/eks-blueprints-addon/aws" 29 | version = "~> 1.1" 30 | 31 | set = concat( 32 | local.set, 33 | var.set 34 | ) 35 | 36 | values = concat( 37 | local.values, 38 | var.values 39 | ) 40 | 41 | create = var.create 42 | tags = var.tags 43 | create_release = var.create_release 44 | name = var.name 45 | description = var.description 46 | namespace = var.namespace 47 | create_namespace = var.create_namespace 48 | chart = var.chart 49 | chart_version = var.chart_version 50 | repository = var.repository 51 | timeout = var.timeout 52 | repository_key_file = var.repository_key_file 53 | repository_cert_file = var.repository_cert_file 54 | repository_ca_file = var.repository_ca_file 55 | repository_username = var.repository_username 56 | repository_password = var.repository_password 57 | devel = var.devel 58 | verify = var.verify 59 | keyring = var.keyring 60 | disable_webhooks = var.disable_webhooks 61 | reuse_values = var.reuse_values 62 | reset_values = var.reset_values 63 | force_update = var.force_update 64 | recreate_pods = var.recreate_pods 65 | cleanup_on_fail = var.cleanup_on_fail 66 | max_history = var.max_history 67 | atomic = var.atomic 68 | skip_crds = var.skip_crds 69 | render_subchart_notes = var.render_subchart_notes 70 | disable_openapi_validation = var.disable_openapi_validation 71 | wait = var.wait 72 | wait_for_jobs = var.wait_for_jobs 73 | dependency_update = var.dependency_update 74 | replace = var.replace 75 | lint = var.lint 76 | postrender = var.postrender 77 | set_sensitive = var.set_sensitive 78 | set_irsa_names = var.set_irsa_names 79 | create_role = var.create_role 80 | role_name = var.role_name 81 | role_name_use_prefix = var.role_name_use_prefix 82 | role_path = var.role_path 83 | role_permissions_boundary_arn = var.role_permissions_boundary_arn 84 | role_description = var.role_description 85 | role_policies = var.role_policies 86 | oidc_providers = var.oidc_providers 87 | max_session_duration = var.max_session_duration 88 | assume_role_condition_test = var.assume_role_condition_test 89 | allow_self_assume_role = var.allow_self_assume_role 90 | create_policy = var.create_policy 91 | source_policy_documents = var.source_policy_documents 92 | override_policy_documents = var.override_policy_documents 93 | policy_statements = var.policy_statements 94 | policy_name = var.policy_name 95 | policy_name_use_prefix = var.policy_name_use_prefix 96 | policy_path = var.policy_path 97 | policy_description = var.policy_description 98 | } 99 | -------------------------------------------------------------------------------- /modules/nginx/outputs.tf: -------------------------------------------------------------------------------- 1 | output "chart" { 2 | description = "The name of the chart" 3 | value = try(module.ingress_nginx.chart, null) 4 | } 5 | 6 | output "name" { 7 | description = "Name is the name of the release" 8 | value = try(module.ingress_nginx.name, null) 9 | } 10 | 11 | output "namespace" { 12 | description = "Name of Kubernetes namespace" 13 | value = try(module.ingress_nginx.namespace, null) 14 | } 15 | 16 | output "revision" { 17 | description = "Version is an int32 which represents the version of the release" 18 | value = try(module.ingress_nginx.revision, null) 19 | } 20 | 21 | output "version" { 22 | description = "A SemVer 2 conformant version string of the chart" 23 | value = try(module.ingress_nginx.version, null) 24 | } 25 | 26 | output "app_version" { 27 | description = "The version number of the application being deployed" 28 | value = try(module.ingress_nginx.app_version, null) 29 | } 30 | -------------------------------------------------------------------------------- /modules/nginx/variables.tf: -------------------------------------------------------------------------------- 1 | variable "create" { 2 | description = "Controls if resources should be created (affects all resources)" 3 | type = bool 4 | default = true 5 | } 6 | 7 | variable "tags" { 8 | description = "A map of tags to add to all resources" 9 | type = map(string) 10 | default = {} 11 | } 12 | 13 | ################################################################################ 14 | # Helm Release 15 | ################################################################################ 16 | 17 | variable "create_release" { 18 | description = "Determines whether the Helm release is created" 19 | type = bool 20 | default = true 21 | } 22 | 23 | variable "name" { 24 | description = "Name of the Helm release" 25 | type = string 26 | default = "" 27 | } 28 | 29 | variable "description" { 30 | description = "Set release description attribute (visible in the history)" 31 | type = string 32 | default = "Nginx ingress helm Chart deployment configuration" 33 | } 34 | 35 | variable "namespace" { 36 | description = "The namespace to install the release into. Defaults to `default`" 37 | type = string 38 | default = "ingress-nginx" 39 | } 40 | 41 | variable "create_namespace" { 42 | description = "Create the namespace if it does not yet exist. Defaults to `false`" 43 | type = bool 44 | default = true 45 | } 46 | 47 | variable "chart" { 48 | description = "Chart name to be installed. The chart name can be local path, a URL to a chart, or the name of the chart if `repository` is specified" 49 | type = string 50 | default = "ingress-nginx" 51 | } 52 | 53 | variable "chart_version" { 54 | description = "Specify the exact chart version to install. If this is not specified, the latest version is installed" 55 | type = string 56 | default = null 57 | } 58 | 59 | variable "repository" { 60 | description = "Repository URL where to locate the requested chart" 61 | type = string 62 | default = "https://kubernetes.github.io/ingress-nginx" 63 | } 64 | 65 | variable "values" { 66 | description = "List of values in raw yaml to pass to helm. Values will be merged, in order, as Helm does with multiple `-f` options" 67 | type = list(string) 68 | default = null 69 | } 70 | 71 | variable "timeout" { 72 | description = "Time in seconds to wait for any individual kubernetes operation (like Jobs for hooks). Defaults to `300` seconds" 73 | type = number 74 | default = null 75 | } 76 | 77 | variable "repository_key_file" { 78 | description = "The repositories cert key file" 79 | type = string 80 | default = null 81 | } 82 | 83 | variable "repository_cert_file" { 84 | description = "The repositories cert file" 85 | type = string 86 | default = null 87 | } 88 | 89 | variable "repository_ca_file" { 90 | description = "The Repositories CA File" 91 | type = string 92 | default = null 93 | } 94 | 95 | variable "repository_username" { 96 | description = "Username for HTTP basic authentication against the repository" 97 | type = string 98 | default = null 99 | } 100 | 101 | variable "repository_password" { 102 | description = "Password for HTTP basic authentication against the repository" 103 | type = string 104 | default = null 105 | } 106 | 107 | variable "devel" { 108 | description = "Use chart development versions, too. Equivalent to version '>0.0.0-0'. If version is set, this is ignored" 109 | type = bool 110 | default = null 111 | } 112 | 113 | variable "verify" { 114 | description = "Verify the package before installing it. Helm uses a provenance file to verify the integrity of the chart; this must be hosted alongside the chart. For more information see the Helm Documentation. Defaults to `false`" 115 | type = bool 116 | default = null 117 | } 118 | 119 | variable "keyring" { 120 | description = "Location of public keys used for verification. Used only if verify is true. Defaults to `/.gnupg/pubring.gpg` in the location set by `home`" 121 | type = string 122 | default = null 123 | } 124 | 125 | variable "disable_webhooks" { 126 | description = "Prevent hooks from running. Defaults to `false`" 127 | type = bool 128 | default = null 129 | } 130 | 131 | variable "reuse_values" { 132 | description = "When upgrading, reuse the last release's values and merge in any overrides. If `reset_values` is specified, this is ignored. Defaults to `false`" 133 | type = bool 134 | default = null 135 | } 136 | 137 | variable "reset_values" { 138 | description = "When upgrading, reset the values to the ones built into the chart. Defaults to `false`" 139 | type = bool 140 | default = true 141 | } 142 | 143 | variable "force_update" { 144 | description = "Force resource update through delete/recreate if needed. Defaults to `false`" 145 | type = bool 146 | default = null 147 | } 148 | 149 | variable "recreate_pods" { 150 | description = "Perform pods restart during upgrade/rollback. Defaults to `false`" 151 | type = bool 152 | default = null 153 | } 154 | 155 | variable "cleanup_on_fail" { 156 | description = "Allow deletion of new resources created in this upgrade when upgrade fails. Defaults to `false`" 157 | type = bool 158 | default = null 159 | } 160 | 161 | variable "max_history" { 162 | description = "Maximum number of release versions stored per release. Defaults to `0` (no limit)" 163 | type = number 164 | default = null 165 | } 166 | 167 | variable "atomic" { 168 | description = "If set, installation process purges chart on fail. The wait flag will be set automatically if atomic is used. Defaults to `false`" 169 | type = bool 170 | default = null 171 | } 172 | 173 | variable "skip_crds" { 174 | description = "If set, no CRDs will be installed. By default, CRDs are installed if not already present. Defaults to `false`" 175 | type = bool 176 | default = null 177 | } 178 | 179 | variable "render_subchart_notes" { 180 | description = "If set, render subchart notes along with the parent. Defaults to `true`" 181 | type = bool 182 | default = null 183 | } 184 | 185 | variable "disable_openapi_validation" { 186 | description = "If set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema. Defaults to `false`" 187 | type = bool 188 | default = null 189 | } 190 | 191 | variable "wait" { 192 | description = "Will wait until all resources are in a ready state before marking the release as successful. If set to `true`, it will wait for as long as `timeout`. If set to `null` fallback on `300s` timeout. Defaults to `false`" 193 | type = bool 194 | default = false 195 | } 196 | 197 | variable "wait_for_jobs" { 198 | description = "If wait is enabled, will wait until all Jobs have been completed before marking the release as successful. It will wait for as long as `timeout`. Defaults to `false`" 199 | type = bool 200 | default = null 201 | } 202 | 203 | variable "dependency_update" { 204 | description = "Runs helm dependency update before installing the chart. Defaults to `false`" 205 | type = bool 206 | default = null 207 | } 208 | 209 | variable "replace" { 210 | description = "Re-use the given name, only if that name is a deleted release which remains in the history. This is unsafe in production. Defaults to `false`" 211 | type = bool 212 | default = null 213 | } 214 | 215 | variable "lint" { 216 | description = "Run the helm chart linter during the plan. Defaults to `false`" 217 | type = bool 218 | default = null 219 | } 220 | 221 | variable "postrender" { 222 | description = "Configure a command to run after helm renders the manifest which can alter the manifest contents" 223 | type = any 224 | default = {} 225 | } 226 | 227 | variable "set" { 228 | description = "Value block with custom values to be merged with the values yaml" 229 | type = any 230 | default = [] 231 | } 232 | 233 | variable "set_sensitive" { 234 | description = "Value block with custom sensitive values to be merged with the values yaml that won't be exposed in the plan's diff" 235 | type = any 236 | default = [] 237 | } 238 | 239 | variable "set_irsa_names" { 240 | description = "Value annotations name where IRSA role ARN created by module will be assigned to the `value`" 241 | type = list(string) 242 | default = [] 243 | } 244 | 245 | ################################################################################ 246 | # IAM Role for Service Account(s) (IRSA) 247 | ################################################################################ 248 | 249 | variable "create_role" { 250 | description = "Determines whether to create an IAM role" 251 | type = bool 252 | default = false 253 | } 254 | 255 | variable "role_name" { 256 | description = "Name of IAM role" 257 | type = string 258 | default = null 259 | } 260 | 261 | variable "role_name_use_prefix" { 262 | description = "Determines whether the IAM role name (`role_name`) is used as a prefix" 263 | type = bool 264 | default = true 265 | } 266 | 267 | variable "role_path" { 268 | description = "Path of IAM role" 269 | type = string 270 | default = "/" 271 | } 272 | 273 | variable "role_permissions_boundary_arn" { 274 | description = "Permissions boundary ARN to use for IAM role" 275 | type = string 276 | default = null 277 | } 278 | 279 | variable "role_description" { 280 | description = "IAM Role description" 281 | type = string 282 | default = null 283 | } 284 | 285 | variable "role_policies" { 286 | description = "Policies to attach to the IAM role in `{'static_name' = 'policy_arn'}` format" 287 | type = map(string) 288 | default = {} 289 | } 290 | 291 | variable "oidc_providers" { 292 | description = "Map of OIDC providers where each provider map should contain the `provider_arn`, and `service_accounts`" 293 | type = any 294 | default = {} 295 | } 296 | 297 | variable "max_session_duration" { 298 | description = "Maximum CLI/API session duration in seconds between 3600 and 43200" 299 | type = number 300 | default = null 301 | } 302 | 303 | variable "assume_role_condition_test" { 304 | description = "Name of the [IAM condition operator](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html) to evaluate when assuming the role" 305 | type = string 306 | default = "StringEquals" 307 | } 308 | 309 | variable "allow_self_assume_role" { 310 | description = "Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/)" 311 | type = bool 312 | default = false 313 | } 314 | 315 | ################################################################################ 316 | # IAM Policy 317 | ################################################################################ 318 | 319 | variable "create_policy" { 320 | description = "Whether to create an IAM policy that is attached to the IAM role created" 321 | type = bool 322 | default = true 323 | } 324 | 325 | variable "source_policy_documents" { 326 | description = "List of IAM policy documents that are merged together into the exported document. Statements must have unique `sid`s" 327 | type = list(string) 328 | default = [] 329 | } 330 | 331 | variable "override_policy_documents" { 332 | description = "List of IAM policy documents that are merged together into the exported document. In merging, statements with non-blank `sid`s will override statements with the same `sid`" 333 | type = list(string) 334 | default = [] 335 | } 336 | 337 | variable "policy_statements" { 338 | description = "List of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement)" 339 | type = any 340 | default = [] 341 | } 342 | 343 | variable "policy_name" { 344 | description = "Name of IAM policy" 345 | type = string 346 | default = null 347 | } 348 | 349 | variable "policy_name_use_prefix" { 350 | description = "Determines whether the IAM policy name (`policy_name`) is used as a prefix" 351 | type = bool 352 | default = true 353 | } 354 | 355 | variable "policy_path" { 356 | description = "Path of IAM policy" 357 | type = string 358 | default = null 359 | } 360 | 361 | variable "policy_description" { 362 | description = "IAM policy description" 363 | type = string 364 | default = null 365 | } 366 | -------------------------------------------------------------------------------- /modules/openobserve-collector/main.tf: -------------------------------------------------------------------------------- 1 | 2 | locals { 3 | 4 | # https://github.com/openobserve/openobserve-helm-chart/blob/main/charts/openobserve-collector/values.yaml 5 | values = [ 6 | <<-EOT 7 | exporters: 8 | otlphttp/openobserve: 9 | endpoint: ${var.zo_endpoint} 10 | headers: 11 | Authorization: ${var.zo_authorization} 12 | otlphttp/openobserve_k8s_events: 13 | endpoint: ${var.zo_endpoint} 14 | headers: 15 | Authorization: ${var.zo_authorization} 16 | stream-name: k8s_events 17 | EOT 18 | ] 19 | set = [] 20 | } 21 | 22 | module "openobserve-collector" { 23 | source = "aws-ia/eks-blueprints-addon/aws" 24 | version = "~> 1.1" 25 | 26 | set = var.set 27 | 28 | values = concat( 29 | local.values, 30 | var.values 31 | ) 32 | 33 | create = var.create 34 | tags = var.tags 35 | create_release = var.create_release 36 | name = var.name 37 | description = var.description 38 | namespace = var.namespace 39 | create_namespace = var.create_namespace 40 | chart = var.chart 41 | chart_version = var.chart_version 42 | repository = var.repository 43 | timeout = var.timeout 44 | repository_key_file = var.repository_key_file 45 | repository_cert_file = var.repository_cert_file 46 | repository_ca_file = var.repository_ca_file 47 | repository_username = var.repository_username 48 | repository_password = var.repository_password 49 | devel = var.devel 50 | verify = var.verify 51 | keyring = var.keyring 52 | disable_webhooks = var.disable_webhooks 53 | reuse_values = var.reuse_values 54 | reset_values = var.reset_values 55 | force_update = var.force_update 56 | recreate_pods = var.recreate_pods 57 | cleanup_on_fail = var.cleanup_on_fail 58 | max_history = var.max_history 59 | atomic = var.atomic 60 | skip_crds = var.skip_crds 61 | render_subchart_notes = var.render_subchart_notes 62 | disable_openapi_validation = var.disable_openapi_validation 63 | wait = var.wait 64 | wait_for_jobs = var.wait_for_jobs 65 | dependency_update = var.dependency_update 66 | replace = var.replace 67 | lint = var.lint 68 | postrender = var.postrender 69 | set_sensitive = var.set_sensitive 70 | set_irsa_names = var.set_irsa_names 71 | create_role = var.create_role 72 | role_name = var.role_name 73 | role_name_use_prefix = var.role_name_use_prefix 74 | role_path = var.role_path 75 | role_permissions_boundary_arn = var.role_permissions_boundary_arn 76 | role_description = var.role_description 77 | role_policies = var.role_policies 78 | oidc_providers = var.oidc_providers 79 | max_session_duration = var.max_session_duration 80 | assume_role_condition_test = var.assume_role_condition_test 81 | allow_self_assume_role = var.allow_self_assume_role 82 | create_policy = var.create_policy 83 | source_policy_documents = var.source_policy_documents 84 | override_policy_documents = var.override_policy_documents 85 | policy_statements = var.policy_statements 86 | policy_name = var.policy_name 87 | policy_name_use_prefix = var.policy_name_use_prefix 88 | policy_path = var.policy_path 89 | policy_description = var.policy_description 90 | } 91 | -------------------------------------------------------------------------------- /modules/openobserve-collector/outputs.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Helm Release 3 | ################################################################################ 4 | 5 | output "chart" { 6 | description = "The name of the chart" 7 | value = try(module.openobserve-collector.chart, null) 8 | } 9 | 10 | output "name" { 11 | description = "Name is the name of the release" 12 | value = try(module.openobserve-collector.name, null) 13 | } 14 | 15 | output "namespace" { 16 | description = "Name of Kubernetes namespace" 17 | value = try(module.openobserve-collector.namespace, null) 18 | } 19 | 20 | output "revision" { 21 | description = "Version is an int32 which represents the version of the release" 22 | value = try(module.openobserve-collector.revision, null) 23 | } 24 | 25 | output "version" { 26 | description = "A SemVer 2 conformant version string of the chart" 27 | value = try(module.openobserve-collector.version, null) 28 | } 29 | 30 | output "app_version" { 31 | description = "The version number of the application being deployed" 32 | value = try(module.openobserve-collector.app_version, null) 33 | } 34 | 35 | # output "values" { 36 | # description = "The compounded values from `values` and `set*` attributes" 37 | # value = try(module.openobserve-collector.values, []) 38 | # } 39 | 40 | ################################################################################ 41 | # IAM Role for Service Account(s) (IRSA) 42 | ################################################################################ 43 | 44 | output "iam_role_arn" { 45 | description = "ARN of IAM role" 46 | value = try(module.openobserve-collector.iam_role_arn, null) 47 | } 48 | 49 | output "iam_role_name" { 50 | description = "Name of IAM role" 51 | value = try(module.openobserve-collector.iam_role_name, null) 52 | } 53 | 54 | output "iam_role_path" { 55 | description = "Path of IAM role" 56 | value = try(module.openobserve-collector.iam_role_name, null) 57 | } 58 | 59 | output "iam_role_unique_id" { 60 | description = "Unique ID of IAM role" 61 | value = try(module.openobserve-collector.iam_role_unique_id, null) 62 | } 63 | 64 | ################################################################################ 65 | # IAM Policy 66 | ################################################################################ 67 | 68 | output "iam_policy_arn" { 69 | description = "The ARN assigned by AWS to this policy" 70 | value = try(module.openobserve-collector.iam_policy_arn, null) 71 | } 72 | 73 | output "iam_policy" { 74 | description = "The policy document" 75 | value = try(module.openobserve-collector.iam_policy, null) 76 | } 77 | -------------------------------------------------------------------------------- /modules/openobserve/main.tf: -------------------------------------------------------------------------------- 1 | data "aws_region" "current" {} 2 | 3 | locals { 4 | zo_root_user_password = coalesce(var.zo_root_user_password, random_password.openobserve_root_password.result) 5 | 6 | # https://openobserve.ai/docs/environment-variables/ 7 | # https://github.com/openobserve/openobserve-helm-chart/blob/main/charts/openobserve-standalone/values.yaml 8 | values = [ 9 | <<-EOT 10 | auth: 11 | ZO_ROOT_USER_EMAIL: ${var.zo_root_user_email} 12 | ZO_ROOT_USER_PASSWORD: ${local.zo_root_user_password} 13 | serviceAccount: 14 | create: true 15 | name: "openobserve" 16 | annotations: 17 | eks.amazonaws.com/role-arn: ${module.role.iam_role_arn} 18 | config: 19 | ZO_LOCAL_MODE_STORAGE: "s3" 20 | # https://github.com/openobserve/openobserve-helm-chart/issues/38 21 | # ZO_META_STORE: "dynamodb" 22 | ZO_META_DYNAMO_PREFIX: ${aws_s3_bucket.openobserve.id} 23 | ZO_TELEMETRY: "false" 24 | ZO_PROMETHEUS_ENABLED: "true" 25 | ZO_S3_REGION_NAME: ${data.aws_region.current.name} 26 | ZO_S3_BUCKET_NAME: ${aws_s3_bucket.openobserve.id} 27 | ZO_S3_PROVIDER: "aws" 28 | # RUST_LOG: "debug" 29 | # RUST_BACKTRACE: "full" 30 | EOT 31 | ] 32 | set = [] 33 | } 34 | 35 | resource "random_password" "openobserve_root_password" { 36 | length = 32 37 | special = false 38 | } 39 | 40 | # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket 41 | resource "aws_s3_bucket" "openobserve" { 42 | bucket_prefix = "openobserve-" 43 | 44 | tags = { 45 | Name = "openobserve" 46 | Terraform = "openobserve" 47 | Environment = "management" 48 | } 49 | 50 | # change it for deleting bucket with all content 51 | force_destroy = false 52 | } 53 | 54 | resource "aws_s3_bucket_versioning" "openobserve" { 55 | bucket = aws_s3_bucket.openobserve.id 56 | versioning_configuration { 57 | status = "Disabled" 58 | } 59 | } 60 | 61 | resource "aws_s3_bucket_server_side_encryption_configuration" "openobserve" { 62 | bucket = aws_s3_bucket.openobserve.id 63 | 64 | rule { 65 | apply_server_side_encryption_by_default { 66 | sse_algorithm = "AES256" 67 | } 68 | } 69 | } 70 | 71 | resource "aws_s3_bucket_public_access_block" "openobserve" { 72 | bucket = aws_s3_bucket.openobserve.id 73 | block_public_acls = true 74 | block_public_policy = true 75 | ignore_public_acls = true 76 | restrict_public_buckets = true 77 | } 78 | 79 | resource "aws_iam_policy" "openobserve" { 80 | name = aws_s3_bucket.openobserve.id 81 | path = "/" 82 | description = "Policy for ${aws_s3_bucket.openobserve.id} to list S3 buckets, and read/write specific S3 bucket and DynamoDB table" 83 | 84 | policy = jsonencode({ 85 | Version = "2012-10-17", 86 | Statement = [ 87 | { 88 | Effect = "Allow", 89 | Action = [ 90 | "s3:ListAllMyBuckets" 91 | ], 92 | Resource = "*" 93 | }, 94 | { 95 | Effect = "Allow", 96 | Action = [ 97 | "s3:ListBucket", 98 | "s3:GetBucketLocation" 99 | ], 100 | Resource = "*" 101 | }, 102 | { 103 | Effect = "Allow", 104 | Action = [ 105 | "s3:*" 106 | ], 107 | Resource = [ 108 | "${aws_s3_bucket.openobserve.arn}/*", 109 | "${aws_s3_bucket.openobserve.arn}" 110 | ] 111 | }, 112 | { 113 | Effect = "Allow", 114 | Action = [ 115 | "dynamodb:*" 116 | ], 117 | Resource = "arn:aws:dynamodb:*:*:table/${aws_s3_bucket.openobserve.id}*" 118 | }, 119 | { 120 | Effect = "Allow", 121 | Action = [ 122 | "dynamodb:ListTables" 123 | ], 124 | Resource = "arn:aws:dynamodb:*:*:table*" 125 | }, 126 | ] 127 | }) 128 | } 129 | 130 | module "role" { 131 | source = "aws-ia/eks-blueprints-addon/aws" 132 | version = "~> 1.1" 133 | 134 | # Disable helm release 135 | create_release = false 136 | 137 | # IAM role for service account (IRSA) 138 | create_role = true 139 | create_policy = false 140 | role_name = "openobserve" 141 | role_policies = merge( 142 | { 143 | openobserve = aws_iam_policy.openobserve.arn 144 | }, 145 | var.role_policies 146 | ) 147 | 148 | oidc_providers = merge( 149 | { 150 | openobserve = { 151 | provider_arn = var.oidc_provider_arn 152 | namespace = var.namespace 153 | service_account = "openobserve" 154 | } 155 | }, 156 | var.oidc_providers 157 | ) 158 | 159 | create = var.create 160 | tags = var.tags 161 | } 162 | 163 | module "openobserve" { 164 | source = "aws-ia/eks-blueprints-addon/aws" 165 | version = "~> 1.1" 166 | 167 | set = var.set 168 | 169 | values = concat( 170 | local.values, 171 | var.values 172 | ) 173 | 174 | create = var.create 175 | tags = var.tags 176 | create_release = var.create_release 177 | name = var.name 178 | description = var.description 179 | namespace = var.namespace 180 | create_namespace = var.create_namespace 181 | chart = var.chart 182 | chart_version = var.chart_version 183 | repository = var.repository 184 | timeout = var.timeout 185 | repository_key_file = var.repository_key_file 186 | repository_cert_file = var.repository_cert_file 187 | repository_ca_file = var.repository_ca_file 188 | repository_username = var.repository_username 189 | repository_password = var.repository_password 190 | devel = var.devel 191 | verify = var.verify 192 | keyring = var.keyring 193 | disable_webhooks = var.disable_webhooks 194 | reuse_values = var.reuse_values 195 | reset_values = var.reset_values 196 | force_update = var.force_update 197 | recreate_pods = var.recreate_pods 198 | cleanup_on_fail = var.cleanup_on_fail 199 | max_history = var.max_history 200 | atomic = var.atomic 201 | skip_crds = var.skip_crds 202 | render_subchart_notes = var.render_subchart_notes 203 | disable_openapi_validation = var.disable_openapi_validation 204 | wait = var.wait 205 | wait_for_jobs = var.wait_for_jobs 206 | dependency_update = var.dependency_update 207 | replace = var.replace 208 | lint = var.lint 209 | postrender = var.postrender 210 | set_sensitive = var.set_sensitive 211 | set_irsa_names = var.set_irsa_names 212 | role_path = var.role_path 213 | role_permissions_boundary_arn = var.role_permissions_boundary_arn 214 | role_description = var.role_description 215 | max_session_duration = var.max_session_duration 216 | assume_role_condition_test = var.assume_role_condition_test 217 | allow_self_assume_role = var.allow_self_assume_role 218 | } 219 | -------------------------------------------------------------------------------- /modules/openobserve/outputs.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Helm Release 3 | ################################################################################ 4 | 5 | output "chart" { 6 | description = "The name of the chart" 7 | value = try(module.openobserve.chart, null) 8 | } 9 | 10 | output "name" { 11 | description = "Name is the name of the release" 12 | value = try(module.openobserve.name, null) 13 | } 14 | 15 | output "namespace" { 16 | description = "Name of Kubernetes namespace" 17 | value = try(module.openobserve.namespace, null) 18 | } 19 | 20 | output "revision" { 21 | description = "Version is an int32 which represents the version of the release" 22 | value = try(module.openobserve.revision, null) 23 | } 24 | 25 | output "version" { 26 | description = "A SemVer 2 conformant version string of the chart" 27 | value = try(module.openobserve.version, null) 28 | } 29 | 30 | output "app_version" { 31 | description = "The version number of the application being deployed" 32 | value = try(module.openobserve.app_version, null) 33 | } 34 | 35 | # output "values" { 36 | # description = "The compounded values from `values` and `set*` attributes" 37 | # value = try(module.openobserve.values, []) 38 | # } 39 | 40 | ################################################################################ 41 | # IAM Role for Service Account(s) (IRSA) 42 | ################################################################################ 43 | 44 | output "iam_role_arn" { 45 | description = "ARN of IAM role" 46 | value = try(module.role.iam_role_arn, null) 47 | } 48 | 49 | output "iam_role_name" { 50 | description = "Name of IAM role" 51 | value = try(module.role.iam_role_name, null) 52 | } 53 | 54 | output "iam_role_path" { 55 | description = "Path of IAM role" 56 | value = try(module.role.iam_role_name, null) 57 | } 58 | 59 | output "iam_role_unique_id" { 60 | description = "Unique ID of IAM role" 61 | value = try(module.role.iam_role_unique_id, null) 62 | } 63 | 64 | ################################################################################ 65 | # IAM Policy 66 | ################################################################################ 67 | 68 | output "iam_policy_arn" { 69 | description = "The ARN assigned by AWS to this policy" 70 | value = try(module.role.iam_policy_arn, null) 71 | } 72 | 73 | output "iam_policy" { 74 | description = "The policy document" 75 | value = try(module.role.iam_policy, null) 76 | } 77 | 78 | ################################################################################ 79 | # OpenObserve 80 | ################################################################################ 81 | 82 | output "zo_root_user_password" { 83 | description = "The openobserve root password" 84 | value = local.zo_root_user_password 85 | sensitive = true 86 | } 87 | -------------------------------------------------------------------------------- /modules/openobserve/variables.tf: -------------------------------------------------------------------------------- 1 | variable "zo_root_user_email" { 2 | description = "auth.ZO_ROOT_USER_EMAIL helm chart value" 3 | type = string 4 | } 5 | 6 | variable "zo_root_user_password" { 7 | description = "auth.ZO_ROOT_USER_PASSWORD helm chart value" 8 | type = string 9 | default = null 10 | } 11 | 12 | variable "create" { 13 | description = "Controls if resources should be created (affects all resources)" 14 | type = bool 15 | default = true 16 | } 17 | 18 | variable "tags" { 19 | description = "A map of tags to add to all resources" 20 | type = map(string) 21 | default = {} 22 | } 23 | 24 | ################################################################################ 25 | # Helm Release 26 | ################################################################################ 27 | 28 | variable "create_release" { 29 | description = "Determines whether the Helm release is created" 30 | type = bool 31 | default = true 32 | } 33 | 34 | variable "name" { 35 | description = "Name of the Helm release" 36 | type = string 37 | default = "" 38 | } 39 | 40 | variable "description" { 41 | description = "Set release description attribute (visible in the history)" 42 | type = string 43 | default = "OpenObserve monitoring server" 44 | } 45 | 46 | variable "namespace" { 47 | description = "The namespace to install the release into. Defaults to `default`" 48 | type = string 49 | default = "openobserve" 50 | } 51 | 52 | variable "create_namespace" { 53 | description = "Create the namespace if it does not yet exist. Defaults to `false`" 54 | type = bool 55 | default = true 56 | } 57 | 58 | variable "chart" { 59 | description = "Chart name to be installed. The chart name can be local path, a URL to a chart, or the name of the chart if `repository` is specified" 60 | type = string 61 | default = "openobserve-standalone" 62 | } 63 | 64 | variable "chart_version" { 65 | description = "Specify the exact chart version to install. If this is not specified, the latest version is installed" 66 | type = string 67 | default = null 68 | } 69 | 70 | variable "repository" { 71 | description = "Repository URL where to locate the requested chart" 72 | type = string 73 | default = "https://charts.openobserve.ai" 74 | } 75 | 76 | variable "values" { 77 | description = "List of values in raw yaml to pass to helm. Values will be merged, in order, as Helm does with multiple `-f` options" 78 | type = list(string) 79 | default = null 80 | } 81 | 82 | variable "timeout" { 83 | description = "Time in seconds to wait for any individual kubernetes operation (like Jobs for hooks). Defaults to `300` seconds" 84 | type = number 85 | default = null 86 | } 87 | 88 | variable "repository_key_file" { 89 | description = "The repositories cert key file" 90 | type = string 91 | default = null 92 | } 93 | 94 | variable "repository_cert_file" { 95 | description = "The repositories cert file" 96 | type = string 97 | default = null 98 | } 99 | 100 | variable "repository_ca_file" { 101 | description = "The Repositories CA File" 102 | type = string 103 | default = null 104 | } 105 | 106 | variable "repository_username" { 107 | description = "Username for HTTP basic authentication against the repository" 108 | type = string 109 | default = null 110 | } 111 | 112 | variable "repository_password" { 113 | description = "Password for HTTP basic authentication against the repository" 114 | type = string 115 | default = null 116 | } 117 | 118 | variable "devel" { 119 | description = "Use chart development versions, too. Equivalent to version '>0.0.0-0'. If version is set, this is ignored" 120 | type = bool 121 | default = null 122 | } 123 | 124 | variable "verify" { 125 | description = "Verify the package before installing it. Helm uses a provenance file to verify the integrity of the chart; this must be hosted alongside the chart. For more information see the Helm Documentation. Defaults to `false`" 126 | type = bool 127 | default = null 128 | } 129 | 130 | variable "keyring" { 131 | description = "Location of public keys used for verification. Used only if verify is true. Defaults to `/.gnupg/pubring.gpg` in the location set by `home`" 132 | type = string 133 | default = null 134 | } 135 | 136 | variable "disable_webhooks" { 137 | description = "Prevent hooks from running. Defaults to `false`" 138 | type = bool 139 | default = null 140 | } 141 | 142 | variable "reuse_values" { 143 | description = "When upgrading, reuse the last release's values and merge in any overrides. If `reset_values` is specified, this is ignored. Defaults to `false`" 144 | type = bool 145 | default = null 146 | } 147 | 148 | variable "reset_values" { 149 | description = "When upgrading, reset the values to the ones built into the chart. Defaults to `false`" 150 | type = bool 151 | default = true 152 | } 153 | 154 | variable "force_update" { 155 | description = "Force resource update through delete/recreate if needed. Defaults to `false`" 156 | type = bool 157 | default = null 158 | } 159 | 160 | variable "recreate_pods" { 161 | description = "Perform pods restart during upgrade/rollback. Defaults to `false`" 162 | type = bool 163 | default = null 164 | } 165 | 166 | variable "cleanup_on_fail" { 167 | description = "Allow deletion of new resources created in this upgrade when upgrade fails. Defaults to `false`" 168 | type = bool 169 | default = null 170 | } 171 | 172 | variable "max_history" { 173 | description = "Maximum number of release versions stored per release. Defaults to `0` (no limit)" 174 | type = number 175 | default = null 176 | } 177 | 178 | variable "atomic" { 179 | description = "If set, installation process purges chart on fail. The wait flag will be set automatically if atomic is used. Defaults to `false`" 180 | type = bool 181 | default = null 182 | } 183 | 184 | variable "skip_crds" { 185 | description = "If set, no CRDs will be installed. By default, CRDs are installed if not already present. Defaults to `false`" 186 | type = bool 187 | default = null 188 | } 189 | 190 | variable "render_subchart_notes" { 191 | description = "If set, render subchart notes along with the parent. Defaults to `true`" 192 | type = bool 193 | default = null 194 | } 195 | 196 | variable "disable_openapi_validation" { 197 | description = "If set, the installation process will not validate rendered templates against the Kubernetes OpenAPI Schema. Defaults to `false`" 198 | type = bool 199 | default = null 200 | } 201 | 202 | variable "wait" { 203 | description = "Will wait until all resources are in a ready state before marking the release as successful. If set to `true`, it will wait for as long as `timeout`. If set to `null` fallback on `300s` timeout. Defaults to `false`" 204 | type = bool 205 | default = false 206 | } 207 | 208 | variable "wait_for_jobs" { 209 | description = "If wait is enabled, will wait until all Jobs have been completed before marking the release as successful. It will wait for as long as `timeout`. Defaults to `false`" 210 | type = bool 211 | default = null 212 | } 213 | 214 | variable "dependency_update" { 215 | description = "Runs helm dependency update before installing the chart. Defaults to `false`" 216 | type = bool 217 | default = null 218 | } 219 | 220 | variable "replace" { 221 | description = "Re-use the given name, only if that name is a deleted release which remains in the history. This is unsafe in production. Defaults to `false`" 222 | type = bool 223 | default = null 224 | } 225 | 226 | variable "lint" { 227 | description = "Run the helm chart linter during the plan. Defaults to `false`" 228 | type = bool 229 | default = null 230 | } 231 | 232 | variable "postrender" { 233 | description = "Configure a command to run after helm renders the manifest which can alter the manifest contents" 234 | type = any 235 | default = {} 236 | } 237 | 238 | variable "set" { 239 | description = "Value block with custom values to be merged with the values yaml" 240 | type = any 241 | default = [] 242 | } 243 | 244 | variable "set_sensitive" { 245 | description = "Value block with custom sensitive values to be merged with the values yaml that won't be exposed in the plan's diff" 246 | type = any 247 | default = [] 248 | } 249 | 250 | variable "set_irsa_names" { 251 | description = "Value annotations name where IRSA role ARN created by module will be assigned to the `value`" 252 | type = list(string) 253 | default = [] 254 | } 255 | 256 | ################################################################################ 257 | # IAM Role for Service Account(s) (IRSA) 258 | ################################################################################ 259 | 260 | variable "role_path" { 261 | description = "Path of IAM role" 262 | type = string 263 | default = "/" 264 | } 265 | 266 | variable "role_permissions_boundary_arn" { 267 | description = "Permissions boundary ARN to use for IAM role" 268 | type = string 269 | default = null 270 | } 271 | 272 | variable "role_description" { 273 | description = "IAM Role description" 274 | type = string 275 | default = null 276 | } 277 | 278 | variable "role_policies" { 279 | description = "Policies to attach to the IAM role in `{'static_name' = 'policy_arn'}` format" 280 | type = map(string) 281 | default = {} 282 | } 283 | 284 | variable "oidc_providers" { 285 | description = "Map of OIDC providers where each provider map should contain the `provider_arn`, and `service_accounts`" 286 | type = any 287 | default = {} 288 | } 289 | 290 | variable "oidc_provider_arn" { 291 | description = "OIDC provider arn for mapping openobserve role with service account" 292 | type = string 293 | } 294 | 295 | variable "max_session_duration" { 296 | description = "Maximum CLI/API session duration in seconds between 3600 and 43200" 297 | type = number 298 | default = null 299 | } 300 | 301 | variable "assume_role_condition_test" { 302 | description = "Name of the [IAM condition operator](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html) to evaluate when assuming the role" 303 | type = string 304 | default = "StringEquals" 305 | } 306 | 307 | variable "allow_self_assume_role" { 308 | description = "Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/)" 309 | type = bool 310 | default = false 311 | } 312 | 313 | -------------------------------------------------------------------------------- /modules/opentelemetry-operator/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | # https://github.com/open-telemetry/opentelemetry-helm-charts/blob/main/charts/opentelemetry-operator/values.yaml 3 | values = [ 4 | <<-EOT 5 | manager: 6 | collectorImage: 7 | repository: "otel/opentelemetry-collector-k8s" 8 | admissionWebhooks: 9 | certManager: 10 | enabled: false 11 | EOT 12 | ] 13 | } 14 | 15 | module "opentelemetry_operator" { 16 | source = "aws-ia/eks-blueprints-addon/aws" 17 | version = "~> 1.1" 18 | 19 | values = concat( 20 | local.values, 21 | var.values 22 | ) 23 | 24 | set = var.set 25 | 26 | create = var.create 27 | tags = var.tags 28 | create_release = var.create_release 29 | name = var.name 30 | description = var.description 31 | namespace = var.namespace 32 | create_namespace = var.create_namespace 33 | chart = var.chart 34 | chart_version = var.chart_version 35 | repository = var.repository 36 | timeout = var.timeout 37 | repository_key_file = var.repository_key_file 38 | repository_cert_file = var.repository_cert_file 39 | repository_ca_file = var.repository_ca_file 40 | repository_username = var.repository_username 41 | repository_password = var.repository_password 42 | devel = var.devel 43 | verify = var.verify 44 | keyring = var.keyring 45 | disable_webhooks = var.disable_webhooks 46 | reuse_values = var.reuse_values 47 | reset_values = var.reset_values 48 | force_update = var.force_update 49 | recreate_pods = var.recreate_pods 50 | cleanup_on_fail = var.cleanup_on_fail 51 | max_history = var.max_history 52 | atomic = var.atomic 53 | skip_crds = var.skip_crds 54 | render_subchart_notes = var.render_subchart_notes 55 | disable_openapi_validation = var.disable_openapi_validation 56 | wait = var.wait 57 | wait_for_jobs = var.wait_for_jobs 58 | dependency_update = var.dependency_update 59 | replace = var.replace 60 | lint = var.lint 61 | postrender = var.postrender 62 | set_sensitive = var.set_sensitive 63 | set_irsa_names = var.set_irsa_names 64 | create_role = var.create_role 65 | role_name = var.role_name 66 | role_name_use_prefix = var.role_name_use_prefix 67 | role_path = var.role_path 68 | role_permissions_boundary_arn = var.role_permissions_boundary_arn 69 | role_description = var.role_description 70 | role_policies = var.role_policies 71 | oidc_providers = var.oidc_providers 72 | max_session_duration = var.max_session_duration 73 | assume_role_condition_test = var.assume_role_condition_test 74 | allow_self_assume_role = var.allow_self_assume_role 75 | create_policy = var.create_policy 76 | source_policy_documents = var.source_policy_documents 77 | override_policy_documents = var.override_policy_documents 78 | policy_statements = var.policy_statements 79 | policy_name = var.policy_name 80 | policy_name_use_prefix = var.policy_name_use_prefix 81 | policy_path = var.policy_path 82 | policy_description = var.policy_description 83 | } 84 | -------------------------------------------------------------------------------- /modules/opentelemetry-operator/outputs.tf: -------------------------------------------------------------------------------- 1 | output "chart" { 2 | description = "The name of the chart" 3 | value = try(module.opentelemetry_operator.chart, null) 4 | } 5 | 6 | output "name" { 7 | description = "Name is the name of the release" 8 | value = try(module.opentelemetry_operator.name, null) 9 | } 10 | 11 | output "namespace" { 12 | description = "Name of Kubernetes namespace" 13 | value = try(module.opentelemetry_operator.namespace, null) 14 | } 15 | 16 | output "revision" { 17 | description = "Version is an int32 which represents the version of the release" 18 | value = try(module.opentelemetry_operator.revision, null) 19 | } 20 | 21 | output "version" { 22 | description = "A SemVer 2 conformant version string of the chart" 23 | value = try(module.opentelemetry_operator.version, null) 24 | } 25 | 26 | output "app_version" { 27 | description = "The version number of the application being deployed" 28 | value = try(module.opentelemetry_operator.app_version, null) 29 | } 30 | -------------------------------------------------------------------------------- /modules/qryn/outputs.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Helm Release 3 | ################################################################################ 4 | 5 | output "chart" { 6 | description = "The name of the chart" 7 | value = { 8 | qryn = try(module.qryn.chart, null) 9 | clickhouse = try(module.clickhouse.chart, null) 10 | } 11 | } 12 | 13 | output "name" { 14 | description = "Name is the name of the release" 15 | value = { 16 | qryn = try(module.qryn.name, null) 17 | clickhouse = try(module.clickhouse.name, null) 18 | } 19 | } 20 | 21 | output "namespace" { 22 | description = "Name of Kubernetes namespace" 23 | value = { 24 | qryn = try(module.qryn.namespace, null) 25 | clickhouse = try(module.clickhouse.namespace, null) 26 | } 27 | } 28 | 29 | output "revision" { 30 | description = "Version is an int32 which represents the version of the release" 31 | value = { 32 | qryn = try(module.qryn.revision, null) 33 | clickhouse = try(module.clickhouse.revision, null) 34 | } 35 | } 36 | 37 | output "version" { 38 | description = "A SemVer 2 conformant version string of the chart" 39 | value = { 40 | qryn = try(module.qryn.version, null) 41 | clickhouse = try(module.clickhouse.version, null) 42 | } 43 | } 44 | 45 | output "app_version" { 46 | description = "The version number of the application being deployed" 47 | value = { 48 | qryn = try(module.qryn.app_version, null) 49 | clickhouse = try(module.clickhouse.app_version, null) 50 | } 51 | } 52 | 53 | # output "values" { 54 | # description = "The compounded values from `values` and `set*` attributes" 55 | # value = { 56 | # qryn = try(module.qryn.values, []) 57 | # clickhouse = try(module.clickhouse.values, []) 58 | # } 59 | # } 60 | 61 | ################################################################################ 62 | # IAM Role for Service Account(s) (IRSA) 63 | ################################################################################ 64 | 65 | output "iam_role_arn" { 66 | description = "ARN of IAM role" 67 | value = try(module.role.iam_role_arn, null) 68 | } 69 | 70 | output "iam_role_name" { 71 | description = "Name of IAM role" 72 | value = try(module.role.iam_role_name, null) 73 | } 74 | 75 | output "iam_role_path" { 76 | description = "Path of IAM role" 77 | value = try(module.role.iam_role_name, null) 78 | } 79 | 80 | output "iam_role_unique_id" { 81 | description = "Unique ID of IAM role" 82 | value = try(module.role.iam_role_unique_id, null) 83 | } 84 | 85 | ################################################################################ 86 | # IAM Policy 87 | ################################################################################ 88 | 89 | output "iam_policy_arn" { 90 | description = "The ARN assigned by AWS to this policy" 91 | value = try(module.role.iam_policy_arn, null) 92 | } 93 | 94 | output "iam_policy" { 95 | description = "The policy document" 96 | value = try(module.role.iam_policy, null) 97 | } 98 | 99 | ################################################################################ 100 | # Qryn 101 | ################################################################################ 102 | 103 | output "root_password" { 104 | description = "The qryn root password" 105 | value = local.root_password 106 | sensitive = true 107 | } 108 | 109 | output "clickhouse_password" { 110 | description = "The qryn clickhouse password" 111 | value = random_password.clickhouse_password.result 112 | sensitive = true 113 | } 114 | -------------------------------------------------------------------------------- /modules/uptrace/outputs.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Helm Release 3 | ################################################################################ 4 | 5 | output "chart" { 6 | description = "The name of the chart" 7 | value = { 8 | uptrace = try(module.uptrace.chart, null) 9 | clickhouse = try(module.clickhouse.chart, null) 10 | postgresql = try(module.postgresql.chart, null) 11 | } 12 | } 13 | 14 | output "name" { 15 | description = "Name is the name of the release" 16 | value = { 17 | uptrace = try(module.uptrace.name, null) 18 | clickhouse = try(module.clickhouse.name, null) 19 | postgresql = try(module.postgresql.name, null) 20 | } 21 | } 22 | 23 | output "namespace" { 24 | description = "Name of Kubernetes namespace" 25 | value = { 26 | uptrace = try(module.uptrace.namespace, null) 27 | clickhouse = try(module.clickhouse.namespace, null) 28 | postgresql = try(module.postgresql.namespace, null) 29 | } 30 | } 31 | 32 | output "revision" { 33 | description = "Version is an int32 which represents the version of the release" 34 | value = { 35 | uptrace = try(module.uptrace.revision, null) 36 | clickhouse = try(module.clickhouse.revision, null) 37 | } 38 | } 39 | 40 | output "version" { 41 | description = "A SemVer 2 conformant version string of the chart" 42 | value = { 43 | uptrace = try(module.uptrace.version, null) 44 | clickhouse = try(module.clickhouse.version, null) 45 | postgresql = try(module.postgresql.version, null) 46 | } 47 | } 48 | 49 | output "app_version" { 50 | description = "The version number of the application being deployed" 51 | value = { 52 | uptrace = try(module.uptrace.app_version, null) 53 | clickhouse = try(module.clickhouse.app_version, null) 54 | postgresql = try(module.postgresql.app_version, null) 55 | } 56 | } 57 | 58 | # output "values" { 59 | # description = "The compounded values from `values` and `set*` attributes" 60 | # value = { 61 | # uptrace = try(module.uptrace.values, []) 62 | # clickhouse = try(module.clickhouse.values, []) 63 | # postgresql = try(module.postgresql.values, []) 64 | # } 65 | # } 66 | 67 | ################################################################################ 68 | # IAM Role for Service Account(s) (IRSA) 69 | ################################################################################ 70 | 71 | output "iam_role_arn" { 72 | description = "ARN of IAM role" 73 | value = try(module.role.iam_role_arn, null) 74 | } 75 | 76 | output "iam_role_name" { 77 | description = "Name of IAM role" 78 | value = try(module.role.iam_role_name, null) 79 | } 80 | 81 | output "iam_role_path" { 82 | description = "Path of IAM role" 83 | value = try(module.role.iam_role_name, null) 84 | } 85 | 86 | output "iam_role_unique_id" { 87 | description = "Unique ID of IAM role" 88 | value = try(module.role.iam_role_unique_id, null) 89 | } 90 | 91 | ################################################################################ 92 | # IAM Policy 93 | ################################################################################ 94 | 95 | output "iam_policy_arn" { 96 | description = "The ARN assigned by AWS to this policy" 97 | value = try(module.role.iam_policy_arn, null) 98 | } 99 | 100 | output "iam_policy" { 101 | description = "The policy document" 102 | value = try(module.role.iam_policy, null) 103 | } 104 | 105 | ################################################################################ 106 | # Uptrace 107 | ################################################################################ 108 | 109 | output "root_password" { 110 | description = "The uptrace root password" 111 | value = local.root_password 112 | sensitive = true 113 | } 114 | 115 | output "project_tokens" { 116 | description = "The uptrace project tokens" 117 | value = random_password.uptrace_project_tokens[*].result 118 | sensitive = true 119 | } 120 | 121 | output "clickhouse_password" { 122 | description = "The uptrace clickhouse password" 123 | value = random_password.clickhouse_password.result 124 | sensitive = true 125 | } 126 | 127 | output "postgresql_password" { 128 | description = "The uptrace postgresql password" 129 | value = random_password.postgresql_password.result 130 | sensitive = true 131 | } 132 | -------------------------------------------------------------------------------- /modules/vector/main.tf: -------------------------------------------------------------------------------- 1 | # locals { 2 | # persistence = var.vector_role == "Aggregator"? true : false 3 | # 4 | # # https://github.com/vectordotdev/helm-charts/blob/develop/charts/vector/values.yaml 5 | # values = [ 6 | # <<-EOT 7 | # role: "${var.vector_role}" 8 | # 9 | # # customConfig -- Override Vector's default configs, if used **all** options need to be specified. This section supports 10 | # # using helm templates to populate dynamic values. See Vector's [configuration documentation](https://vector.dev/docs/reference/configuration/) 11 | # # for all options. 12 | # customConfig: 13 | # data_dir: /vector-data-dir 14 | # api: 15 | # enabled: true 16 | # address: 127.0.0.1:8686 17 | # playground: false 18 | # 19 | # # https://vector.dev/docs/reference/configuration/sources/ 20 | # %{ if var.vector_sources } 21 | # ${indent(6, var.vector_sources)} 22 | # %{ else } 23 | # %{ if var.vector_role == "Agent" } 24 | # sources: 25 | # kubernetes_logs: 26 | # type: kubernetes_logs 27 | # host_metrics: 28 | # filesystem: 29 | # devices: 30 | # excludes: [binfmt_misc] 31 | # filesystems: 32 | # excludes: [binfmt_misc] 33 | # mountpoints: 34 | # excludes: ["*/proc/sys/fs/binfmt_misc"] 35 | # type: host_metrics 36 | # internal_metrics: 37 | # type: internal_metrics 38 | # %{ else } 39 | # sources: 40 | # datadog_agent: 41 | # address: 0.0.0.0:8282 42 | # type: datadog_agent 43 | # fluent: 44 | # address: 0.0.0.0:24224 45 | # type: fluent 46 | # internal_metrics: 47 | # type: internal_metrics 48 | # logstash: 49 | # address: 0.0.0.0:5044 50 | # type: logstash 51 | # splunk_hec: 52 | # address: 0.0.0.0:8080 53 | # type: splunk_hec 54 | # statsd: 55 | # address: 0.0.0.0:8125 56 | # mode: tcp 57 | # type: statsd 58 | # syslog: 59 | # address: 0.0.0.0:9000 60 | # mode: tcp 61 | # type: syslog 62 | # vector: 63 | # address: 0.0.0.0:6000 64 | # type: vector 65 | # version: "2" 66 | # %{ endif } 67 | # %{ endif } 68 | # 69 | # # https://vector.dev/docs/reference/configuration/transforms/ 70 | # %{ if var.vector_transforms } 71 | # ${indent(6, var.vector_transforms)} 72 | # %{ else } 73 | # %{ if var.vector_role == "Agent" } 74 | # transforms: {} 75 | # %{ else } 76 | # transforms: {} 77 | # %{ endif } 78 | # %{ endif } 79 | # 80 | # # https://vector.dev/docs/reference/configuration/sinks/ 81 | # %{ if var.vector_sinks } 82 | # ${indent(6, var.vector_sinks)} 83 | # %{ else } 84 | # %{ if var.vector_role == "Agent" } 85 | # sinks: 86 | # prom_exporter: 87 | # type: prometheus_exporter 88 | # inputs: [host_metrics, internal_metrics] 89 | # address: 0.0.0.0:9090 90 | # stdout: 91 | # type: console 92 | # inputs: [kubernetes_logs] 93 | # encoding: 94 | # codec: json 95 | # %{ else } 96 | # sinks: 97 | # prom_exporter: 98 | # type: prometheus_exporter 99 | # inputs: [internal_metrics] 100 | # address: 0.0.0.0:9090 101 | # stdout: 102 | # type: console 103 | # inputs: [datadog_agent, fluent, logstash, splunk_hec, statsd, syslog, vector] 104 | # encoding: 105 | # codec: json 106 | # %{ endif } 107 | # %{ endif } 108 | # 109 | # # Configuration for Vector's data persistence. 110 | # persistence: 111 | # enabled: "${local.persistence}" 112 | # EOT 113 | # ] 114 | # 115 | # } 116 | 117 | module "vector" { 118 | source = "aws-ia/eks-blueprints-addon/aws" 119 | version = "~> 1.1" 120 | 121 | set =var.set 122 | values = var.values 123 | 124 | # values = concat( 125 | # local.values, 126 | # var.values 127 | # ) 128 | 129 | create = var.create 130 | tags = var.tags 131 | create_release = var.create_release 132 | name = var.name 133 | description = var.description 134 | namespace = var.namespace 135 | create_namespace = var.create_namespace 136 | chart = var.chart 137 | chart_version = var.chart_version 138 | repository = var.repository 139 | timeout = var.timeout 140 | repository_key_file = var.repository_key_file 141 | repository_cert_file = var.repository_cert_file 142 | repository_ca_file = var.repository_ca_file 143 | repository_username = var.repository_username 144 | repository_password = var.repository_password 145 | devel = var.devel 146 | verify = var.verify 147 | keyring = var.keyring 148 | disable_webhooks = var.disable_webhooks 149 | reuse_values = var.reuse_values 150 | reset_values = var.reset_values 151 | force_update = var.force_update 152 | recreate_pods = var.recreate_pods 153 | cleanup_on_fail = var.cleanup_on_fail 154 | max_history = var.max_history 155 | atomic = var.atomic 156 | skip_crds = var.skip_crds 157 | render_subchart_notes = var.render_subchart_notes 158 | disable_openapi_validation = var.disable_openapi_validation 159 | wait = var.wait 160 | wait_for_jobs = var.wait_for_jobs 161 | dependency_update = var.dependency_update 162 | replace = var.replace 163 | lint = var.lint 164 | postrender = var.postrender 165 | set_sensitive = var.set_sensitive 166 | set_irsa_names = var.set_irsa_names 167 | create_role = var.create_role 168 | role_name = var.role_name 169 | role_name_use_prefix = var.role_name_use_prefix 170 | role_path = var.role_path 171 | role_permissions_boundary_arn = var.role_permissions_boundary_arn 172 | role_description = var.role_description 173 | role_policies = var.role_policies 174 | oidc_providers = var.oidc_providers 175 | max_session_duration = var.max_session_duration 176 | assume_role_condition_test = var.assume_role_condition_test 177 | allow_self_assume_role = var.allow_self_assume_role 178 | create_policy = var.create_policy 179 | source_policy_documents = var.source_policy_documents 180 | override_policy_documents = var.override_policy_documents 181 | policy_statements = var.policy_statements 182 | policy_name = var.policy_name 183 | policy_name_use_prefix = var.policy_name_use_prefix 184 | policy_path = var.policy_path 185 | policy_description = var.policy_description 186 | } 187 | -------------------------------------------------------------------------------- /modules/vector/outputs.tf: -------------------------------------------------------------------------------- 1 | output "chart" { 2 | description = "The name of the chart" 3 | value = try(module.vector.chart, null) 4 | } 5 | 6 | output "name" { 7 | description = "Name is the name of the release" 8 | value = try(module.vector.name, null) 9 | } 10 | 11 | output "namespace" { 12 | description = "Name of Kubernetes namespace" 13 | value = try(module.vector.namespace, null) 14 | } 15 | 16 | output "revision" { 17 | description = "Version is an int32 which represents the version of the release" 18 | value = try(module.vector.revision, null) 19 | } 20 | 21 | output "version" { 22 | description = "A SemVer 2 conformant version string of the chart" 23 | value = try(module.vector.version, null) 24 | } 25 | 26 | output "app_version" { 27 | description = "The version number of the application being deployed" 28 | value = try(module.vector.app_version, null) 29 | } 30 | -------------------------------------------------------------------------------- /modules/victoriametrics-operator/main.tf: -------------------------------------------------------------------------------- 1 | data "aws_region" "current" {} 2 | 3 | locals { 4 | 5 | # https://github.com/VictoriaMetrics/helm-charts/blob/master/charts/victoria-metrics-operator/values.yaml 6 | values = [ 7 | <<-EOT 8 | operator: 9 | # -- By default, operator converts prometheus-operator objects. 10 | disable_prometheus_converter: false 11 | # -- Compare-options and sync-options for prometheus objects converted by operator for properly use with ArgoCD 12 | prometheus_converter_add_argocd_ignore_annotations: true 13 | # -- By default, operator doesn't create psp for its objects. 14 | psp_auto_creation_enabled: false 15 | # -- Enables ownership reference for converted prometheus-operator objects, 16 | # it will remove corresponding victoria-metrics objects in case of deletion prometheus one. 17 | enable_converter_ownership: true 18 | # -- Enables custom config-reloader, bundled with operator. 19 | # It should reduce vmagent and vmauth config sync-time and make it predictable. 20 | useCustomConfigReloader: true 21 | serviceMonitor: 22 | enabled: false 23 | EOT 24 | ] 25 | set = [] 26 | 27 | } 28 | 29 | module "victoriametrics" { 30 | source = "aws-ia/eks-blueprints-addon/aws" 31 | version = "~> 1.1" 32 | 33 | set = var.set 34 | 35 | values = concat( 36 | local.values, 37 | var.values 38 | ) 39 | 40 | create = var.create 41 | tags = var.tags 42 | create_release = var.create_release 43 | name = var.name 44 | description = var.description 45 | namespace = var.namespace 46 | create_namespace = var.create_namespace 47 | chart = var.chart 48 | chart_version = var.chart_version 49 | repository = var.repository 50 | timeout = var.timeout 51 | repository_key_file = var.repository_key_file 52 | repository_cert_file = var.repository_cert_file 53 | repository_ca_file = var.repository_ca_file 54 | repository_username = var.repository_username 55 | repository_password = var.repository_password 56 | devel = var.devel 57 | verify = var.verify 58 | keyring = var.keyring 59 | disable_webhooks = var.disable_webhooks 60 | reuse_values = var.reuse_values 61 | reset_values = var.reset_values 62 | force_update = var.force_update 63 | recreate_pods = var.recreate_pods 64 | cleanup_on_fail = var.cleanup_on_fail 65 | max_history = var.max_history 66 | atomic = var.atomic 67 | skip_crds = var.skip_crds 68 | render_subchart_notes = var.render_subchart_notes 69 | disable_openapi_validation = var.disable_openapi_validation 70 | wait = var.wait 71 | wait_for_jobs = var.wait_for_jobs 72 | dependency_update = var.dependency_update 73 | replace = var.replace 74 | lint = var.lint 75 | postrender = var.postrender 76 | set_sensitive = var.set_sensitive 77 | set_irsa_names = var.set_irsa_names 78 | create_role = var.create_role 79 | role_name = var.role_name 80 | role_name_use_prefix = var.role_name_use_prefix 81 | role_path = var.role_path 82 | role_permissions_boundary_arn = var.role_permissions_boundary_arn 83 | role_description = var.role_description 84 | role_policies = var.role_policies 85 | oidc_providers = var.oidc_providers 86 | max_session_duration = var.max_session_duration 87 | assume_role_condition_test = var.assume_role_condition_test 88 | allow_self_assume_role = var.allow_self_assume_role 89 | create_policy = var.create_policy 90 | source_policy_documents = var.source_policy_documents 91 | override_policy_documents = var.override_policy_documents 92 | policy_statements = var.policy_statements 93 | policy_name = var.policy_name 94 | policy_name_use_prefix = var.policy_name_use_prefix 95 | policy_path = var.policy_path 96 | policy_description = var.policy_description 97 | } 98 | 99 | module "prometheus_operator_crds" { 100 | source = "aws-ia/eks-blueprints-addon/aws" 101 | version = "~> 1.1" 102 | 103 | set = var.prometheus_operator_crds_set 104 | values = var.prometheus_operator_crds_values 105 | 106 | create = var.create 107 | tags = var.tags 108 | create_release = var.prometheus_operator_crds_create_release 109 | name = var.prometheus_operator_crds_name 110 | description = var.prometheus_operator_crds_description 111 | namespace = var.namespace 112 | create_namespace = var.prometheus_operator_crds_create_namespace 113 | chart = var.prometheus_operator_crds_chart 114 | chart_version = var.prometheus_operator_crds_chart_version 115 | repository = var.prometheus_operator_crds_repository 116 | timeout = var.prometheus_operator_crds_timeout 117 | repository_key_file = var.prometheus_operator_crds_repository_key_file 118 | repository_cert_file = var.prometheus_operator_crds_repository_cert_file 119 | repository_ca_file = var.prometheus_operator_crds_repository_ca_file 120 | repository_username = var.prometheus_operator_crds_repository_username 121 | repository_password = var.prometheus_operator_crds_repository_password 122 | devel = var.prometheus_operator_crds_devel 123 | verify = var.prometheus_operator_crds_verify 124 | keyring = var.prometheus_operator_crds_keyring 125 | disable_webhooks = var.prometheus_operator_crds_disable_webhooks 126 | reuse_values = var.prometheus_operator_crds_reuse_values 127 | reset_values = var.prometheus_operator_crds_reset_values 128 | force_update = var.prometheus_operator_crds_force_update 129 | recreate_pods = var.prometheus_operator_crds_recreate_pods 130 | cleanup_on_fail = var.prometheus_operator_crds_cleanup_on_fail 131 | max_history = var.prometheus_operator_crds_max_history 132 | atomic = var.prometheus_operator_crds_atomic 133 | skip_crds = var.prometheus_operator_crds_skip_crds 134 | render_subchart_notes = var.prometheus_operator_crds_render_subchart_notes 135 | disable_openapi_validation = var.prometheus_operator_crds_disable_openapi_validation 136 | wait = var.prometheus_operator_crds_wait 137 | wait_for_jobs = var.prometheus_operator_crds_wait_for_jobs 138 | dependency_update = var.prometheus_operator_crds_dependency_update 139 | replace = var.prometheus_operator_crds_replace 140 | lint = var.prometheus_operator_crds_lint 141 | postrender = var.prometheus_operator_crds_postrender 142 | set_sensitive = var.prometheus_operator_crds_set_sensitive 143 | set_irsa_names = var.prometheus_operator_crds_set_irsa_names 144 | } 145 | -------------------------------------------------------------------------------- /modules/victoriametrics-operator/outputs.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Helm Release 3 | ################################################################################ 4 | 5 | output "chart" { 6 | description = "The name of the chart" 7 | value = { 8 | victoriametrics = try(module.victoriametrics.chart, null) 9 | prometheus_operator_crds = try(module.prometheus_operator_crds.chart, null) 10 | } 11 | } 12 | 13 | output "name" { 14 | description = "Name is the name of the release" 15 | value = { 16 | victoriametrics = try(module.victoriametrics.name, null) 17 | prometheus_operator_crds = try(module.prometheus_operator_crds.name, null) 18 | } 19 | } 20 | 21 | output "namespace" { 22 | description = "Name of Kubernetes namespace" 23 | value = { 24 | victoriametrics = try(module.victoriametrics.namespace, null) 25 | prometheus_operator_crds = try(module.prometheus_operator_crds.namespace, null) 26 | } 27 | } 28 | 29 | output "revision" { 30 | description = "Version is an int32 which represents the version of the release" 31 | value = { 32 | victoriametrics = try(module.victoriametrics.revision, null) 33 | prometheus_operator_crds = try(module.prometheus_operator_crds.revision, null) 34 | } 35 | } 36 | 37 | output "version" { 38 | description = "A SemVer 2 conformant version string of the chart" 39 | value = { 40 | victoriametrics = try(module.victoriametrics.version, null) 41 | prometheus_operator_crds = try(module.prometheus_operator_crds.version, null) 42 | } 43 | } 44 | 45 | output "app_version" { 46 | description = "The version number of the application being deployed" 47 | value = { 48 | victoriametrics = try(module.victoriametrics.app_version, null) 49 | prometheus_operator_crds = try(module.prometheus_operator_crds.app_version, null) 50 | } 51 | } 52 | 53 | # output "values" { 54 | # description = "The compounded values from `values` and `set*` attributes" 55 | # value = { 56 | # victoriametrics = try(module.victoriametrics.values, []) 57 | # prometheus_operator_crds = try(module.prometheus_operator_crds.values, []) 58 | # } 59 | # } 60 | -------------------------------------------------------------------------------- /modules/victoriametrics/main.tf: -------------------------------------------------------------------------------- 1 | data "aws_region" "current" {} 2 | 3 | locals { 4 | grafana_admin_password = coalesce(var.grafana_admin_password, random_password.grafana_admin_password.result) 5 | auth_vmagent_rw_password = coalesce(var.auth_vmagent_rw_password, random_password.auth_vmagent_rw_password.result) 6 | auth_vmagent_rw_user = "agent" 7 | 8 | auth_vmsingle_password = coalesce(var.auth_victoriametrics_password, random_password.auth_victoriametrics_password.result) 9 | auth_vmsingle_user = "vmsingle" 10 | 11 | auth_vmselect_password = coalesce(var.auth_victoriametrics_password, random_password.auth_victoriametrics_password.result) 12 | auth_vmselect_user = "vmselect" 13 | 14 | auth_alertmanager_password = coalesce(var.auth_alertmanager_password, random_password.auth_alertmanager_password.result) 15 | auth_alertmanager_user = "alertmanager" 16 | 17 | auth_vmalert_password = coalesce(var.auth_vmalert_password, random_password.auth_vmalert_password.result) 18 | auth_vmalert_user = "vmalert" 19 | 20 | # https://github.com/VictoriaMetrics/helm-charts/blob/72ae97b4cfb27797928952d2bb0a3f3ecc146cee/charts/victoria-metrics-k8s-stack/values.yaml 21 | values = [ 22 | <<-EOT 23 | vmsingle: 24 | enabled: true 25 | # spec for VMSingle crd 26 | # https://docs.victoriametrics.com/operator/api.html#vmsinglespec 27 | spec: 28 | retentionPeriod: "14" 29 | replicaCount: 1 30 | extraArgs: {} 31 | storage: 32 | accessModes: 33 | - ReadWriteOnce 34 | resources: 35 | requests: 36 | storage: 10Gi 37 | vmcluster: 38 | enabled: false 39 | # spec for VMCluster crd 40 | # https://docs.victoriametrics.com/operator/api.html#vmclusterspec 41 | spec: 42 | retentionPeriod: "14" 43 | replicationFactor: 2 44 | vmstorage: 45 | replicaCount: 2 46 | storageDataPath: "/vm-data" 47 | storage: 48 | volumeClaimTemplate: 49 | spec: 50 | resources: 51 | requests: 52 | storage: 10Gi 53 | grafana: 54 | persistence: 55 | enabled: true 56 | size: 1Gi 57 | admin: 58 | existingSecret: "victoriametrics-grafana-admin-credentials" 59 | userKey: username 60 | passwordKey: password 61 | EOT 62 | ] 63 | set = [] 64 | 65 | # https://github.com/VictoriaMetrics/helm-charts/blob/1e41a73904dbaed41748ddb724674c94cbfa2fd6/charts/victoria-metrics-auth/values.yaml 66 | # https://docs.victoriametrics.com/vmauth/ 67 | auth_values = [ 68 | <<-EOT 69 | serviceMonitor: 70 | enabled: true 71 | secretName: "victoriametrics-auth-config" 72 | EOT 73 | ] 74 | auth_set = [] 75 | 76 | } 77 | 78 | resource "random_password" "grafana_admin_password" { 79 | length = 32 80 | special = false 81 | } 82 | 83 | resource "random_password" "auth_vmagent_rw_password" { 84 | length = 32 85 | special = false 86 | } 87 | 88 | resource "random_password" "auth_victoriametrics_password" { 89 | length = 32 90 | special = false 91 | } 92 | 93 | resource "random_password" "auth_alertmanager_password" { 94 | length = 32 95 | special = false 96 | } 97 | 98 | resource "random_password" "auth_vmalert_password" { 99 | length = 32 100 | special = false 101 | } 102 | 103 | module "kubernetes_manifests" { 104 | source = "../kubernetes-manifests" 105 | 106 | create = var.create 107 | name = "victoriametrics-${var.namespace}-manifests" 108 | namespace = var.namespace 109 | tags = var.tags 110 | 111 | values = [ 112 | <<-EOT 113 | resources: 114 | - kind: Secret 115 | apiVersion: v1 116 | metadata: 117 | name: "victoriametrics-grafana-admin-credentials" 118 | namespace: "${var.namespace}" 119 | stringData: 120 | username: "${var.grafana_admin_user}" 121 | password: "${local.grafana_admin_password}" 122 | type: Opaque 123 | - kind: Secret 124 | apiVersion: v1 125 | metadata: 126 | name: "victoriametrics-auth-config" 127 | namespace: "${var.namespace}" 128 | stringData: 129 | # https://docs.victoriametrics.com/vmauth/ 130 | "auth.yml": | 131 | users: 132 | - username: "${local.auth_vmagent_rw_user}" 133 | password: "${local.auth_vmagent_rw_password}" 134 | url_prefix: "http://vmagent-${module.victoriametrics.chart}:8429/" 135 | - username: "${local.auth_vmsingle_user}" 136 | password: "${local.auth_vmsingle_password}" 137 | url_prefix: "http://vmsingle-${module.victoriametrics.chart}:8429/" 138 | - username: "${local.auth_vmselect_user}" 139 | password: "${local.auth_vmselect_password}" 140 | url_prefix: "http://vmselect-${module.victoriametrics.chart}:8481/" 141 | - username: "${local.auth_alertmanager_user}" 142 | password: "${local.auth_alertmanager_password}" 143 | url_prefix: "http://vmalertmanager-${module.victoriametrics.chart}:9093/" 144 | - username: "${local.auth_vmalert_user}" 145 | password: "${local.auth_vmalert_password}" 146 | url_prefix: "http://vmalert-${module.victoriametrics.chart}:8080/" 147 | type: Opaque 148 | EOT 149 | ] 150 | } 151 | 152 | module "victoriametrics" { 153 | source = "aws-ia/eks-blueprints-addon/aws" 154 | version = "~> 1.1" 155 | 156 | depends_on = [ 157 | #module.kubernetes_manifests 158 | ] 159 | 160 | set = var.set 161 | 162 | values = concat( 163 | local.values, 164 | var.values 165 | ) 166 | 167 | create = var.create 168 | tags = var.tags 169 | create_release = var.create_release 170 | name = var.name 171 | description = var.description 172 | namespace = var.namespace 173 | create_namespace = var.create_namespace 174 | chart = var.chart 175 | chart_version = var.chart_version 176 | repository = var.repository 177 | timeout = var.timeout 178 | repository_key_file = var.repository_key_file 179 | repository_cert_file = var.repository_cert_file 180 | repository_ca_file = var.repository_ca_file 181 | repository_username = var.repository_username 182 | repository_password = var.repository_password 183 | devel = var.devel 184 | verify = var.verify 185 | keyring = var.keyring 186 | disable_webhooks = var.disable_webhooks 187 | reuse_values = var.reuse_values 188 | reset_values = var.reset_values 189 | force_update = var.force_update 190 | recreate_pods = var.recreate_pods 191 | cleanup_on_fail = var.cleanup_on_fail 192 | max_history = var.max_history 193 | atomic = var.atomic 194 | skip_crds = var.skip_crds 195 | render_subchart_notes = var.render_subchart_notes 196 | disable_openapi_validation = var.disable_openapi_validation 197 | wait = var.wait 198 | wait_for_jobs = var.wait_for_jobs 199 | dependency_update = var.dependency_update 200 | replace = var.replace 201 | lint = var.lint 202 | postrender = var.postrender 203 | set_sensitive = var.set_sensitive 204 | set_irsa_names = var.set_irsa_names 205 | create_role = var.create_role 206 | role_name = var.role_name 207 | role_name_use_prefix = var.role_name_use_prefix 208 | role_path = var.role_path 209 | role_permissions_boundary_arn = var.role_permissions_boundary_arn 210 | role_description = var.role_description 211 | role_policies = var.role_policies 212 | oidc_providers = var.oidc_providers 213 | max_session_duration = var.max_session_duration 214 | assume_role_condition_test = var.assume_role_condition_test 215 | allow_self_assume_role = var.allow_self_assume_role 216 | create_policy = var.create_policy 217 | source_policy_documents = var.source_policy_documents 218 | override_policy_documents = var.override_policy_documents 219 | policy_statements = var.policy_statements 220 | policy_name = var.policy_name 221 | policy_name_use_prefix = var.policy_name_use_prefix 222 | policy_path = var.policy_path 223 | policy_description = var.policy_description 224 | } 225 | 226 | module "auth" { 227 | source = "aws-ia/eks-blueprints-addon/aws" 228 | version = "~> 1.1" 229 | 230 | depends_on = [ 231 | module.victoriametrics, 232 | #module.kubernetes_manifests 233 | ] 234 | 235 | set = var.auth_set 236 | 237 | values = concat( 238 | local.auth_values, 239 | var.auth_values 240 | ) 241 | 242 | create = var.create 243 | tags = var.tags 244 | create_release = var.auth_create_release 245 | name = var.auth_name 246 | description = var.auth_description 247 | namespace = var.namespace 248 | create_namespace = var.create_namespace 249 | chart = var.auth_chart 250 | chart_version = var.auth_chart_version 251 | repository = var.auth_repository 252 | timeout = var.auth_timeout 253 | repository_key_file = var.auth_repository_key_file 254 | repository_cert_file = var.auth_repository_cert_file 255 | repository_ca_file = var.auth_repository_ca_file 256 | repository_username = var.auth_repository_username 257 | repository_password = var.auth_repository_password 258 | devel = var.auth_devel 259 | verify = var.auth_verify 260 | keyring = var.auth_keyring 261 | disable_webhooks = var.auth_disable_webhooks 262 | reuse_values = var.auth_reuse_values 263 | reset_values = var.auth_reset_values 264 | force_update = var.auth_force_update 265 | recreate_pods = var.auth_recreate_pods 266 | cleanup_on_fail = var.auth_cleanup_on_fail 267 | max_history = var.auth_max_history 268 | atomic = var.auth_atomic 269 | skip_crds = var.auth_skip_crds 270 | render_subchart_notes = var.auth_render_subchart_notes 271 | disable_openapi_validation = var.auth_disable_openapi_validation 272 | wait = var.auth_wait 273 | wait_for_jobs = var.auth_wait_for_jobs 274 | dependency_update = var.auth_dependency_update 275 | replace = var.auth_replace 276 | lint = var.auth_lint 277 | postrender = var.auth_postrender 278 | set_sensitive = var.auth_set_sensitive 279 | set_irsa_names = var.auth_set_irsa_names 280 | } 281 | 282 | # https://grafana.github.io/grafana-operator/docs/datasources/ 283 | module "grafana_operator_datasource" { 284 | source = "../kubernetes-manifests" 285 | count = var.grafana_operator_integration == true ? 1 : 0 286 | 287 | name = "victoriametrics-${var.namespace}-datasource" 288 | namespace = var.grafana_operator_namespace 289 | tags = var.tags 290 | 291 | values = [ 292 | <<-EOT 293 | resources: 294 | - apiVersion: grafana.integreatly.org/v1beta1 295 | kind: GrafanaDatasource 296 | metadata: 297 | name: "victoriametrics-single-${var.namespace}-datasource" 298 | spec: 299 | instanceSelector: 300 | matchLabels: 301 | dashboards: "grafana" 302 | datasource: 303 | name: "VictoriaMetrics-Single-${var.namespace}" 304 | type: prometheus 305 | access: proxy 306 | basicAuth: false 307 | url: "http://vmsingle-${module.victoriametrics.chart}.${module.victoriametrics.namespace}.svc:8429/" 308 | isDefault: false 309 | jsonData: 310 | "tlsSkipVerify": true 311 | "timeInterval": "5s" 312 | editable: true 313 | - apiVersion: grafana.integreatly.org/v1beta1 314 | kind: GrafanaDatasource 315 | metadata: 316 | name: "victoriametrics-cluster-${var.namespace}-datasource" 317 | spec: 318 | instanceSelector: 319 | matchLabels: 320 | dashboards: "grafana" 321 | datasource: 322 | name: "VictoriaMetrics-Cluster-${var.namespace}" 323 | type: prometheus 324 | access: proxy 325 | basicAuth: false 326 | url: "http://vmselect-${module.victoriametrics.chart}.${module.victoriametrics.namespace}.svc:8481" 327 | isDefault: false 328 | jsonData: 329 | "tlsSkipVerify": true 330 | "timeInterval": "5s" 331 | editable: true 332 | EOT 333 | ] 334 | } 335 | -------------------------------------------------------------------------------- /modules/victoriametrics/outputs.tf: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Helm Release 3 | ################################################################################ 4 | 5 | output "chart" { 6 | description = "The name of the chart" 7 | value = { 8 | stack = try(module.victoriametrics.chart, null) 9 | auth = try(module.auth.chart, null) 10 | } 11 | } 12 | 13 | output "name" { 14 | description = "Name is the name of the release" 15 | value = { 16 | stack = try(module.victoriametrics.name, null) 17 | auth = try(module.auth.name, null) 18 | } 19 | } 20 | 21 | output "namespace" { 22 | description = "Name of Kubernetes namespace" 23 | value = { 24 | stack = try(module.victoriametrics.namespace, null) 25 | auth = try(module.auth.namespace, null) 26 | } 27 | } 28 | 29 | output "revision" { 30 | description = "Version is an int32 which represents the version of the release" 31 | value = { 32 | stack = try(module.victoriametrics.revision, null) 33 | auth = try(module.auth.revision, null) 34 | } 35 | } 36 | 37 | output "version" { 38 | description = "A SemVer 2 conformant version string of the chart" 39 | value = { 40 | stack = try(module.victoriametrics.version, null) 41 | auth = try(module.auth.version, null) 42 | } 43 | } 44 | 45 | output "app_version" { 46 | description = "The version number of the application being deployed" 47 | value = { 48 | stack = try(module.victoriametrics.app_version, null) 49 | auth = try(module.auth.app_version, null) 50 | } 51 | } 52 | 53 | # output "values" { 54 | # description = "The compounded values from `values` and `set*` attributes" 55 | # value = { 56 | # stack = try(module.victoriametrics.values, []) 57 | # auth = try(module.auth.values, null) 58 | # } 59 | # } 60 | 61 | ################################################################################ 62 | # Grafana 63 | ################################################################################ 64 | 65 | output "grafana_admin_password" { 66 | description = "Grafana admin password" 67 | value = local.grafana_admin_password 68 | sensitive = true 69 | } 70 | 71 | output "grafana_admin_user" { 72 | description = "Grafana admin user" 73 | value = var.grafana_admin_user 74 | } 75 | 76 | ################################################################################ 77 | # VM Auth 78 | ################################################################################ 79 | 80 | output "auth_vmagent_rw_user" { 81 | description = "VM Agent read write user" 82 | value = local.auth_vmagent_rw_user 83 | } 84 | 85 | output "auth_vmagent_rw_password" { 86 | description = "VM Agent read write password" 87 | value = local.auth_vmagent_rw_password 88 | sensitive = true 89 | } 90 | 91 | output "auth_vmsingle_user" { 92 | description = "VM Single user" 93 | value = local.auth_vmsingle_user 94 | } 95 | 96 | output "auth_vmsingle_password" { 97 | description = "VM Single password" 98 | value = local.auth_vmsingle_password 99 | sensitive = true 100 | } 101 | 102 | output "auth_vmselect_user" { 103 | description = "VM Select user" 104 | value = local.auth_vmselect_user 105 | } 106 | 107 | output "auth_vmselect_password" { 108 | description = "VM Select password" 109 | value = local.auth_vmselect_password 110 | sensitive = true 111 | } 112 | 113 | output "auth_alertmanager_user" { 114 | description = "VM Alertmanager user" 115 | value = local.auth_alertmanager_user 116 | } 117 | 118 | output "auth_alertmanager_password" { 119 | description = "VM Alertmanager password" 120 | value = local.auth_alertmanager_password 121 | sensitive = true 122 | } 123 | 124 | output "auth_vmalert_user" { 125 | description = "VM Alert user" 126 | value = local.auth_vmalert_user 127 | } 128 | 129 | output "auth_vmalert_password" { 130 | description = "VM Alert password" 131 | value = local.auth_vmalert_password 132 | sensitive = true 133 | } 134 | -------------------------------------------------------------------------------- /outputs.tf: -------------------------------------------------------------------------------- 1 | output "eks" { 2 | value = module.eks 3 | } 4 | 5 | output "aws_efs_csi_driver" { 6 | value = module.addons.aws_efs_csi_driver 7 | } 8 | 9 | output "aws_node_termination_handler" { 10 | value = module.addons.aws_node_termination_handler 11 | } 12 | 13 | output "cert_manager" { 14 | value = module.addons.cert_manager 15 | } 16 | 17 | output "cluster_autoscaler" { 18 | value = module.addons.cluster_autoscaler 19 | } 20 | 21 | output "eks_addons" { 22 | value = module.addons.eks_addons 23 | } 24 | 25 | output "metrics_server" { 26 | value = module.addons.metrics_server 27 | } 28 | 29 | output "vpa" { 30 | value = module.addons.vpa 31 | } 32 | 33 | output "apisix" { 34 | value = try(module.ingress_apisix, null) 35 | } 36 | 37 | output "nginx" { 38 | value = try(module.ingress_nginx, null) 39 | } 40 | 41 | output "victoriametrics_operator" { 42 | value = try(module.victoriametrics_operator, null) 43 | } 44 | 45 | output "opentelemetry_operator" { 46 | value = try(module.opentelemetry_operator, null) 47 | } 48 | 49 | output "clickhouse_operator" { 50 | value = try(module.clickhouse_operator, null) 51 | } 52 | 53 | output "grafana_operator" { 54 | value = try(module.grafana_operator, null) 55 | } 56 | 57 | output "victoriametrics" { 58 | value = try(module.victoriametrics, null) 59 | } 60 | 61 | output "grafana" { 62 | value = try(module.grafana, null) 63 | } 64 | 65 | output "uptrace" { 66 | value = try(module.uptrace, null) 67 | } 68 | 69 | output "qryn" { 70 | value = try(module.qryn, null) 71 | } 72 | 73 | output "openobserve" { 74 | value = try(module.openobserve, null) 75 | } 76 | 77 | output "openobserve_collector" { 78 | value = try(module.openobserve_collector, null) 79 | } 80 | 81 | output "vector_agent" { 82 | value = try(module.vector_agent, null) 83 | } 84 | 85 | output "kubernetes_dashboard" { 86 | value = try(module.kubernetes_dashboard, null) 87 | } 88 | -------------------------------------------------------------------------------- /promlems.md: -------------------------------------------------------------------------------- 1 | ## Problems with taints and tolerations 2 | 3 | This doesn't work 4 | cert-manager-85b8554b54-k6cfx 5 | ebs-csi-controller-777d6956f7-9x4nk 6 | grafana-operator-5cf9bcfd76-v8jn9 7 | metrics-server-7b674c55cd-ts64v 8 | postgresql-0 9 | snapshot-controller-786bf8b4fc-l6mq 10 | victoria-metrics-k8s-stack-kube-state-metrics-889cfcf97-gp96p 11 | vmagent-victoria-metrics-k8s-stack-7c84947b56-n9j4w 12 | vmalert-victoria-metrics-k8s-stack-6b9496f4f-t8p6w 13 | vmalertmanager-victoria-metrics-k8s-stack-0 14 | vmsingle-victoria-metrics-k8s-stack-59d857bcd4-2kzbz 15 | vpa-certgen-46hz6 16 | 17 | ## qryn failing under load and return 401 18 | 19 | ## vector can't validate loki qryn config because of missing `encoding` and `labels` xD 20 | 21 | ## openobserve looking for nginx hook and custom ingress doesn't work after latest update 22 | 23 | ## Problem with fargate 24 | 25 | efs-csi-controller-56f9b4cb75-6nt6l Pod not supported on Fargate: fields not supported: HostNetwork, port contains HostIP or HostPort 26 | efs-csi-controller-56f9b4cb75-5hqmk 0/1 nodes are available: 1 node(s) had untolerated taint {eks.amazonaws.com/compute-type: fargate}. 27 | efs-csi-controller-56f9b4cb75-bjrk7 0/1 nodes are available: 1 node(s) had untolerated taint {eks.amazonaws.com/compute-type: fargate}. 28 | 29 | eks.amazonaws.com/compute-type fargate 30 | 31 | coredns Annotations eks.amazonaws.com/compute-type ec2; kube-system namespace 32 | 0/1 nodes are available: 1 node(s) had untolerated taint {eks.amazonaws.com/compute-type: fargate}. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling.. 33 | 34 | aws-node-termination-handler-6885ff9f5c-8lkml 0/1 nodes are available: 1 node(s) had untolerated taint {node.cloudprovider.kubernetes.io/uninitialized: true}. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling.. 35 | 36 | cert-manager-6b8949bd9f-4xjv6 works fine 37 | cert-manager-webhook-7dd5f98779-4ptvk works fine 38 | 39 | cert-manager-startupapicheck-zsjtj BackOff a minute ago kubelet Back-off restarting failed container cert-manager-startupapicheck in pod 40 | 41 | cluster-autoscaler-aws-cluster-autoscaler-55946f8cb6-9wxtb 0/1 nodes are available: 1 node(s) had untolerated taint {node.cloudprovider.kubernetes.io/uninitialized: true}. preemption: 0/1 nodes are available: 1 Preemption is not helpful fo 42 | 43 | metrics-server-767bf8d8cb-kqzmn 0/1 nodes are available: 1 node(s) had untolerated taint {node.cloudprovider.kubernetes.io/uninitialized: true}. 44 | 45 | vpa-certgen-4qqrb 0/1 nodes are available: 1 node(s) had untolerated taint {eks.amazonaws.com/compute-type: fargate}. 46 | 47 | Error: creating EKS Fargate Profile (test:external-secrets_us-east-2b): operation error EKS: CreateFargateProfile, https response error StatusCode: 400, RequestID: d2c0004e-4394-4eba-8b7c-5842ba1f10da, ResourceLimitExceededException: Fargate Profile limit exceeded for cluster. 48 | 49 | ## Problem with tainted vm 50 | 51 | cert-manager-cainjector-6994f8b485-8zn4t 0/1 nodes are available: 1 node(s) had untolerated taint {node.kubernetes.io/purpose: management} 52 | cert-manager-startupapicheck-pj5xm 0/1 nodes are available: 1 node(s) had untolerated taint {node.kubernetes.io/purpose: management} 53 | cert-manager-webhook-7dd5f98779-265rs 0/1 nodes are available: 1 node(s) had untolerated taint {node.kubernetes.io/purpose: management} 54 | 55 | cluster-autoscaler-aws-cluster-autoscaler-74bb4b4ddd-7rd9t Back-off restarting failed container aws-cluster-autoscaler in pod cluster-autoscaler-aws-cluster-autoscaler-74bb4b4ddd-7rd9t_kube-system(3e8626f8-1f11-4e08-a115-b0bdd0ee6095) 56 | 57 | coredns-664b6f5f5c-bl8tx 0/1 nodes are available: 1 node(s) had untolerated taint {node.kubernetes.io/purpose: management} 58 | coredns-664b6f5f5c-h5jzw 0/1 nodes are available: 1 node(s) had untolerated taint {node.kubernetes.io/purpose: management} 59 | 60 | efs-csi-controller-56f9b4cb75-hb6tq 0/1 nodes are available: 1 node(s) had untolerated taint {node.kubernetes.io/purpose: management}. 61 | efs-csi-controller-56f9b4cb75-s6g2j 0/1 nodes are available: 1 node(s) had untolerated taint {node.kubernetes.io/purpose: management} 62 | 63 | vpa-certgen-zkkzt 0/1 nodes are available: 1 node(s) had untolerated taint {node.kubernetes.io/purpose: management}. 64 | 65 | ## Problems with labels vm 66 | 67 | ╷ 68 | │ Error: creating IAM Policy (aws-node-termination-handler-2023121322583753120000001c): MalformedPolicyDocument: Policy statement must contain resources. 69 | │ status code: 400, request id: 29a9eebd-7b9c-4d3a-9b91-c256b1514f93 70 | │ 71 | │ with module.eks.module.addons.module.aws_node_termination_handler.aws_iam_policy.this[0], 72 | │ on .terraform/modules/eks.addons.aws_node_termination_handler/main.tf line 242, in resource "aws_iam_policy" "this": 73 | │ 242: resource "aws_iam_policy" "this" { 74 | │ 75 | ╵ 76 | ╷ 77 | │ Error: creating EKS Add-On (test:aws-ebs-csi-driver): operation error EKS: CreateAddon, https response error StatusCode: 400, RequestID: 898b8647-dfd0-4777-b599-5a41052a5b6c, InvalidParameterException: ConfigurationValue provided in request is not supported: Json schema validation failed with error: [$.nodeSelector: is not defined in the schema and the schema does not allow additional properties] 78 | │ 79 | │ with module.eks.module.addons.aws_eks_addon.this["aws-ebs-csi-driver"], 80 | │ on .terraform/modules/eks.addons/main.tf line 2177, in resource "aws_eks_addon" "this": 81 | │ 2177: resource "aws_eks_addon" "this" { 82 | │ 83 | ╵ 84 | ╷ 85 | │ Error: creating EKS Add-On (test:snapshot-controller): operation error EKS: CreateAddon, https response error StatusCode: 400, RequestID: fdbb7642-2f1e-4e1a-bea2-9074d9b03488, InvalidParameterException: ConfigurationValue provided in request is not supported: Json schema validation failed with error: [$.nodeSelector: is not defined in the schema and the schema does not allow additional properties] 86 | │ 87 | │ with module.eks.module.addons.aws_eks_addon.this["snapshot-controller"], 88 | │ on .terraform/modules/eks.addons/main.tf line 2177, in resource "aws_eks_addon" "this": 89 | │ 2177: resource "aws_eks_addon" "this" { 90 | │ 91 | ╵ 92 | ╷ 93 | │ Error: creating EKS Add-On (test:vpc-cni): operation error EKS: CreateAddon, https response error StatusCode: 400, RequestID: aaecec3f-34ca-4977-bf4e-993c4c382242, InvalidParameterException: ConfigurationValue provided in request is not supported: Json schema validation failed with error: [$.nodeSelector: is not defined in the schema and the schema does not allow additional properties] 94 | │ 95 | │ with module.eks.module.addons.aws_eks_addon.this["vpc-cni"], 96 | │ on .terraform/modules/eks.addons/main.tf line 2177, in resource "aws_eks_addon" "this": 97 | │ 2177: resource "aws_eks_addon" "this" { 98 | -------------------------------------------------------------------------------- /universal_values.yaml: -------------------------------------------------------------------------------- 1 | nodeSelector: 2 | kubernetes.io/os: linux 3 | node.kubernetes.io/purpose: management 4 | tolerations: 5 | - key: node.kubernetes.io/purpose 6 | operator: Equal 7 | value: management 8 | effect: NoSchedule 9 | --------------------------------------------------------------------------------