Terraform backend-ы в Unix/Linux

Terraform сохраняет состояние управляемой инфраструктуры и ее конфигурацию. По умолчанию состояние хранится локально, в файле JSON с именем terraform.tfstate. От первого подъема до последнего изменения плана инфраструктуры каждый кусок данных заполняет файл состояния, позволяя сопоставлять реальные ресурсы с конфигурацией terraform и отслеживать метаданные.

«Бэкэнд» в Terraform — это абстракция, которая определяет обработку состояния и способ выполнения определенных операций, обеспечивая множество важных функций и служит для того, чтобы загружать state-файлы при выполнения «terraform apply».

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

  • Необходимо общее хранилище для файлов состояния — чтобы использовать Terraform для обновления вашей инфраструктуры, каждому члену вашей команды необходим доступ к одним и тем же файлам состояния Terraform. Это означает, что вам нужно хранить эти файлы в общем месте.
  • Необходима блокировка файлов состояния — как только данные передаются, вы сталкиваетесь с новой проблемой: блокировка. Без блокировки, если два члена команды одновременно используют Terraform, вы можете столкнуться с условиями гонки, поскольку несколько процессов Terraform одновременно обновляют файлы состояний, что приводит к конфликтам, потере данных и повреждению файлов состояний.
  • Необходима изоляция данных. Т.е для прода будут использоваться одни модули и стейт-файлы, для другого типа ENV — другие.

Виды Terraform backend-ов:

  • AWS S3 — Standard (с locking через DynamoDB). Сохраняет состояние в виде заданного ключа в заданном сегменте на Amazon S3. Этот бэкэнд также поддерживает блокировку состояния и проверку согласованности через DynamoDB.
  • Consul — Standard (с locking). Сохраняет состояние в Consul в виде K/V по заданному пути.
  • terraform enterprise — Standard (без блокировки).
  • Remote State Storage — использовать Terraform Cloud в качестве бэкэнда.
  • artifactory — Standard (без локинга). Сохраняет состояние как артефакт в Artifactory сервисе.
  • azurerm — Standard (с locking стейта). Сохраняет состояние как BLOB-объект с данным ключом в «Blob Container» внутри «Blob Storage Account». Этот бэкэнд также поддерживает блокировку состояния и проверку согласованности с помощью «Azure Blob Storage».
  • etcd — Standard (без лока). Сохраняет состояние в etcd 2.x по заданному пути.
  • etcdv3 — Standard (с блокировкой). Сохраняет состояние в хранилище etcd в виде K/V с заданным префиксом.
  • gcs — Standard (с локом). Сохраняет состояние как объект в настраиваемом префиксе в заданном сегменте в Google Cloud Storage (GCS). Этот бэкэнд также поддерживает блокировку состояния.
  • http — Standard (с дополнительной блокировкой). Сохраняет состояние с помощью простого клиента REST. Состояние будет получено с помощью GET, обновлено с помощью POST и очищено с помощью DELETE. Метод, используемый для обновления, настраивается.
  • manta — Standard (с локов в самой manta). Хранит стейт как артефакт в Манта.
  • OSS — Standard (с блокировкой через TableStore). Сохраняет состояние в качестве заданного ключа в заданном сегменте в хранилище Alibaba Cloud OSS. Этот бэкэнд также поддерживает блокировку состояния и проверку согласованности через Alibaba Cloud Table Store, который можно включить, установив в поле tablestore_table имя существующей таблицы TableStore.
  • pg — Standard (с блокировкой). Сохраняет состояние в базе данных Postgres версии 9.5 или новее. Этот бэкэнд поддерживает блокировку состояния.
  • swift — Standard ( без поддержки блокировки состояний). Хранит состояние как артефакт в Swift.

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

Terraform AWS S3 backend

Создаем\открываем файл:

$ vim backend.tf

Прописываем в него:

terraform {
	backend "s3" {
 		encrypt                 = true
 		bucket 	                = "terraform-state"
 		region 	                = "us-west-2"
 		key 	                = "jenkins/jenkins-aor-nonprod.tfstate"
        shared_credentials_file = "$HOME/.aws/credentials"
        profile                 = "SSO_DCOPS"
 	}
    required_providers {
        aws     = ">= 2.14.0"
    }
}

Выполняем инит:

 ⚙ captain@Macbook  ~/Projects/work/Git_repo/garson_to_aws/tf/projects/nonprod/aor   master ●  terraform-0.11 init
Initializing modules...
- module.key_pair
- module.alb
- module.iam_asg
- module.asg
- module.efs_asg
- module.iam_ecs
- module.ecs_cluster

Initializing the backend...

Initializing provider plugins...

The following providers do not have any version constraints in configuration,
so the latest version was installed.

To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.

* provider.aws: version = "~> 2.33"
* provider.template: version = "~> 2.1"

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
 ⚙ captain@Macbook  ~/Projects/work/Git_repo/garson_to_aws/tf/projects/nonprod/aor   master ● 

Чтобы сделать lock для TF, можно заюзать DynamoDB и хранить в ней локи, для этого, нужно создать таблицу, например «ship-jenkins-nonprod-tf»:

В качестве «Primary key» или «Partition key», стоит прописать «LockID». Нажимаем на создать. Сейчас нужно в backend.tf добавить «dynamodb_table» поле с вашим названием таблицы у меня это «ship-jenkins-nonprod-tf».

Открываем файл:

$ vim backend.tf

Прописываем в него:

terraform {
	backend "s3" {
 		encrypt                 = true
 		bucket 	                = "terraform-state"
 		region 	                = "us-west-2"
 		key 	                = "jenkins/jenkins-aor-nonprod.tfstate"
        dynamodb_table          = "ship-jenkins-nonprod-tf"
        shared_credentials_file = "$HOME/.aws/credentials"
        profile                 = "SSO_DCOPS"
 	}
    required_providers {
        aws     = ">= 2.14.0"
    }
}

На этой все.

Terraform Consul backend

Открываем файл:

$ vim backend.tf

Прописываем:

terraform {
  backend "consul" {
    address = "server.consul.io"
    scheme  = "https"
    path    = "my_app_project/terraform.tfstate"
  }
}

Чтобы подключить бэкенд, стоит запустить:

$ terraform init

Можно использовать переменные и переопределить кое-какие значения, например:

$ terraform init \
    -backend-config="address=my_server_here.consul.io" \
    -backend-config="path=test_project/terraform.state" \
    -backend-config="scheme=https"

Как-то так.

Terraform enterprise backend

Открываем файл:

$ vim backend.tf

Прописываем:

terraform {
  backend "atlas" {
    name = "<ORGANIZATION>/<WORKSPACE>"
    address = "https://app.terraform.io"
  }
}

Чтобы подключить бэкенд, стоит запустить:

$ terraform init

Ну и так далее по аналогии с другими примерами.

Terraform remote State Storage backend

Открываем файл:

$ vim backend.tf

Прописываем:

terraform {
  backend "remote" {
    organization = "<ORG_NAME>"

    workspaces {
      name = "Example-Workspace"
    }
  }
}

Еще, понадобится токен, который нужно будет вставить в:

$ vim ~/.terraformrc

В данный файл прописываем:

credentials "app.terraform.io" {
  token = "token"
}

Найти его можно на официальном сайте (админ панели):

Вот и все, статья «Terraform backend-ы в Unix/Linux» завершена.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.