Як перевірити конфігурацію Terraform?


37

Якщо у вас була конфігурація Terraform, яка мала помірний ступінь складності, як би ви писали тести навколо конфігурації, яка могла б бути виконана як частина конвеєра безперервної інтеграції / безперервної доставки?

Як приклад, у вас може бути конфігурація мульти хмари, яка визначає наступний бажаний стан:

  • Служби контейнерів Azure для розміщення Docker в Azure
  • Зберігання Blob Azure
  • SQL Azure
  • Служба контейнерів EC2 для розміщення Docker в AWS
  • Служба зберігання Amazon S3
  • База даних SQL Server Amazon RDS

Потенційно terraform applyможе бути створене вище з нуля, або перехід від частково розгорнутого стану до вищезгаданого стану.

Мені відомо, що Terraform розбиває свою роботу на етап плану виконання та фазу застосування, яка фактично вносить зміни в цільову архітектуру. Чи можна це використовувати для написання тестів на план виконання, якщо так, чи існують рамки, які допоможуть написати їх?



Дійсно цікаво, можливо відповідь гідна.
Річард Слейтер

Я сам не користуюся тераформою, тому дозволю комусь із реальним досвідом написати відповідь :)
Tensibai

Відповіді:


20

В даний час не існує повного рішення для цього інтегрованого в Terraform, але є деякі будівельні блоки, які можуть бути корисними для написання тестів окремою мовою програмування.

Terraform створює файли стану у форматі JSON, які, в принципі, можуть використовуватися зовнішніми програмами для отримання певних даних про те, що Terraform створив. Хоча цей формат ще не вважається офіційно стабільним, на практиці він змінюється досить рідко, щоб люди успішно інтегрувалися з ним, приймаючи, що їм, можливо, потрібно буде вносити корективи під час оновлення Terraform.

Яка стратегія тут доречна, багато що залежатиме від того, що саме ви хочете протестувати. Наприклад:

  • У середовищі, що закручує віртуальні сервери, такі інструменти, як Serverspec, можуть бути використані для запуску тестів з точки зору цих серверів. Це може бути або працювати окремо від терраформіровать з допомогою деяких з позасмугових процесу, або в якості частини терраформіровать застосовуються з використанням remote-execProvisioner . Це дозволяє перевірити питання на кшталт "чи може сервер дістатися до бази даних?", Але не підходить для запитань, таких як "чи достатньо обмежена група безпеки екземпляра?", Оскільки чітко перевіряється, що вимагає доступу до даних за межами самого екземпляра.

  • Можна написати тести, використовуючи існуючий тестовий фреймворк (наприклад, RSpec для Ruby, unittestдля Python тощо), який збирає відповідні ідентифікатори ресурсів або адреси з файлу стану Terraform, а потім використовує SDK відповідної платформи для отримання даних про ресурси і стверджує, що вони встановлюються як очікувалося. Це більш загальна форма попередньої ідеї, яка проводить тести з точки зору хоста за межами тестованої інфраструктури, і, таким чином, може збирати більш широкий набір даних для твердження.

  • Для більш скромних потреб можна вибрати довіру, що стан Terraform є точним поданням реальності (обгрунтоване припущення у багатьох випадках) і просто стверджувати безпосередньо про це. Це найбільш підходить для простих "схожих" випадків, таких як перевірка того, що правильна схема тегування ресурсів дотримується для розподілу витрат.

Про це є ще кілька дискусій у відповідному випуску Terraform Github .

В останніх версіях Terraform настійно рекомендується використовувати віддалений сервер для будь-якого додатка, який не є іграшкою, але це означає, що дані про стан не доступні безпосередньо на локальному диску. Однак її знімок можна отримати з віддаленого бекенда за допомогою terraform state pullкоманди, яка друкує дані про стан, відформатовані JSON, до stdout, щоб його можна було захопити та проаналізувати викликовою програмою.


12

Як оновлення цього питання, тепер існує кухня-Terraform, яка дозволяє тестувати файли конфігурації Terraform, не порушуючи виробниче середовище. Репозиторій також містить кілька прикладів для різних постачальників Terraform.


12

Ми нещодавно відкрили джерело Terratest , наш швейцарський армійський ніж для тестування інфраструктурного коду.

Сьогодні ви, ймовірно, випробовуєте весь свій інфраструктурний код вручну, розгортаючи, перевіряючи та нерозгортаючи. Terratest допомагає вам автоматизувати цей процес:

  1. Пишіть тести на Go.
  2. Використовуйте помічників у Terratest для виконання ваших реальних інструментів IaC (наприклад, Terraform, Packer тощо) для розгортання реальної інфраструктури (наприклад, серверів) в реальному середовищі (наприклад, AWS).
  3. Використовуйте помічників у Terratest для перевірки правильності роботи інфраструктури в цьому середовищі, роблячи HTTP-запити, API-дзвінки, SSH-з'єднання тощо.
  4. Використовуйте помічників у Terratest, щоб не розблокувати все в кінці тесту.

