{"id":13575512,"url":"https://github.com/maddevsio/aws-eks-base","last_synced_at":"2025-05-15T07:04:44.997Z","repository":{"id":38366963,"uuid":"345692117","full_name":"maddevsio/aws-eks-base","owner":"maddevsio","description":"This boilerplate contains terraform configurations for the rapid deployment of a Kubernetes cluster, supporting services, and the underlying infrastructure in AWS.","archived":false,"fork":false,"pushed_at":"2025-05-02T11:27:25.000Z","size":1410,"stargazers_count":631,"open_issues_count":14,"forks_count":110,"subscribers_count":15,"default_branch":"main","last_synced_at":"2025-05-02T11:39:59.539Z","etag":null,"topics":["amazon-eks","aws","boilerplate","eks","eks-cluster","hashicorp-terraform","infrastructure","k8s-cluster","kubernetes","kubernetes-clusters","serverless-kubernetes-cluster","terraform","terraform-files","terraform-module","terraform-module-manager"],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/maddevsio.png","metadata":{"files":{"readme":"README-RU.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-03-08T14:55:35.000Z","updated_at":"2025-04-29T10:02:23.000Z","dependencies_parsed_at":"2023-01-19T16:03:54.410Z","dependency_job_id":"3d24cd37-3ec4-48f2-a9ff-6bcd2f7d188b","html_url":"https://github.com/maddevsio/aws-eks-base","commit_stats":{"total_commits":417,"total_committers":20,"mean_commits":20.85,"dds":0.7482014388489209,"last_synced_commit":"15ad5fa2827e0915048b75d06e7f3c8d4650df62"},"previous_names":[],"tags_count":16,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maddevsio%2Faws-eks-base","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maddevsio%2Faws-eks-base/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maddevsio%2Faws-eks-base/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maddevsio%2Faws-eks-base/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/maddevsio","download_url":"https://codeload.github.com/maddevsio/aws-eks-base/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254292039,"owners_count":22046426,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["amazon-eks","aws","boilerplate","eks","eks-cluster","hashicorp-terraform","infrastructure","k8s-cluster","kubernetes","kubernetes-clusters","serverless-kubernetes-cluster","terraform","terraform-files","terraform-module","terraform-module-manager"],"created_at":"2024-08-01T15:01:01.706Z","updated_at":"2025-05-15T07:04:39.983Z","avatar_url":"https://github.com/maddevsio.png","language":"HCL","funding_links":[],"categories":["HCL","boilerplate"],"sub_categories":[],"readme":"# Бойлерплейт базовой AWS инфраструктуры c EKS-кластером\n\n[![Developed by Mad Devs](https://maddevs.io/badge-dark.svg)](https://maddevs.io/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n## Преимущества этого бойлерплейта\n\n- Инфраструктура как код (IaC): используя Terraform, вы получаете налаженную и продуктивную инфраструктуру\n- Управление состоянием: Terraform сохраняет текущее состояние инфраструктуры, поэтому вы можете просматривать последующие изменения, не применяя их. Также возможность хранить стейт удаленно позволяет работать над инфраструктурой в команде\n- Масштабируемость и гибкость: инфраструктуру, построенную на основе этого бойлерплейта, можно расширять и обновлять ​​в любое время\n- Дополнения: вы получаете инструменты масштабирования и мониторинга вместе с базовой инфраструктурой. Вам не нужно вручную ничего изменять в инфраструктуре; вы можете просто подправить что-то в Terraform по мере необходимости и задеплоить это в AWS и Kubernetes\n- Контроль над ресурсами: подход IaC делает инфраструктуру более наблюдаемой и предотвращает растрату ресурсов\n- Четкая документация: ваш код в Terraform фактически становится вашей проектной документацией. Это означает, что вы можете добавлять новых членов в команду, и им не понадобится слишком много времени, чтобы понять, как работает инфраструктура\n\n## Причины использовать этот бойлерплейт\n\n- Безопасный и отшлифованный: мы использовали эти решения в наших собственных крупномасштабных, высоконагруженных проектах. Мы месяцами совершенствовали этот процесс построения инфраструктуры, чтобы в результате получилась безопасная в использовании, защищенная и надежная система\n- Экономит время: вы можете потратить недели на собственные поиски и неизбежные ошибки, чтобы построить такую инфраструктуру. Или же вы можете положиться на этот бойлерплейт и поднять нужную инфраструктуру в течение дня\n- Свободный: мы рады делиться результатами своей работы\n\n[![boilerplate asciicast](https://asciinema.org/a/wCS0HdC6UViWDKO7GypyIJjaB.png)](https://asciinema.org/a/wCS0HdC6UViWDKO7GypyIJjaB?autoplay=1\u0026speed=2)\n\n## Описание\n\nВ данном репозитории собраны наработки команды Mad Devs для быстрого развертывания Kubernetes кластера, вспомогательных сервисов и нижележащей инфраструктуры в облаке Amazon. Основным инструментом разработки и поставки является [terraform](https://www.terraform.io/).\n\nЗа время работы компании мы перепробовали много инфраструктурных решений и сервисов, и прошли путь от on-premise железа до serverless. В итоге на текущий момент нашей стандартной платформой для развертывания приложений стал Kubernetes, а основным облаком - AWS. \n\nТут стоит отметить, что несмотря на то, что 90% наших и клиентских проектов хостится на AWS, а в качестве Kubernetes платформы используется [AWS EKS](https://aws.amazon.com/eks/), мы не упираемся рогом, не тащим все подряд в Kubernetes и не заставляем хостится в AWS. Kubernetes предлагается только после сбора и анализа требований к архитектуре сервиса. \n\nА далее при выборе Kubernetes - приложениям почти не важно, как создан сам кластер - вручную, через kops или используя managed услуги облачных провайдеров - в своей основе платформа Kubernetes везде одинакова. И выбор конкретного провайдера уже складывается из дополнительных требований, экспертизы и т.д.\n\nМы знаем, что текущая реализация далеко не идеальна. Например, в кластер мы деплоим сервисы с помощью `terraform` - это довольно топорно и против подходов кубера, но это удобно для бутстрапа - т.к. используя стейт и интерполяцию, мы передаем необходимые `ids`, `arns` и другие указатели на ресурсы и имена или секреты в шаблоны и генерим из них `values` для нужных чартов, не выходя за пределы терраформа. \n\nЕсть более специфичные минусы: ресурсы `data \"template_file\"`, которые мы использовали для большинства шаблонов, крайне неудобны для разработки и отладки, особенно если это такие 500+ строчные рулоны, типа `terraform/layer2-k8s/templates/elk-values.yaml`. Также, смотря на `helm3` и избавление от `tiller` - большое количество helm-релизов все равно в какой-то момент приводит к зависанию плана. Частично, но не всегда решается путем таргетированного апплая `terraform apply -target`, но для консистентности стейта желательно выполнять `plan` и `apply` целиком на всей конфигурации. Если собираетесь использовать данный бойлер, желательно разбить слой `terraform/layer2-k8s` на несколько, вынеся крупные и комплексные релизы в отдельные подслои.\n\nМогут возникнуть справедливые вопросы к количеству `.tf` файлов. Оно конечно просится на рефакторинг и \"обмодуливание\". Чем мы и займемся в ближайшее время, разбивая этот монолит на микромодули и вводя `terragrunt`, попутно решая озвученные проблемы выше.\n\nБолее подробно о нашем бойлерплейте смотрите в видео:\n\n[![boilerplate youtube video](https://img.youtube.com/vi/loqSDGgtmKg/0.jpg)](https://youtu.be/loqSDGgtmKg)\n\n## Оглавление\n\n- [Бойлерплейт базовой AWS инфраструктуры c EKS-кластером](#бойлерплейт-базовой-aws-инфраструктуры-c-eks-кластером)\n  - [Преимущества этого бойлерплейта](#преимущества-этого-бойлерплейта)\n  - [Причины использовать этот бойлерплейт](#причины-использовать-этот-бойлерплейт)\n  - [Описание](#описание)\n  - [Оглавление](#оглавление)\n  - [Архитектурная схема](#архитектурная-схема)\n  - [Стоимость текущей инфры](#стоимость-текущей-инфры)\n  - [Структура неймспейсов в K8S кластере](#структура-неймспейсов-в-k8s-кластере)\n  - [Необходимый инструментарий](#необходимый-инструментарий)\n  - [Полезные экстеншены VSCode](#полезные-экстеншены-vscode)\n  - [AWS аккаунт](#aws-аккаунт)\n    - [Настройки IAM](#настройки-iam)\n    - [Настройка awscli](#настройка-awscli)\n  - [Как использовать этот репо](#как-использовать-этот-репо)\n    - [Подготовка](#подготовка)\n      - [S3 state backend](#s3-state-backend)\n      - [Входные данные](#входные-данные)\n      - [Секреты](#секреты)\n      - [Домен и SSL](#домен-и-ssl)\n    - [Работа с terraform](#работа-с-terraform)\n      - [init](#init)\n      - [plan](#plan)\n      - [apply](#apply)\n    - [terragrunt](#terragrunt)\n  - [Что делать после деплоя](#что-делать-после-деплоя)\n    - [examples](#examples)\n  - [Coding conventions](#coding-conventions)\n    - [Имена и подходы, используемые в коде](#имена-и-подходы-используемые-в-коде)\n      - [Базовое имя проекта](#базовое-имя-проекта)\n      - [Формирование уникального префикса имен ресурсов](#формирование-уникального-префикса-имен-ресурсов)\n      - [Разделители](#разделители)\n      - [Формирование имен ресурсов](#формирование-имен-ресурсов)\n      - [Формирование имен переменных](#формирование-имен-переменных)\n      - [Формирование имен вывода данных](#формирование-имен-вывода-данных)\n    - [Название файлов, директорий и модулей терраформа](#название-файлов-директорий-и-модулей-терраформа)\n      - [Общие конфигурационные файлы](#общие-конфигурационные-файлы)\n      - [Специфичные конфигурационные файлы](#специфичные-конфигурационные-файлы)\n      - [Модули](#модули)\n  - [### Структура проекта](#-структура-проекта)\n\n## Архитектурная схема\n\n![aws-base-diagram](docs/aws-base-diagrams-Infrastracture-v6.svg)\n\nЭта схема описывает инфраструктуру, создаваемую по умолчанию.\nНебольшое описание того, что мы имеем на схеме. Инфраструктура в облаке AWS\n\n- Мы используем три availability Zone\n- Основная сеть VPC\n  - Три публичные подсети для ресурсов, которые должны быть доступны из интернета\n    - Elastic load balancing - точка входа в k8s cluster\n    - Internet gateway - точка входа в созданную VPC\n    - Single Nat Gateway - сервис для организации доступа для инстансов из приватных сетей в публичные.\n  - Три приватные подсети с доступом к интернету через Nat Gateway\n  - Три интра подсети без доступа в интернет\n  - Три приватные подсети для RDS\n  - Route tables для приватных сетей\n  - Route tables для публичных сетей\n- Autoscaling groups\n  - On-demand - эта группа с 1-5 on-demand instances для ресурсов с требованиями бесперебойной работы\n  - Spot     - эта группа с 1-6 spot instances для ресурсов, которым не критично прерывание работы\n  - CI       - эта группа с 0-3 spot instances, создающихся по требованию gitlab-runner, расположены в публичной сети\n- EKS control plane - это узлы плоскости управления кластеров k8s\n- Route53 - сервис для управления DNS\n- Cloudwatch - сервис для получения метрик о состоянии работы ресурсов в облаке AWS\n- AWS Certificate manager - сервис для управления сертификатами AWS\n- SSM parameter store - сервис для хранения, извлечения и контроля значений конфигурации\n- S3 bucket - это бакет используется для хранения terraform state\n- Elastic container registry - сервис для хранения docker images\n\n## Стоимость текущей инфры\n\n| Resource      | Type/size                | Price per hour $ | Price per GB $ | Number | Monthly cost      |\n|---------------|--------------------------|-----------------:|---------------:|-------:|------------------:|\n| EKS           |                          | 0.1              |                | 1      | 73                |\n| EC2 ondemand  | t3.medium                | 0.0456           |                | 1      | 33,288            |\n| EC2 Spot      | t3.medium/t3a.medium     | 0.0137/0.0125    |                | 1      | 10                |\n| EC2 Spot Ci   | t3.medium/t3a.medium     | 0.0137/0.0125    |                | 0      | 10                |\n| EBS           | 100 Gb                   |                  | 0.11           | 2      | 22                |\n| NAT gateway   |                          | 0.048            | 0.048          | 1      | 35                |\n| Load Balancer | Classic                  | 0.028            | 0.008          | 1      | 20.44             |\n| S3            | Standart                 |                  |                | 1      | 1                 |\n| ECR           | 10 Gb                    |                  |                | 2      | 1.00              |\n| Route53       | 1 Hosted Zone            |                  |                | 1      | 0.50              |\n| Cloudwatch    | First 10 Metrics - free  |                  |                |        | 0                 |\n|               |                          |                  |                | Total  | 216.8             |\n\n\u003e Стоимость указана без подсчета количества трафика для Nat Gateway Load Balancer и S3\n\n## Структура неймспейсов в K8S кластере\n\nНа этой схеме указаны неймспейсы, которые используются в кластере, и ресурсы, которые находятся в этих неймспесах по умолчанию.\n\n![aws-base-namespaces](docs/aws-base-diagrams-Namespaces-v3.svg)\n\nИспользуемые в кластере чарты, с указанием неймспейса и коротким описанием.\n\n| Namespace   |  service                                                                                                            | Description                                                                                                             |\n|-------------|---------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------|\n| kube-system | [core-DNS](https://github.com/coredns/coredns)                                                                      | DNS сервер, используемый в кластере                                                                                      |\n| certmanager | [cert-manager](https://github.com/jetstack/cert-manager)                                                            | Cервис для автоматизации управления и получения сертификатов TLS                                                        |\n| certmanager | [cluster-issuer](https://gitlab.com/madboiler/devops/aws-eks-base/-/tree/master/helm-charts/cluster-issuer)         | Ресурс, представляющий центр сертификации, который может генерировать подписанные сертификаты, выполняя запросы подписи. |\n| ing         | [nginx-ingress](https://github.com/kubernetes/ingress-nginx)                                                        | Ингресс контролер, который использует nginx в качестве реверс прокси.                                                   |\n| ing         | [Certificate](https://gitlab.com/madboiler/devops/aws-eks-base/-/tree/master/helm-charts/certificate)               | Объект сертификата, который используется для nginx-ingress.                                                             |\n| dns         | [external-dns](https://github.com/bitnami/charts/tree/master/bitnami/external-dns)                                  | Сервис для организации доступа к внешним DNS из кластера.                                                               |\n| ci          | [gitlab-runner](https://gitlab.com/gitlab-org/charts/gitlab-runner)                                                 | Гитлаб раннер используемый для запуска агентов gitlab-ci.                                                                |\n| sys         | [aws-node-termination-handler](https://github.com/aws/eks-charts/tree/master/stable/aws-node-termination-handler)   | Сервис для контроля корректного завершения работы EC2.                                                                  |\n| sys         | [autoscaler](https://github.com/kubernetes/autoscaler)                                                              | Сервис, который автоматически регулирует размер k8s кластера в зависимости от требований.                                |\n| sys         | [kubernetes-external-secrets](https://github.com/external-secrets/kubernetes-external-secrets)                      | Сервис для работы с внешними хранилищами секретов, такими как secret-manager, ssm parameter store и тд.                 |\n| sys         | [Reloader](https://github.com/stakater/Reloader)                                                                    | Сервис, который следит за изменения внешних секретов и обновляет их в кластере.                                          |\n| monitoring  | [kube-prometheus-stack](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack) | Зонтичный чарт включает в себя группу сервисов, используемых для мониторинга работы кластера и визуализации данных.       |\n| monitoring  | [loki-stack](https://github.com/grafana/loki/tree/master/production/helm/loki-stack)                                | Зонтичный чарт включает в себя сервис сбора логов контейнеров и визуализации данных.                                    |\n| elk         | [elk](https://gitlab.com/madboiler/devops/aws-eks-base/-/tree/master/helm-charts/elk)                               | Зонтичный чарт включает в себя группу сервисов, для сбора логов, метрик и визуализации этих данных.                     |\n\n## Необходимый инструментарий\n\n- [tfenv](https://github.com/tfutils/tfenv) - утилита для менеджмента разных версий терраформа, необходимую версию можно задать напрямую аргументом или через `.terraform-version`\n- [terraform](https://www.terraform.io/) - тот самый терраформ, наш главный инструмент разработки: `tfenv install`\n- [awscli](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) - консольная утилита для работы с AWS API\n- [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) - консольная тула для работы с кубер кластерами\n- [kubectx + kubens](https://github.com/ahmetb/kubectx) - консольные тулы для kubectl помогают переключаться между кластерами и неймспейсами Kubernetes\n- [helm](https://helm.sh/docs/intro/install/) - пакетный менеджер для деплоя приоложений в кубер\n- [helmfile](https://github.com/roboll/helmfile) - \"докер композ\" для хелм чартов\n- [terragrunt](https://terragrunt.gruntwork.io/) - небольшой wrapper для терраформа обеспечивающий DRY для некоторых статичных частей терраформ кода\n- [awsudo](https://github.com/meltwater/awsudo) - простая консольная утилита, позволяющая запускать команды awscli из-под определенных ролей\n- [aws-vault](https://github.com/99designs/aws-vault) - тула для секурного менеджмента ключей AWS и запуска консольных команд\n- [aws-mfa](https://github.com/broamski/aws-mfa) - утилита для автоматизации получения временных реквизитов доступа к AWS с включенным MFA\n- [vscode](https://code.visualstudio.com/) - основная IDE\n\n\u003e Опционально, можно поставить и сконфигурить пре-коммит хук для терраформа: [pre-commit-terraform](https://github.com/antonbabenko/pre-commit-terraform), что позволит форматировать и проверять код еще на этапе коммита\n\n## Полезные экстеншены VSCode\n\n- [editorconfig](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig)\n- [terraform](https://marketplace.visualstudio.com/items?itemName=4ops.terraform)\n- [drawio](https://marketplace.visualstudio.com/items?itemName=hediet.vscode-drawio)\n- [yaml](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml)\n- [embrace](https://marketplace.visualstudio.com/items?itemName=mycelo.embrace)\n- [js-beautify](https://marketplace.visualstudio.com/items?itemName=HookyQR.beautify)\n- [docker](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker)\n- [git-extension-pack](https://marketplace.visualstudio.com/items?itemName=donjayamanne.git-extension-pack)\n- [githistory](https://marketplace.visualstudio.com/items?itemName=donjayamanne.githistory)\n- [kubernetes-tools](https://marketplace.visualstudio.com/items?itemName=ms-kubernetes-tools.vscode-kubernetes-tools)\n- [markdown-preview-enhanced](https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced)\n- [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint)\n- [file-tree-generator](https://marketplace.visualstudio.com/items?itemName=Shinotatwu-DS.file-tree-generator)\n- [gotemplate-syntax](https://marketplace.visualstudio.com/items?itemName=casualjim.gotemplate)\n\n## AWS аккаунт\n\nМы не будем сильно углубляться в настройки безопасности, тк требования у всех разные. Однако есть самые простые и базовые шаги, которые стоит выполнить, чтобы идти дальше. Если у вас все готово, смело пропускайте этот раздел.\n\n\u003e Крайне не рекомендуется использовать рутовый аккаунт для работы с AWS. Не ленитесь создавать пользователей с требуемыми/ограниченными правами.\n\n### Настройки IAM\n\nИтак, вы создали акк, прошли подтверждение, возможно уже даже создали Access Keys для консоли. В любом случае перейдите в настройки безопасности [аккаунта](https://console.aws.amazon.com/iam/home#/security_credentials) и обязательно выполните следующие шаги:\n\n- Задайте сильный пароль\n- Активируйте MFA для root аккаунта\n- Удалите и не создавайте access keys root аккаунта\n\nДалее в [IAM](https://console.aws.amazon.com/iam/home#/home) консоли:\n\n- В разделе [Policies](https://console.aws.amazon.com/iam/home#/policies) создайте политику `MFASecurity`, запрещающую пользователям пользоваться сервисами без активации [MFA](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_aws_my-sec-creds-self-manage-mfa-only.html)\n- В разделе [Roles](https://console.aws.amazon.com/iam/home?region=us-east-1#/roles) создайте новую роль `administrator`. Выберете *Another AWS Account*, указав в поле Account ID номер нашего аккаунт. Отметьте галочку *Require MFA*. В следующем окне Permissions прикрепите к ней политику `AdministratorAccess`\n- В разделе [Policies](https://console.aws.amazon.com/iam/home#/policies) создайте политику `assumeAdminRole`:\n\n  ```json\n  {\n    \"Version\": \"2012-10-17\",\n    \"Statement\": {\n        \"Effect\": \"Allow\",\n        \"Action\": \"sts:AssumeRole\",\n        \"Resource\": \"arn:aws:iam::730809894724:role/administrator\"\n    }\n  }\n  ```\n- В разделе [Groups](https://console.aws.amazon.com/iam/home#/groups) создайте группу `admin`, в следующем окне прикрепите к ней политику `assumeAdminRole` и `MFASecurity`. Завершите создание группы.\n- В разделе [Users](https://console.aws.amazon.com/iam/home#/users) создайте пользователя для работы с AWS, выбрав обе галочки в *Select AWS access type*. В следующем окне добавьте пользователя в группу `admin`. Завершите создание и скачайте CSV с реквизитами доступа.\n\n\u003e В рамках этой доки мы не рассмотрели более секурный и правильный метод управления пользователями, используя внешние Identity провайдеры. Такие как G-suite, Okta и [другие](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers.html).\n\n### Настройка awscli\n\n- Terraform умеет работать с переменными окружения для [AWS access key ID and a secret access key](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys) или AWS профилем, в данном примере создадим aws profile:\n\n  ```bash\n  $ aws configure --profile maddevs\n  AWS Access Key ID [None]: *****************\n  AWS Secret Access Key [None]: *********************\n  Default region name [None]: us-east-1\n  Default output format [None]: json\n  ```\n\n  ```bash\n  $ export AWS_PROFILE=maddevs\n  ```\n- Далее пройдите по [ссылке](https://docs.aws.amazon.com/neptune/latest/userguide/iam-auth-temporary-credentials.html), чтобы узнать как получить временные токены\n- В качестве альтернативы, для того чтобы использовать `awscli` и соответственно `terraform` с [MFA](https://aws.amazon.com/premiumsupport/knowledge-center/authenticate-mfa-cli/), можно использовать `aws-mfa`, `aws-vault` и `awsudo`\n\n## Как использовать этот репо\n\n### Подготовка\n\n#### S3 state backend\n\nВ качестве бэкенда для хранения стейтов терраформа и для обмена данными между слоями используется S3. Есть два способа настроить бэкенд: создать вручную `backend.tf` файл в каждом слое и более простой способ - выполнить из `terraform/`:\n\n  ```bash\n  $ export TF_REMOTE_STATE_BUCKET=my-new-state-bucket\n  $ terragrunt run-all init\n  ```\n\n#### Входные данные\n\nВ файле `terraform/demo.tfvars.example` представлен пример со значениями для терраформа. Скопируйте его в `terraform/terraform.tfvars` и отредактируйте по своему усмотрению:\n\n```bash\n$ cp terraform/layer1-aws/demo.tfvars.example terraform/layer1-aws/terraform.tfvars\n```\n\n\u003e Все возможные параметры можно посмотреть в Readme для каждого слоя.\n\n#### Секреты\n\nВ корне `layer2-k8s` лежит файл `aws-sm-secrets.tf`, ожидающий значения, заданные в секрете `/${local.name}-${local.environment}/infra/layer2-k8s` сервиса [AWS Secrets Manager](https://console.aws.amazon.com/secretsmanager/home?region=us-east-1#!/home). Данный секрет используется для аутентификации в Kibana и Grafana используя GitLab. Также задается токен для регистрации гитлаб раннера, параметры slack для алертменеджера:\n\n  ```json\n  {\n    \"kibana_gitlab_client_id\": \"access key token\",\n    \"kibana_gitlab_client_secret\": \"secret key token\",\n    \"kibana_gitlab_group\": \"gitlab group\",\n    \"grafana_gitlab_client_id\": \"access key token\",\n    \"grafana_gitlab_client_secret\": \"secret key token\",\n    \"gitlab_registration_token\": \"gitlab-runner token\",\n    \"grafana_gitlab_group\": \"gitlab group\",\n    \"alertmanager_slack_url\": \"slack url\",\n    \"alertmanager_slack_channel\": \"slack channel\"\n  }\n  ```\n\n\u003e Задайте все необходимые значения, можно задать пустые значения. В случае если вы не будете использовать данные секреты, следует удалить этот `.tf` файл из корня `layer2-k8s`\n\n#### Домен и SSL\n\nНеобходимо будет купить или подключить уже купленный домен в Route53. Имя домена и айди зоны нужно будет задать в переменных `domain_name` и `zone_id` в слое layer1.\n\nПо умолчанию значение переменной `create_acm_certificate = false`. Что указывает терраформу запросить arn существующего ACM сертификата. Установите значение `true` если вы хотите, чтобы терраформ создал новый SSL сертификат.\n\n### Работа с terraform\n\n#### init\n\nКоманда `terraform init` используется для инициализации стейта и его бэкенда, провайдеров, плагинов и модулей. Это первая команда, которую необходимо выполнить в `layer1` и `layer2`:\n\n  ```bash\n  $ terraform init\n  ```\n\n  Правильный аутпут:\n\n  ```\n  * provider.aws: version = \"~\u003e 2.10\"\n  * provider.local: version = \"~\u003e 1.2\"\n  * provider.null: version = \"~\u003e 2.1\"\n  * provider.random: version = \"~\u003e 2.1\"\n  * provider.template: version = \"~\u003e 2.1\"\n\n  Terraform has been successfully initialized!\n  ```\n\n#### plan\n\nКоманда `terraform plan` считывает стейт терраформа, конфигурационные файлы и выводит список изменений и действий, которые необходимо произвести, чтобы привести стейт в соответствие с конфигурацией. Удобный способ проверить изменения перед применением. В случае использования с параметром `-out` сохраняет пакет изменений в указанный файл, который позже можно будет использовать при `terraform apply`. Пример вызова:\n\n  ```bash\n  $ terraform plan\n  # ~600 rows skipped\n  Plan: 82 to add, 0 to change, 0 to destroy.\n\n  ------------------------------------------------------------------------\n\n  Note: You didn't specify an \"-out\" parameter to save this plan, so Terraform\n  can't guarantee that exactly these actions will be performed if\n  \"terraform apply\" is subsequently run.\n  ```\n\n#### apply\n\nКоманда `terraform apply` сканирует `.tf` в текущей директории и приводит стейт к описанной в них конфигурации, производя изменения в инфраструктуре. По умолчанию перед применение производится `plan` с диалогом о продолжении. Опционально можно указать в качестве инпута сохраненный план файл:\n\n  ```bash\n  $ terraform apply\n  # ~600 rows skipped\n  Plan: 82 to add, 0 to change, 0 to destroy.\n\n  Do you want to perform these actions?\n    Terraform will perform the actions described above.\n    Only 'yes' will be accepted to approve.\n\n    Enter a value: yes\n\n  Apply complete! Resources: 82 added, 0 changed, 0 destroyed.\n  ```\n\nНе всегда нам нужно перечитывать и сравнивать весь стейт, если были добавлены небольшие изменения не влияющие на всю инфру. Для таких целей можно использовать таргетный `apply`, например:\n\n  ```bash\n  $ terraform apply -target helm_release.kibana\n  ```\n\nБолее подробно можно почитать по этой [ссылке](https://www.terraform.io/docs/cli/run/index.html)\n\n\u003e Первый раз команда `apply` должна производиться в слоях по порядку: сначала layer1, следом layer2.\nА `destroy` инфраструктуры должен производиться в обратном порядке.\n\n### terragrunt\n\nДля упрощения создания remote state бакета и бэкенд конфигурации терраформа мы добавили `terragrunt`. Все, что нужно - это задать имя бакета в переменной окружения `TF_REMOTE_STATE_BUCKET` и выполнить команды terragrunt из директории `terraform/`:\n\n ```bash\n $ export TF_REMOTE_STATE_BUCKET=my-new-state-bucket\n $ terragrunt run-all init\n $ terragrunt run-all apply\n ```\n\nТаким образом `terragrunt` создаст бакет, подготовит бэкенд терраформа, последовательно в layer-1 и layer-2 произведет `terraform init` и `terraform apply`.\n\n## Что делать после деплоя\n\nПосле апплая данной конфигурации вы получите инфраструктуру, описанную и обрисованную в начале документа. В AWS и внутри EKS кластера будут созданы базовые ресурсы и сервисы, необходимые для работы EKS k8s кластера.\n\nПолучить доступ к кластеру можно командой:\n\n  ```bash\n  aws eks update-kubeconfig --name maddevs-demo-use1 --region us-east-1\n  ```\n\n### examples\n\nВ каждом слое находится директория `examples/`, которая содержит рабочие примеры, расширяющие базовую конфигурацию. Название файлов и содержимое соответствует нашим кодинг соглашениям, поэтому дополнительное описание не требуется. Если необходимо что-то заюзать - достаточно перенести из этой папки в корень слоя.\n\nЭто позволит расширить вам базовый функционал запустив систему мониторинга на базе ELK или Prometheus Stack и тд\n## Coding conventions\n\nВ данном разделе собраны самые базовые рекомендации для пользователей и контрибьютеров по написанию кода, неймингу и тд. Задача - однородный, стандартизированный, читаемый код. Дополнение, предложения и изменения - приветствуется.\n\n### Имена и подходы, используемые в коде\n\n#### Базовое имя проекта\n\nБазовое имя задается в переменной name в variables.tf, используется при формировании уникальных имен ресурсов:\n\n```\nvariable \"name\" {\n  default = \"demo\"\n}\n```\n\n#### Формирование уникального префикса имен ресурсов\n\nНа базе переменной name, целевого региона (переменная region) и значения terraform.workspace мы формируем уникальный префикс для имен ресурсов:\n\n```\nlocals {\n  env            = terraform.workspace == \"default\" ? var.environment : terraform.workspace\n  short_region   = var.short_region[var.region]\n  name           = \"${var.name}-${local.env}-${local.short_region}\"\n}\n```\n\nПример префикса:\n\n- name = \"demo\"\n- region = \"us-east-2\"\n- terraform.workspace = \"test\"\n\n`demo-test-use2`\n\nПосле чего значение `local.name` используется в качестве префикса для всех атрибутов `name` и `name_prefix`. Это позволяет нам запускать копии инфраструктуры даже в одном аккаунте.\n\n#### Разделители\n\n- Для атрибутов `name` или `name_prefix` у ресурсов, модулей и тд, а так же для значений данных вывода в качестве разделителя используется символ дефиса `-`:\n\n  ```\n  name = \"${local.name}-example\"\n  ```\n\n  или\n\n  ```\n  name = \"demo-test-use2-example\"\n  ```\n\n- Для сложных имен в объявлении ресурсов, переменных, модулей, аутпутов в коде используется символ подчёркивания `_`:\n\n  ```\n  resource \"aws_iam_role_policy_attachment\" \"pritunl_server\"{\n  }\n\n  variable \"cluster_name\" {\n  }\n\n  module \"security_groups\" {\n  }\n  ```\n\n#### Формирование имен ресурсов\n\n- Не следует повторять тип ресурса в имени ресурса (ни частично, ни полностью):\n  - Хорошо: `resource \"aws_route_table\" \"public\" {}`\n  - Плохо: `resource \"aws_route_table\" \"public_route_table\" {}`\n  - Плохо: `resource \"aws_route_table\" \"public_aws_route_table\" {}`\n\n- Если ресурс уникален в рамках модуля, следует при именовании использовать `this`. Например модуль содержит один ресурс типа `aws_nat_gateway` и несколько ресурсов типа `aws_route_table`, в этом случае `aws_nat_gateway` должен быть назван `this`, а  `aws_route_table` должны иметь более осмысленные имена,например `private`, `public`, `database`:\n\n  ```\n  resource \"aws_nat_gateway\" \"this\" {\n    ...\n  }\n  resource \"aws_route_table\" \"public\"{\n    ...\n  }\n  resource \"aws_route_table\" \"private\"{\n    ...\n  }\n  ```\n\n- Для имен должны использоваться существительные\n- В большинстве случаев, если ресурс поддерживает параметр `name_prefix`, следует использовать его вместо параметра `name`\n\n#### Формирование имен переменных\n\n- Используйте те же имена переменных, описание и значение по умолчанию, как определено в официальной документации терраформ для ресурса, над которым вы работаете\n- Не указывать `type = \"list\"`, если есть `default = []`\n- Не указывать `type = \"map\"`, если есть `default = {}`\n- Используйте множественное число в имени переменных типа list и map:\n\n  ```\n  variable \"rds_parameters\" {\n  default = [\n    {\n      name  = \"log_min_duration_statement\"\n      value = \"2000\"\n    },\n  ]\n  }\n  ```\n\n- Всегда используйте description для переменных\n- При объявлении переменных соблюдайте следующий порядок ключей: `description`, `type`, `default`\n- Чем выше уровень объявления переменной, тем желательней использовать семантические префиксы для каждой переменной:\n\n  ```\n  variable \"ecs_instance_type\" {\n  ...\n  }\n\n  variable \"rds_instance_type\" {\n  ...\n  }\n  ```\n\n#### Формирование имен вывода данных\n\n- Имена вывода данных должны быть понятны за пределами терраформ и вне контекста модуля (когда пользователь использует модуль, должны быть понятны тип и атрибут возвращаемого значения)\n\n- Общая рекомендация для именования вывода данных заключается в том, что имя должно описывать содержащееся в ней значение и не иметь излишеств\n\n- Правильная структура для имен вывода выглядит как `{name}_{type}_{attribute}` для неуникальных атрибутов и ресурсов и `{type}_{attribute}` для уникальных, например вывод одной из нескольких security групп и уникального публичного адреса:\n\n  ```\n  output \"alb_security_group_id\" {\n    description = \"The ID of the example security group\"\n    value       = \"${aws_security_group.alb.id}\"\n  }\n\n  output \"public_ip\" {\n    description = \"Public Ip Address of the Elasti IP assigned to ec2 instance\"\n    value       = \"${aws_eip.this.public_ip}\"\n  }\n  ```\n\n- Если возвращаемое значение является списком, оно должно иметь имя во множественном числе\n- Всегда используйте description для вывода данных\n\n### Название файлов, директорий и модулей терраформа\n\n#### Общие конфигурационные файлы\n\nКаждый модуль и конфигурация терраформа содержит набор общих файлов заканчивающихся на `.tf`:\n\n- `main.tf` - содержит настройки терраформа, если это верхний слой; или основной рабочий код, если это модуль\n- `variables.tf` - входные значения конфигурации или модуля\n- `outputs.tf` - выходные значения конфигурации или модуля\n\nПомимо этого могут присутствовать:\n\n- `locals.tf` - содержит набор переменных, полученных путем интерполяции из remote state, outputs, variables и тд.\n- `providers.tf` - содержит настройки провайдеров терраформа, например `aws`, `kubernetes` и тд\n- `iam.tf` - сюда могут быть вынесены IAM конфигурации политик, ролей и тд\n\nЭто не конечный список, каждая конфигурация, модуль или слой могут нуждаться в дополнительных файлах и манифестах. Задача - называть их как можно ёмче и ближе по смыслу к содержимому. Префиксы не использовать.\n\n\u003e Самом терраформу не важно, сколько файлов вы создаете. Он собирает все манифесты слоев и модулей в один объект, строит зависимости и исполняет.\n\n#### Специфичные конфигурационные файлы\n\nК таким конфигурационным файлам и манифестам можно отнести следующее: темплейты для ресурсов `data \"template_file\"` или `templatefile()`, вынесенная в отдельный `.tf` файл логическая группа ресурсов, один или несколько деплойментов в кубер с помощью `resource \"helm_release\"`, создание aws ресурсов не требующих отдельного модуля, инициализация модуля и тд.\n\n\u003e Справедливо будет заметить, что раз создается какая-то логическая группа ресурсов и это будет реюзаться, то почему не вынести это все в отдельный модуль. Но оказалось, что менеджить хелм релизы, темплейты для них и дополнительные ресурсы проще в отдельных .tf файлах в корне слоя. И для многих таких конфигураций с переездом в модули количество кода может удвоиться + в модули обычно мы переносим то, что собираемся реюзать.\n\nКаждый специфичный `.tf` файл должен начинаться с префикса, указывающего на сервис или провайдер, к которому относится основнoй создаваемый ресурс или группа, например `aws`. Следом опционально указывается тип сервиса, например `iam`. Далее идет название главного сервиса или ресурса или группы ресурсов, которые декларируется внутри, после чего опционально может быть добавлен поясняющий суффикс, если таких файлов будет несколько. Все части имени разделены `дефисами`.\n\nИтого формула выглядит так:\n`provider|servicename`-[`optional resource/service type`]-`main resourcename|group-name`-[`optional suffix`].tf\n\nПримеры:\n\n- `aws-vpc.tf` - терраформ манифест описывающий создание единственной vpc\n- `aws-vpc-stage.tf` - терраформ манифест описывающий создание одной из vpc, для стейджинга\n- `eks-namespaces.tf` - группа неймспейсов, создаваемых в EKS кластере\n- `eks-external-dns.tf` - содержит описание деплоя external-dns сервиса в EKS кластер\n- `aws-ec2-pritunl.tf` - содержит инициализацию модуля, который создает EC2 инстанс в AWS с настроенным pritunl\n\n#### Модули\n\nПодход к названию директорий модулей точно такой же, как и к специфичным `.tf` файлам и соответствует формуле:\n`provider|servicename`-[`optional resource/service type`]-`main resourcename|group-name`-[`optional suffix`]\n\nПримеры:\n\n- `eks-rbac-ci` - модуль для создания рбак для CI внутри EKS кластера\n- `aws-iam-autoscaler` - модуль для создания IAM политик для автоскейлера\n- `aws-ec2-pritunl` -  модуль для создания pritunl ec2 инстанса\n\n### Структура проекта\n---\n\n| FILE / DIRECTORY| DESCRIPTION   |\n| --------------- |:-------------:|\n| docker/      | кастомные и модифицированные докерфайлы|\n| examples/    | примеры k8s деплойментов |\n| helm-charts/ | тут находятся используемые чарты |\n| helm-charts/certificate | чарт создающий ssl сертификат для nginx-ingress |\n| helm-charts/cluster-issuer | чарт создающий cluster-issuer используя CRD cert-manager |\n| helm-charts/elk | зонтичный чарт для деплоя elk стэка |\n| helm-charts/teamcity | helm chart для деплоя teamcity агента иои сервера |\n|terraform/| здесь лежат файли терраформа |\n|terraform/layer1-aws| базовые AWS ресурсы |\n|terraform/layer2-k8s| здесь лежит описание ресурсов для деплоя в EKS |\n|terraform/modules| директория содержащая небольшие самописные модули |\n|.editorconfig| |\n|.gitlab-ci.yml||\n|.pre-commit-config.yaml||\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaddevsio%2Faws-eks-base","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaddevsio%2Faws-eks-base","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaddevsio%2Faws-eks-base/lists"}