Terraform позволяет создать облачную инфраструктуру с помощью всего одной команды. Допустим, вы хотите запустить Elasticsearch и Kibana в кластере Kubernetes.
Для этого можно написать несколько файлов
Теперь предположим, что вам нужны и другие экземпляры стека Elastic, которые можно использовать для демонстрации. В этом случае придется создать новые рабочие пространства Terraform и выполнить
Проблема такого подхода заключается в том, что в этом случае придется каждый раз реплицировать всю инфраструктуру. Следовательно, у вас будет несколько кластеров Kubernetes. На запуск каждого кластера уходит не менее 15 минут, а его стоимость на AWS составляет 72 долл. в месяц.
Гораздо лучшей альтернативой было бы повторное использование одного кластера Kubernetes и создание на его основе нескольких сред. Таким образом, вы платите за один кластер, и вам не нужно ждать создания нового кластера каждый раз, когда вы создаете новую среду.
Именно для этого и существует Layerform. Layerform позволяет инженерам разбивать файлы Terraform на компонуемые слои. Таким образом, команды могут иметь общий базовый слой для кластера Kubernetes и несколько вышестоящих слоев с Elasticsearch, Kibana и даже другими необходимыми им бессерверными компонентами, такими как Lambdas, очереди SQS или балансировщики нагрузки.
В этой статье я расскажу о том, как работают слои, как разбить файлы Terraform на компонуемые слои и продемонстрирую несколько вариантов использования слоев. Эти случаи включают создание сред разработки, похожих на производственные, и настройку ссылок предварительного просмотра запросов на поставку для любого типа приложений.
Следует отметить, что рабочие пространства Terraform достаточно трудоемки в использовании. В официальной документации даже содержится предупреждение об их использовании.
Важно: рабочие пространства не подходят для декомпозиции системы или развертывания, требующего отдельных учетных данных и контроля доступа.
В Layerform файлы Terraform делятся на слои. В определении каждого слоя указываются входящие в него файлы и список зависимостей.
Допустим, вы хотите запустить Elasticsearch и Kibana в рамках экземпляра EKS (AWS-управляемый k8s).
Для этого у вас будет два слоя: один для
В определении слоя
Определив таким образом слои, можно самостоятельно запустить кластер EKS, выполнив команду
Затем каждый инженер может создавать собственные экземпляры
Если кому-то понадобится новый кластер, он может воссоздать весь стек, передав флаг
Закончив работу со слоями, инженеры могут уничтожить свои экземпляры слоев, не повреждая чужую работу.
В некотором смысле слои Layerform похожи на слои контейнеров. Некоторые называют их «Кастомизация для Terraform».
Для большинства команд «staging» является проблемным местом. Обычно в компаниях работает много инженеров, но есть только одна среда «staging» для всех. Соответственно, разработчики, желающие протестировать изменения в среде, похожей на производственную, вынуждены стоять в очереди.
Кроме того, если система большая или зависит от бессерверных компонентов, инженеры не могут надежно запустить все свое программное обеспечение на своих машинах. Поэтому все они обращаются к одной и той же среде staging и наступают друг другу на пятки.
Слои помогают командам решить эту проблему, позволяя каждому инженеру создавать собственную среду и совместно использовать основные элементы инфраструктуры, как было показано выше.
Layerform также предоставляет разработчикам ценные возможности для локальной разработки приложений, направляя их на
Предположим, что вы не можете запустить Elasticsearch локально, например, потому что JVM требует слишком много памяти. В этом случае можно использовать вывод layerform для получения адреса удаленного экземпляра Elasticsearch.
Вы можете использовать этот URL в файле конфигурации Kibana (
Если в конфигурационном файле необходимо интерполировать несколько выводов, как это бывает во многих приложениях, можно даже написать шаблонный файл и указать Layerform интерполировать его за вас.
В качестве примера можно привести следующий файл-шаблон для
Чтобы вывести этот файл и заменить {{
Затем инженеры могут передать полученный файл в реальный
После этого
Аналогично Terraform, Layerform может использовать удаленный back-end для хранения состояний и определений слоев.
Когда инженер создает экземпляр слоя, Layerform синхронизирует его с удаленным файлом состояний в S3. Затем, когда кто-то другой использует список экземпляров layerform, Layerform получает состояние из удаленного бэкенда и выводит актуальный список экземпляров.
Предположим, что инженер A создал первый слой. Если инженер B захочет сотрудничать с инженером A, он сможет увидеть первый слой в списке слоев, поскольку список хранится удаленно.
Затем инженер B также может получить URL-адрес экземпляра
Мы продолжаем работать над созданием надлежащих механизмов блокировки и взаимодействия, чтобы не допускать возникновения условий гонки состояний. Если вы хотите внести свой вклад в эту работу, мы приветствуем запросы на исправление.
Каждый раз, когда инженеры вносят изменения и открывают пул-реквестор, Vercel запускает свое приложение
Большинство разработчиков, дизайнеров и менеджеров по продуктам любят превью-версии Vercel. Проблема заключается в том, что эти предварительные версии не подходят для команд с более сложной конфигурацией. Например, вы не можете получить превью полного стека, если у вас есть бессерверное приложение или вам нужен кластер Kubernetes.
Сегодня большинство команд создают такие предварительные среды собственными силами, используя кучу специальных скриптов.
Layerform помогает командам решить эту проблему, позволяя им создавать отдельный слой превью. Затем инженеры могут вызвать Layerform CLI из своего CI и развернуть только ту инфраструктуру, которая им необходима.
Поскольку Layerform использует файлы Terraform, он может создавать любые типы инфраструктуры для этих предварительных версий, включая ресурсы Kubernetes, Lambdas, экземпляры SQS и ведра S3.
Например, в случае стека Elastic инженеры могут создать действие на GitHub для layerform, чтобы размножить только слой стека Elastic поверх общего кластера предварительных версий, что значительно снизит стоимость предварительных версий.
В приведенной выше схеме работы в качестве имени инстанса слоя будет использоваться имя ветки пул-реквеста.
Как и любой другой инстанс слоя он будет отображаться при запуске списка
Наконец, когда процесс создания слоя завершен, можно написать код для вызова
После этого изменения в каждом открытом PR появится ссылка на превью, указывающая на реальную производственную инфраструктуру.
Для уничтожения этих инстансов слоя необходимо создать второй рабочий процесс, который запускается при закрытии или объединении PR. Этот рабочий процесс должен вызывать
В этих примерах я предполагаю, что пользователи развернули контроллер nginx-ingress-controller на своем кластере через уровень
В любом случае, многие разработчики, вероятно, захотят держать свои среды разработки в пределах VPN, что также возможно, поскольку Layerform предоставляет всю инфраструктуру в вашем облаке с помощью простых файлов Terraform.
Когда дело доходит до развертывания собственно капсул в кластере, вы можете использовать все, что пожелаете. Когда я сам тестировал примеры, я указывал необработанные ресурсы Kubernetes через провайдера kubernetes. Тем не менее, вы можете использовать диаграммы Helm с провайдером Helm. Единственное требование для использования слоев — чтобы ваша информация находилась в файле Terraform, а не в специальных скриптах.
Наконец, еще одна интересная деталь заключается в том, что инженеры должны предоставить определения слоев удаленному внутреннему серверу с помощью
Если эта идея показалась вам интересной, пожалуйста, поставьте нам звезду на GitHub.
Возможно, захочется почитать и это:
Для этого можно написать несколько файлов
.tf
и выполнить команду terraform apply
для инициализации кластера Kubernetes и развёртывания на нем нескольких подсистем.Теперь предположим, что вам нужны и другие экземпляры стека Elastic, которые можно использовать для демонстрации. В этом случае придется создать новые рабочие пространства Terraform и выполнить
terraform apply
несколько раз.Проблема такого подхода заключается в том, что в этом случае придется каждый раз реплицировать всю инфраструктуру. Следовательно, у вас будет несколько кластеров Kubernetes. На запуск каждого кластера уходит не менее 15 минут, а его стоимость на AWS составляет 72 долл. в месяц.
Гораздо лучшей альтернативой было бы повторное использование одного кластера Kubernetes и создание на его основе нескольких сред. Таким образом, вы платите за один кластер, и вам не нужно ждать создания нового кластера каждый раз, когда вы создаете новую среду.
Именно для этого и существует Layerform. Layerform позволяет инженерам разбивать файлы Terraform на компонуемые слои. Таким образом, команды могут иметь общий базовый слой для кластера Kubernetes и несколько вышестоящих слоев с Elasticsearch, Kibana и даже другими необходимыми им бессерверными компонентами, такими как Lambdas, очереди SQS или балансировщики нагрузки.
В этой статье я расскажу о том, как работают слои, как разбить файлы Terraform на компонуемые слои и продемонстрирую несколько вариантов использования слоев. Эти случаи включают создание сред разработки, похожих на производственные, и настройку ссылок предварительного просмотра запросов на поставку для любого типа приложений.
Следует отметить, что рабочие пространства Terraform достаточно трудоемки в использовании. В официальной документации даже содержится предупреждение об их использовании.
Важно: рабочие пространства не подходят для декомпозиции системы или развертывания, требующего отдельных учетных данных и контроля доступа.
❯ Как работают слои
В Layerform файлы Terraform делятся на слои. В определении каждого слоя указываются входящие в него файлы и список зависимостей.
Допустим, вы хотите запустить Elasticsearch и Kibana в рамках экземпляра EKS (AWS-управляемый k8s).
Для этого у вас будет два слоя: один для
eks
, другой для elastic_stack
.{
"layers": [
{
"name": "eks",
"files": ["layers/eks.tf", "layers/eks/**"]
},
{
"name": "elastic_stack",
"files": ["layers/elastic_stack.tf", "layers/elastic_stack/**"],
"dependencies": ["eks"]
}
]
}
В определении слоя
eks
указывается, какие файлы относятся к этому слою. Поскольку eks
не зависит ни от какой другой инфраструктуры, он не будет указывать другие слои в качестве зависимостей. С другой стороны, файлы слоя elastic_stack
зависят от eks
. Следовательно, он будет включать eks как зависимость.Определив таким образом слои, можно самостоятельно запустить кластер EKS, выполнив команду
layerform spawn eks default
.Затем каждый инженер может создавать собственные экземпляры
elastic_stack
и повторно использовать один и тот же кластер. Для этого все они выполняют команду layerform spawn elastic_stack <_name_>
, и каждый из этих слоев ищет нижележащий слой eks
с идентификатором default
.➜ layerform list instances
INSTANCE NAME LAYER NAME DEPENDENCIES
default eks
first elastic_stack eks=default
second elastic_stack eks=default
Если кому-то понадобится новый кластер, он может воссоздать весь стек, передав флаг
--base
, как в layerform spawn elastic_stack third --base eks=another_eks
.➜ layerform list instances
INSTANCE NAME LAYER NAME DEPENDENCIES
default eks
another_eks eks
first elastic_stack eks=default
second elastic_stack eks=default
third elastic_stack eks=another_eks
Закончив работу со слоями, инженеры могут уничтожить свои экземпляры слоев, не повреждая чужую работу.
В некотором смысле слои Layerform похожи на слои контейнеров. Некоторые называют их «Кастомизация для Terraform».
❯ Использование слоев для создания сред разработки
Для большинства команд «staging» является проблемным местом. Обычно в компаниях работает много инженеров, но есть только одна среда «staging» для всех. Соответственно, разработчики, желающие протестировать изменения в среде, похожей на производственную, вынуждены стоять в очереди.
Кроме того, если система большая или зависит от бессерверных компонентов, инженеры не могут надежно запустить все свое программное обеспечение на своих машинах. Поэтому все они обращаются к одной и той же среде staging и наступают друг другу на пятки.
Слои помогают командам решить эту проблему, позволяя каждому инженеру создавать собственную среду и совместно использовать основные элементы инфраструктуры, как было показано выше.
Layerform также предоставляет разработчикам ценные возможности для локальной разработки приложений, направляя их на
back-end
своей среды «staging».Предположим, что вы не можете запустить Elasticsearch локально, например, потому что JVM требует слишком много памяти. В этом случае можно использовать вывод layerform для получения адреса удаленного экземпляра Elasticsearch.
➜ layerform output elastic_stack first
{
"cluster_name": {
"sensitive": false,
"type": "string",
"value": "demo-eks-post-example"
},
"elasticsearch_url": {
"sensitive": false,
"type": "string",
"value": "https://elasticsearch-post-example.environment.ergomake.link"
}
}
Вы можете использовать этот URL в файле конфигурации Kibana (
config.yml
). Таким образом, в процессе разработки можно будет указывать локальную Kibana на удаленный Elasticsearch.elasticsearch.hosts:
["https://elasticsearch-post-example.environment.ergomake.link"]
Если в конфигурационном файле необходимо интерполировать несколько выводов, как это бывает во многих приложениях, можно даже написать шаблонный файл и указать Layerform интерполировать его за вас.
В качестве примера можно привести следующий файл-шаблон для
config.yml
Kibana.elasticsearch.hosts: ["{{elasticsearch_url.value}}"]
Чтобы вывести этот файл и заменить {{
elasticsearch_url.value
}} реальными значениями для конкретного слоя, можно использовать флаг --template
для вывода выведенного файла в stdout
.➜ layerform output elastic_stack first --template config/kibana-template.yml
elasticsearch.hosts: ['http://elastic-stack-xehl-es.environment.ergomake.link']
Затем инженеры могут передать полученный файл в реальный
config.yml
и использовать его, не зная ничего о слоях и не вводя значения вручную.➜ layerform output elastic_stack first --template config/kibana-template.yml > config.yml
После этого
yarn start
заставит Kibana прочитать config.yml
и указать на удаленный Elasticsearch.❯ Примечание по совместной работе со слоями
Аналогично Terraform, Layerform может использовать удаленный back-end для хранения состояний и определений слоев.
Когда инженер создает экземпляр слоя, Layerform синхронизирует его с удаленным файлом состояний в S3. Затем, когда кто-то другой использует список экземпляров layerform, Layerform получает состояние из удаленного бэкенда и выводит актуальный список экземпляров.
Предположим, что инженер A создал первый слой. Если инженер B захочет сотрудничать с инженером A, он сможет увидеть первый слой в списке слоев, поскольку список хранится удаленно.
# Выполнено инженером B
➜ layerform list instances
INSTANCE NAME LAYER NAME DEPENDENCIES
default eks
first elastic_stack eks=default
Затем инженер B также может получить URL-адрес экземпляра
Elasticsearch
в первом слое, выполнив вывод layerform
.Мы продолжаем работать над созданием надлежащих механизмов блокировки и взаимодействия, чтобы не допускать возникновения условий гонки состояний. Если вы хотите внести свой вклад в эту работу, мы приветствуем запросы на исправление.
❯ Использование слоев для превью пул-реквестов
Каждый раз, когда инженеры вносят изменения и открывают пул-реквестор, Vercel запускает свое приложение
Next.js
и добавляет ссылку на превью в PR.Большинство разработчиков, дизайнеров и менеджеров по продуктам любят превью-версии Vercel. Проблема заключается в том, что эти предварительные версии не подходят для команд с более сложной конфигурацией. Например, вы не можете получить превью полного стека, если у вас есть бессерверное приложение или вам нужен кластер Kubernetes.
Сегодня большинство команд создают такие предварительные среды собственными силами, используя кучу специальных скриптов.
Layerform помогает командам решить эту проблему, позволяя им создавать отдельный слой превью. Затем инженеры могут вызвать Layerform CLI из своего CI и развернуть только ту инфраструктуру, которая им необходима.
Поскольку Layerform использует файлы Terraform, он может создавать любые типы инфраструктуры для этих предварительных версий, включая ресурсы Kubernetes, Lambdas, экземпляры SQS и ведра S3.
Например, в случае стека Elastic инженеры могут создать действие на GitHub для layerform, чтобы размножить только слой стека Elastic поверх общего кластера предварительных версий, что значительно снизит стоимость предварительных версий.
name: Preview
on:
pull_request:
jobs:
preview:
runs-on: ubuntu-latest
steps:
# + + Проверка кода, установка deps и т.д..
- name: Install Layerform
run: go install github.com/ergomake/layerform@main
# Настройка удаленного статуса - мы будем улучшать это
- name: Create Layerform config file
run: |
mkdir -p ~/.layerform
echo "currentContext: demo" > ~/.layerform/config
echo "contexts:" >> ~/.layerform/config
echo " demo:" >> ~/.layerform/config
echo " type: s3" >> ~/.layerform/config
echo " bucket: layerform-post-demo" >> ~/.layerform/config
echo " region: us-west-1" >> ~/.layerform/config
# Собственно создание слоя превью
- id: layerform
name: Spawn Elasticstack using Layerform
run: |
layerform spawn elastic_stack ${{ github.event.pull_request.head.ref }}
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
В приведенной выше схеме работы в качестве имени инстанса слоя будет использоваться имя ветки пул-реквеста.
Как и любой другой инстанс слоя он будет отображаться при запуске списка
layerform
, поэтому при желании можно подключиться к нему и из терминала.Наконец, когда процесс создания слоя завершен, можно написать код для вызова
layerform output
и добавить комментарий со ссылкой на превью к пул-реквесту.# ...
# Получение URL Kibana из результатов layerform с помощью jq
- id: layerform
name: Spawn Elasticstack using Layerform
run: |
layerform spawn elastic_stack ${{ github.event.pull_request.head.ref }}
kibana=$(layerform output elastic_stack ${{ github.event.pull_request.head.ref }} | jq -r .kibana_url.value)
echo "kibana=$kibana" >> "$GITHUB_OUTPUT"
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
# Добавление комментария к пул-реквесту
- uses: actions/github-script@v6
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '${{ steps.layerform.outputs.kibana }}'
})
После этого изменения в каждом открытом PR появится ссылка на превью, указывающая на реальную производственную инфраструктуру.
Для уничтожения этих инстансов слоя необходимо создать второй рабочий процесс, который запускается при закрытии или объединении PR. Этот рабочий процесс должен вызывать
layerform kill
и передавать ему имя слоя, которое в данном случае совпадает с именем ветки.имя: Уничтожать предварительные просмотры при закрытии PR
name: Destroy previews when PRs are closed
on:
pull_request:
types: [closed]
jobs:
kill_preview:
runs-on: ubuntu-latest
steps:
# + Проверка кода, установка deps и т.д..
- name: Install Layerform
run: go install github.com/ergomake/layerform@main
- name: Kill preview
run: layerform kill elastic_stack ${{ github.event.pull_request.head.ref }}
❯ Дополнительные заметки по внедрению
В этих примерах я предполагаю, что пользователи развернули контроллер nginx-ingress-controller на своем кластере через уровень
eks
. Этот контроллер отвечает за создание nlb
и открытие Elasticsearch
и Kibana
для выхода в Интернет через их ингрессы.В любом случае, многие разработчики, вероятно, захотят держать свои среды разработки в пределах VPN, что также возможно, поскольку Layerform предоставляет всю инфраструктуру в вашем облаке с помощью простых файлов Terraform.
Когда дело доходит до развертывания собственно капсул в кластере, вы можете использовать все, что пожелаете. Когда я сам тестировал примеры, я указывал необработанные ресурсы Kubernetes через провайдера kubernetes. Тем не менее, вы можете использовать диаграммы Helm с провайдером Helm. Единственное требование для использования слоев — чтобы ваша информация находилась в файле Terraform, а не в специальных скриптах.
Наконец, еще одна интересная деталь заключается в том, что инженеры должны предоставить определения слоев удаленному внутреннему серверу с помощью
layerform configure
, прежде чем кто-либо сможет породить экземпляры.Если эта идея показалась вам интересной, пожалуйста, поставьте нам звезду на GitHub.