Ось приклад тесту для деяких кодів Terraform:

terraformOptions := &terraform.Options {
  // The path to where your Terraform code is located
  TerraformDir: "../examples/terraform-basic-example",
}

// This will run `terraform init` and `terraform apply` and fail the test if there are any errors
terraform.InitAndApply(t, terraformOptions)

// At the end of the test, run `terraform destroy` to clean up any resources that were created
defer terraform.Destroy(t, terraformOptions)

// Run `terraform output` to get the value of an output variable
instanceUrl := terraform.Output(t, terraformOptions, "instance_url")

// Verify that we get back a 200 OK with the expected text
// It can take a minute or so for the Instance to boot up, so retry a few times
expected := "Hello, World"
maxRetries := 15
timeBetweenRetries := 5 * time.Second
http_helper.HttpGetWithRetry(t, instanceUrl, 200, expected, maxRetries, timeBetweenRetries)

Це інтеграційні тести, і залежно від того, що ви тестуєте, може зайняти 5 - 50 хвилин. Це не швидко (хоча, використовуючи Docker і тестові етапи , ви можете прискорити деякі речі), і вам доведеться попрацювати, щоб зробити тести надійними, але це варто того часу.

Перегляньте репортаж Terratest щодо документів та безлічі прикладів різних типів інфраструктурного коду та відповідних тестів для них.


1
Я також написав допис у блозі, який детальніше розглядає тестування одного з моїх прикладних проектів із Terratest : rightfame.co/blog/… . Це може бути корисно для будь-кого. Ура, Роб!
Роб Морган

Великий шанувальник Terratest!
jlucktay

7

На додаток до всіх інших згаданих варіантів, хотілося б зазначити, що InSpec 2.0 додав підтримку API хмарних постачальників. В основному ви можете продовжувати писати IaC за допомогою Terraform, а потім писати перевірки на відповідність InSpec для своїх хмарних ресурсів. Крім того, InSpec підтримує написання тестів для окремих машин, якщо вам це колись потрібно.

Ось стаття Крістофа Хартмана (співавтора Inspec) про те, як використовувати Inspec з Terraform: https://lollyrock.com/articles/inspec-terraform/


5

На Aws-Side є https://github.com/k1LoW/awspec - слід мати можливість подавати в terraform.state і тестувати, чи правильно застосовується тераформа.

Але я думаю, що поза тестуванням інструменту на низькому рівні, який ви використовували, це, мабуть, краща ідея, щоб подумати про тестування цілої інфраструктури.

Ми обговорюємо цю ідею тут:

https://github.com/DomainDrivenArchitecture/dda-cloudspec/blob/development/README.md

Для тестування інваріантів наперед, я не знаю готового до використання рішення ...

Ми зробили кілька експериментів, використовуючи суміш terraform plan -out=plan.dump і grepвідсутність назв елементів. Тут обговорюється більш доступний формат плану: github.com/hashicorp/terraform/isissue/11883

На даний момент ми використовуємо процес огляду плану вручну для важливих частин нашої інфраструктури.


4
Мета полягає в тому, щоб перевірити зміни в конфігурації тераформи не порушувати очікуваних потреб. Після розгортання це занадто пізно, у кращому випадку у вас є помилка, коли базу даних видалено там, де вона не повинна, але ви вже порушили цільове середовище. .. питання полягає у тестуванні коду тераформи, а не в тестуванні кінцевого результату, одиничних тестах та інтеграційних тестах.
Тенсібай

хороший момент ... додали розділ для тестування інваріантів.
джегер

0

Я бачив цей елегантний, низький метод технологій для тесту терраформіровать запропонував apparentlymart в питанні нитки GitHub. Це не підходить для кожної ситуації, але відмінно підходить для перевірки логіки модуля.

Створіть кореневий модуль, який включає перевірений модуль та перевіряє результати недостатнього тестування. Ось простий приклад використання двох файлів:

  • main.tf що запустить тести
  • simple_module/outputs.tf що представляє тестуваний модуль

./main.tf

terraform {
  required_version = ">= 0.12"
}

module "simple_module" {
  source = "./simple_module"
}

locals {
  expected = 1
  got      = module.simple_module.module-returns-1
}

# Test Output
output "expect-1" {
  value = upper(local.expected == local.got)
}

output "expect-other" {
  value = "other" == local.got ? upper(true) : "FALSE. Got ${local.got}"
}

./simple_module/outputs.tf

output "module-returns-1" {
  value = 1
}

Виконати тести

terraform init
terraform apply -auto-approve
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

expect-1 = TRUE
expect-other = FALSE. Got 1
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.