Рубрики
Uncategorized

Непрерывная доставка на AWS с террафом и Трэвисом СИ

В этом блоговом сообщении мы хотим сочетать Terraform с автоматизированным строительным трубопроводом на Travis CI. Terraporm будет настроен на использование удаленного состояния AWS S3 с шифрованием, версиями и блокировкой. Помечено с AWS, облаком, дежоптом, террафом.

Этот пост блога является частью моей серии AWS:

  • Инфраструктура как код — управление AWS с террафом
  • Развертывание HTTP API на AWS с использованием шлюза лямбда и API
  • Развертывание HTTP API на AWS с использованием эластичного Geanstalk
  • Развертывание и сравнительный анализ AWS RDS MySQL
  • Обработка событий в AWS использует SNS, SQS и LAMBDA
  • Непрерывная доставка на AWS с террафом и Трэвисом СИ
  • Обработка данных датчика на AWS с использованием Core Iot Core, Kinesis и Elasticache
  • Мониторинг AWS Lambda функционирует с CloudWatch

В предыдущих постах мы ввели и широко использовали Terraporm для автоматизации развертывания инфраструктуры. Если вы стремитесь к истинной непрерывной доставке, высокая степень автоматизации имеет решающее значение. Непрерывная доставка (CD) состоит в том, чтобы произвести программное обеспечение в коротких циклах с высокой уверенностью, уменьшая риск получения изменений.

В этом сообщении мы хотим объединить террафору с автоматическим строительным трубопроводом на Трэвис СИ . Для использования террафора в общей настройке мы должны настроить его для использования Удаленный штат , в качестве локального состояния нельзя использовать для любого проекта, который включает в себя несколько разработчиков или автоматизированные построенные трубопроводы. Приложение, которое мы развертываем, станет статическим веб-сайтом, созданным Jekyll Отказ

Остальная часть поста структурирована следующим образом. В первом разделе мы кратко обсудим общую архитектуру решения, вкладывая фокус на инфраструктуру непрерывной развертывания. Следующий раздел собирается разработать два решения, как предоставить удаленные государственные ресурсы с использованием террафора. После этого возникнут прогулка по внедрению удаленной загрузки состояния, развертывание статического сайта и автоматизации с использованием TRAVIS CI. Мы закрываем сообщение в блоге, суммируя основные идеи.

Вышеуказанная фигура визуализирует архитектуру раствора, включая компоненты для непрерывной интеграции (CI) и CD. Клиент является разработчиком в этом случае, когда мы смотрим на настройку с точки зрения разработки.

Как только разработчик толкает новые изменения в удаленном репозитории GitHub, он вызывает сборку TRAVIS CI. Travis CI — это проведенная служба сборки, которая может бесплатно пользоваться проектами с открытым исходным кодом. Затем Трэвис создает артефакты сайта, развертывает инфраструктуру и подталкивает артефакты на производство.

Мы используем S3 Backend с Dynamodb для террафора. Terraform будет хранить состояние в S3 и использовать DynamOdb для получения блокировки при выполнении изменений. Замок важен, чтобы избежать того, чтобы две двоичные файлы террафора изменяют одно и то же состояние одновременно.

Чтобы использовать дистанционное состояние S3 удаленного состояния, нам необходимо заранее создать ведро S3 и таблицу Dynamodb. Эта загрузка также выполняется и автоматизирована с террафом. Но как нам управлять инфраструктурой с террафом, которая требуется для использования террафора? Следующий раздел обсудит два подхода для решения этой проблемы 🐔 & 🥚.

Как мы можем использовать Terraporm для настройки ведра S3 и таблицу Dynamodb, мы хотим использовать для удаленного состояния Backend? Сначала мы создаем дистанционные ресурсы Backend с местным государством. Тогда мы как-то нужно поделиться этим состоянием, чтобы позволить модификации бэкэндских ресурсов позже. От того, что я могу сказать, есть два жизнеспособных решения для этого:

  1. Общее местное государство. Подтвердите локальное состояние на вашу версию контроля и поделитесь его в удаленном хранилище.
  2. Мигрированное состояние. Миграция локального государства в удаленное государственное бэкэнд.

Оба решения включают создание ресурсов удаленного состояния с использованием локального состояния. Они отличаются тем, как государство для обеспечения удаленных государственных ресурсов совместно. Хотя первый вариант легко настроить, есть два основных риска, которые необходимо учитывать:

  • Государство террафора может содержать секреты. В случае только для ведра S3 и таблицы Dynamodb есть только одна переменная, которая может быть проблематичной: ключ доступа AWS. Если вы работаете с частным репозитором, это не может быть огромной проблемой. При работе над открытым исходным кодом может быть полезно шифровать файл состояния, прежде чем совершить его. Вы можете сделать это с Openssl или более специализированные инструменты, такие как Обязательное хранилище Отказ
  • Общий локальный штат не имеет механизма блокировки или синхронизации. При публикации своего локального состояния террафора на удаленный исходный код репозитория необходимо вручную, чтобы сохранить этот файл состояния в синхронизации со всеми разработчиками. Если кто-то делает модификации ресурсов, которые он или она должен совершить и толкать обновленный файл состояния и убедиться, что никто другой не модифицирует инфраструктуру одновременно.

Второй вариант немного безопаснее в отношении вышеупомянутых вопросов. S3 поддерживает шифрование в состоянии покоя из коробки, и вы можете иметь тонкий гранулированный контроль доступа на ведро. Также, если DynociOdB используется для блокировки, две стороны не могут одновременно изменять ресурсы. Недостатком является то, что решение является более сложным.

После того, как мы перенесем локальное состояние в созданное удаленное состояние государства, он будет содержать состояние для самого бэкэнда, а также состояние инфраструктуры приложений. К счастью, Terraform обеспечивает встроенный способ изоляции состояния различных сред: Рабочие пространства Отказ Мы можем создать отдельное рабочее пространство для бэкэндских ресурсов, чтобы избежать вмешательства между изменениями в нашей инфраструктуре Backend и инфраструктуре приложений.

Работа с рабочими областями немного сложно обернуть голову, поэтому мы собираемся решить эту опцию в ходе этого поста, чтобы узнать его подробно. На практике я не уверен, стоит ли усилие повышенной сложности, особенно как вы обычно не касаетесь бэкэндской инфраструктуры, если вы не хотите выключить проект. Следующий раздел объяснит загрузку и внедрение приложений и шаг развертывания на шаг.

Инструмент разработки стека

Для разработки решения мы используем следующие инструменты:

  • Terraform v0.11.7.
  • Jekyll 3.8.3
  • Git 2.15.2
  • Intellij + Terraform Plugin

Исходный код Доступен на Github. Теперь давайте посмотрим на детали реализации каждого компонента.

Удаленный загрузчик и настройка состояния

Мы организуем наши файлы Terraform в рабочих пространствах и папках. Рабочие пространства изолируют состояние резервного ресурса из состояния ресурса приложений. Папки будут использоваться для организации файлов ресурсов террафора.

Мы создадим два рабочих места: Государство и продлицо . Государство Рабочая область будет управлять удаленными государственными ресурсами, то есть ведро S3 и таблице Dynamodb. прод Рабочая область будет управлять производственной средой нашего веб-сайта. Вы можете добавить больше рабочих пространств для постановки или тестирования позже, но это за пределами объема этого блога.

Мы создадим три папки, содержащие файлы террафора: Bootstrap , Backend и Сайт Отказ Следующий список описывает каталог и структуру файла проекта.

.
├── locals.tf
├── providers.tf
├── backend
│   ├── backend.tf
│   ├── backend.tf.tmpl
│   ├── locals.tf -> ../locals.tf
│   ├── providers.tf -> ../providers.tf
│   └── state.tf -> ../bootstrap/state.tf
├── bootstrap
│   ├── locals.tf -> ../locals.tf
│   ├── providers.tf -> ../providers.tf
│   └── state.tf
└── website
    ├── backend.tf -> ../backend/backend.tf
    ├── locals.tf -> ../locals.tf
    ├── providers.tf -> ../providers.tf
    └── website.tf

Корень проекта будет содержать общий конфигурацию поставщика AWS Proyers.tf , а также переменная имени проекта внутри locals.tf. . Мы будем в подробности о содержании файла позже.

В дополнение к общим файлам Bootstrap Содержит State.tf , который определяет ведро S3 и Dynamodb Table Backend ресурсов ресурсов. Мы разделяем их через папки, используя символические ссылки. Backend Папка будет иметь те же ресурсы, но использует уже присутствующий бэкэн S3, определенный в backend.tf Отказ При переключении с Bootstrap к отдохнуть После первоначального обеспечения террафом будет мигрировать местное состояние на дистанционную репутацию.

Сайт Папка содержит дистанционную конфигурацию Backend и все ресурсы, связанные с фактическим развертыванием веб-сайта. Мы получим доступ к отдохнуть и Bootstrap от государство Рабочая область и Сайт от прод и любое другое дополнительное рабочее пространство, связанное с приложением.

Следующий список показывает, что Bootstrap/Stature.tf файл выглядит как. Project_Name Локальная переменная определяется в разделе «Общий |» locals.tf файл. Текущий aws_caller_identity и AWS_REGION определены в рамках общего Proyers.tf файл.

# state.tf

locals {
  state_bucket_name = "${local.project_name}-${data.aws_caller_identity.current.account_id}-${data.aws_region.current.name}"
  state_table_name = "${local.state_bucket_name}"
}

resource "aws_dynamodb_table" "locking" {
  name           = "${local.state_table_name}"
  read_capacity  = "20"
  write_capacity = "20"
  hash_key       = "LockID"

  attribute {
    name = "LockID"
    type = "S"
  }
}

resource "aws_s3_bucket" "state" {
  bucket = "${local.state_bucket_name}"
  region = "${data.aws_region.current.name}"

  versioning {
    enabled = true
  }

  server_side_encryption_configuration {
    "rule" {
      "apply_server_side_encryption_by_default" {
        sse_algorithm = "AES256"
      }
    }
  }

  tags {
    Name = "terraform-state-bucket"
    Environment = "global"
    project = "${local.project_name}"
  }
}

output "BACKEND_BUCKET_NAME" {
  value = "${aws_s3_bucket.state.bucket}"
}

output "BACKEND_TABLE_NAME" {
  value = "${aws_dynamodb_table.locking.name}"
}

Здесь мы определяем ведро S3 и включить шифрование, а также версию. Шифрование важно, поскольку состояние Terraform может содержать секретные переменные. Версификация настоятельно рекомендуется, чтобы иметь возможность откатиться в случае случайных модификаций состояния.

Мы также настраиваем таблицу Dynamodb, которая используется для блокировки. Terraform использует атрибут под названием Безразличный Поэтому мы должны создать его и сделать его главным ключом. При использовании dynamodb без автоматического масштабирования вы должны указать максимальную Читать и писать емкость Перед запросом дросселирования пинается. Если честно, я думаю, что вы должны пойти с минимумом здесь.

Теперь мы можем создать Государство Рабочая область и начать загрузку с местным государством:

  • Terraporm Workspace Новое состояние
  • Terraform Init Bootstrap.
  • Террафом применяют бутстрап

После создания ведра S3 и таблицы Dynamodb мы будем мигрировать локальное состояние. Это делается путем инициализации государственных ресурсов с недавно созданной дистанционной бэкэндом. Прежде чем мы сможем продолжить, однако нам нужно включить BackeND_BUCKET_NAME и BackeND_Table_name Переменные в Backend/Backend.tf Отказ Я сделал это, создавая файл, используя EnvStubst и Backend/backend.tf.tmpl :

# backend.tf.tmpl

terraform {
  backend "s3" {
    bucket         = "${BACKEND_BUCKET_NAME}"
    key            = "terraform.tfstate"
    region         = "eu-central-1"
    dynamodb_table = "${BACKEND_TABLE_NAME}"
  }
}

Теперь давайте инициализируем дистанционные ресурсы Backend для миграции локального состояния.

$ terraform init backend

Initializing the backend...
Do you want to migrate all workspaces to "s3"?
  Both the existing "local" backend and the newly configured "s3" backend support
  workspaces. When migrating between backends, Terraform will copy all
  workspaces (with the same names). THIS WILL OVERWRITE any conflicting
  states in the destination.

  Terraform initialization doesn't currently migrate only select workspaces.
  If you want to migrate a select number of workspaces, you must manually
  pull and push those states.

  If you answer "yes", Terraform will migrate all states. If you answer
  "no", Terraform will abort.

  Enter a value: yes


Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.

Вот и все! Мы создали пульт дистанционного состояния, используя локальное состояние и впоследствии мигрировали локальное состояние. Далее мы разверним некоторые фактические ресурсы приложений, используя бэкэнд удаленного состояния.

Статический сайт

Я выбрал статический веб-страницу в качестве примера приложения для этого поста. Причина в том, что основной фокус находится в автоматизации и работает с удаленным состоянием, поэтому этот будет сохранен довольно простым. Сайт генерируется с помощью Jekyll, а исходный код хранится в Сайт/статический Отказ

Чтобы сделать сайт общедоступным, мы будем использовать еще одно ведро S3 и настроить его для отображения файлов в качестве веб-сайта. Вот конфигурация ведра внутри Сайт/сайт.tf Отказ

# website.tf

locals {
  website_bucket_name = "${local.project_name}-${terraform.workspace}-website"
}

resource "aws_s3_bucket" "website" {
  bucket = "${local.website_bucket_name}"
  acl    = "public-read"
  policy = <

Мы настраиваем ведро, которое должно быть общедоступно, используя соответствующую ACL и политику. Мы можем настроить хостинг сайта, используя Сайт Стэнза. index_document будет подан, когда никакого конкретного ресурса не запрашивается, в то время как error_document используется, если запрошенный ресурс не существует.

Далее мы должны указать файлы HTML и CSS. Это немного громоздка, поскольку мы не можем сказать террафору, чтобы загрузить целую структуру папки. Мы также выводим URL-адрес, который можно использовать для доступа к веб-сайту в конце.

# website.tf

locals {
  site_root = "website/static/_site"
  index_html = "${local.site_root}/index.html"
  about_html = "${local.site_root}/about/index.html"
  post_html = "${local.site_root}/jekyll/update/2018/06/30/welcome-to-jekyll.html"
  error_html = "${local.site_root}/404.html"
  main_css = "${local.site_root}/assets/main.css"
}

resource "aws_s3_bucket_object" "index" {
  bucket = "${aws_s3_bucket.website.id}"
  key    = "index.html"
  source = "${local.index_html}"
  etag   = "${md5(file(local.index_html))}"
  content_type = "text/html"
}

resource "aws_s3_bucket_object" "post" {
  bucket = "${aws_s3_bucket.website.id}"
  key    = "jekyll/update/2018/06/30/welcome-to-jekyll.html"
  source = "${local.post_html}"
  etag   = "${md5(file(local.post_html))}"
  content_type = "text/html"
}

resource "aws_s3_bucket_object" "about" {
  bucket = "${aws_s3_bucket.website.id}"
  key    = "about/index.html"
  source = "${local.about_html}"
  etag   = "${md5(file(local.about_html))}"
  content_type = "text/html"
}

resource "aws_s3_bucket_object" "error" {
  bucket = "${aws_s3_bucket.website.id}"
  key    = "error.html"
  source = "${local.error_html}"
  etag   = "${md5(file(local.error_html))}"
  content_type = "text/html"
}

resource "aws_s3_bucket_object" "css" {
  bucket = "${aws_s3_bucket.website.id}"
  key    = "assets/main.css"
  source = "${local.main_css}"
  etag   = "${md5(file(local.main_css))}"
  content_type = "text/css"
}

output "url" {
  value = "http://${local.website_bucket_name}.s3-website.${aws_s3_bucket.website.region}.amazonaws.com"
}

Прежде чем мы развертываем изменения, мы должны создать новое рабочее пространство. Государство Рабочая область будет использоваться только в том случае, если нам нужно сделать модификации удаленного состояния Backend Resources. Мы назовем новое рабочее пространство прод И используйте его для инициализации и развертывания ресурсов сайта.

  • Terraporm Workspace Новый Prod
  • Terraform Init сайт
  • Веб-сайт CD/Static && Jekyll Build && CD -
  • Терраформ применять сайт
  • 🎉🎉. 🎉

«Но как насчет непрерывной доставки», я слышу, как вы спрашиваете? Следующий раздел будет покрывать настройку автоматизированной работы TRAVIS.

Работа Трэвиса

Чтобы использовать TRAVIS CI, мы должны создать файл конфигурации сборки .travis.yml.yml.yml . Просто поместите его, сообщает сервер сборки, которые выполняют команды для выполнения. Вот что мы собираемся сделать:

# .travis.yml

language: generic

install:
  - gem install bundler jekyll

script:
  - ./build.sh

build.sh Файл содержит фактическую логику. Хотя можно напрямую можно поставить все команды в файле Ямла, это немного неуклюже. Следующий список содержит содержимое сценария сборки. Обратите внимание, что мы совершили бинацию Terraform Linux в репозитории Поэтому нам не нужно загружать его в каждую сборку и обязательно иметь правильную версию.

# build.sh

cd website/static
bundle install
bundle exec jekyll build
cd -

./terraform-linux init
./terraform-linux validate website

if [[ $TRAVIS_BRANCH == 'master' ]]
then
    ./terraform-linux workspace select prod
    ./terraform-linux apply -auto-approve website
fi

Обратите внимание, что мы только развертываем изменения в производстве от главной отрасли. На других ветвях террафом только проверяет синтаксис и проверяет, что все необходимые переменные определены.

Чтобы позволить двоичному двоину террафом поговорить с AWS в рамках сервера сборки, нам также необходимо настроить учетные данные AWS. Это может быть сделано путем настройки переменных секретной среды в настройках сборки:

Тогда нам нужно только включить репозиторий на панели инструментов TRAVIS и вызвать сборку, либо нажав коммит или использование UI. Если все работает, как ожидалось, вы получите Зеленая сборка :

В этом посте мы видели, как использовать террафору в автоматизированной настройке для непрерывного развертывания. Используя комбинацию дистанционного состояния AWS Remote State Backend и рабочих мест, мы смогли решить проблему курицы и яйца при предоставлении удаленных государственных ресурсов. Затем мы развернули сгенерированный Jekyll статический сайт с использованием S3.

Однако, по моему мнению, решение с государственной миграцией и всеми символическими звеньями довольно сложна. Если возможно, я бы, вероятно, пойдет только на местное государство, и хранить его непосредственно в репозитории. Что вы думаете? Вы когда-нибудь использовали удаленный штат с террафом? Как вы его предоставили? Дай мне знать в комментариях.

Оригинал: «https://dev.to/frosnerd/continuous-delivery-on-aws-with-terraform-and-travis-ci-3914»