Вступ до Terraform для початківців – підручник Terraform

Бажаєте дізнатися, що таке Terraform? Давайте заглибимося в цю тему.

Інфраструктура як код (IaC) – це концепція, яка набула широкого поширення серед фахівців DevOps. Вона передбачає керування та створення всієї ІТ-інфраструктури, як фізичної, так і віртуальної, за допомогою файлів конфігурації, призначених для читання машиною. По суті, це застосування принципів розробки програмного забезпечення до операційних процесів. Це дозволяє автоматизувати роботу цілих центрів обробки даних за допомогою програмних сценаріїв.

Попри безліч переваг, IaC має певні виклики:

  • Потрібні знання програмування.
  • Складно передбачити наслідки змін.
  • Не завжди просто скасувати зроблені зміни.
  • Ускладнено відстеження історії змін.
  • Автоматизація ресурсів може бути непростою.
  • Різні середовища вимагають окремого підходу до інфраструктури.

Terraform було розроблено саме для вирішення цих проблем.

Отже, що ж таке Terraform?

Terraform – це інструмент з відкритим вихідним кодом для управління інфраструктурою як кодом, створений компанією HashiCorp. Він дає змогу описувати та створювати інфраструктуру за допомогою простої декларативної мови.

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

Ось деякі з переваг використання Terraform:

  • Забезпечує оркестрацію, а не лише управління конфігурацією.
  • Підтримує багатьох провайдерів, як-от AWS, Azure, GCP, DigitalOcean тощо.
  • Створює незмінну інфраструктуру, де конфігурація оновлюється поступово.
  • Використовує зрозумілу мову HCL (мова конфігурації HashiCorp).
  • Легко переноситься між різними провайдерами.
  • Застосовує клієнтську архітектуру, усуваючи потребу в додатковому управлінні конфігурацією на сервері.

Ключові поняття Terraform

Розгляньмо основні терміни та концепції, які використовуються в Terraform:

  • Змінні: Вхідні параметри, представлені у вигляді пар ключ-значення, які модулі Terraform використовують для налаштування.
  • Провайдер: Плагін для взаємодії з API конкретного сервісу та доступу до його ресурсів.
  • Модуль: Тека, що містить шаблони Terraform з усіма необхідними конфігураціями.
  • Стан: Кешована інформація про інфраструктуру, керовану Terraform, а також відповідні конфігурації.
  • Ресурси: Блок, що описує один або декілька об’єктів інфраструктури (обчислювальні екземпляри, віртуальні мережі тощо), які використовуються для налаштування та управління інфраструктурою.
  • Джерела даних: Реалізація постачальниками для отримання інформації про зовнішні об’єкти, необхідної Terraform.
  • Вихідні значення: Дані, що повертаються модулем Terraform, які можуть використовувати інші конфігурації.
  • План: Етап, на якому визначається, які ресурси потрібно створити, змінити або видалити, щоб досягти бажаного стану інфраструктури.
  • Застосування: Етап, на якому Terraform вносить зміни у поточний стан інфраструктури відповідно до плану, щоб досягти бажаного стану.

Життєвий цикл Terraform

Життєвий цикл Terraform складається з чотирьох етапів: ініціалізація, планування, застосування та знищення.

  • Terraform init ініціалізує робочу директорію, де зберігаються файли конфігурації.
  • Terraform plan створює план виконання для досягнення бажаного стану інфраструктури, враховуючи зміни в конфігураційних файлах.
  • Terraform apply вносить зміни в інфраструктуру відповідно до створеного плану, приводячи її до потрібного стану.
  • Terraform destroy використовується для видалення всіх ресурсів інфраструктури, які були створені та позначені як непотрібні після фази застосування.

Як працює Terraform?

Архітектура Terraform складається з двох основних компонентів:

Terraform Core

Terraform Core використовує два джерела вхідних даних для виконання своєї роботи:

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

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

Провайдери

Другим важливим компонентом архітектури є провайдери для конкретних технологій. Це можуть бути хмарні провайдери, такі як AWS, Azure, GCP, або інші платформи інфраструктури як сервіс. Також існують провайдери компонентів вищого рівня, наприклад, Kubernetes, або різних інструментів платформи як сервіс та навіть інструментів самообслуговування.

Це дозволяє створювати інфраструктуру на різних рівнях.

Наприклад, ви можете спочатку створити інфраструктуру в AWS, потім розгорнути Kubernetes на ній, а вже потім створити необхідні сервіси та компоненти в кластері Kubernetes.

Terraform має понад сотню провайдерів для різних технологій, і кожен з них надає користувачам доступ до ресурсів відповідної платформи. Наприклад, через провайдера AWS ви отримуєте доступ до сотень ресурсів AWS, таких як інстанції EC2, користувачі AWS тощо. За допомогою провайдера Kubernetes ви можете керувати такими ресурсами, як сервіси, розгортання та простори імен.

Саме так працює Terraform, допомагаючи вам забезпечити та налаштувати повний стек вашого застосунку, від інфраструктури до самої програми.

Перейдемо до практики. 👨‍💻

Давайте встановимо Terraform на Ubuntu та створимо базову інфраструктуру.

Встановлення Terraform

Завантажте останню версію Terraform.

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

[email protected]:~$ wget https://releases.hashicorp.com/terraform/0.13.0/terraform_0.13.0_linux_amd64.zip
--2020-08-14 16:55:38--
https://releases.hashicorp.com/terraform/0.13.0/terraform_0.13.0_linux_amd64.zip
Resolving releases.hashicorp.com (releases.hashicorp.com)... 151.101.153.183, 2a04:4e42:24::439
Connecting to releases.hashicorp.com (releases.hashicorp.com)|151.101.153.183|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 34851622 (33M) [application/zip]
Saving to: ‘terraform_0.13.0_linux_amd64.zip’

terraform_0.13.0_linux_amd64.zip
100%[=================================================================>] 33.24M
90.3KB/s in 5m 28s

2020-08-14 17:01:06 (104 KB/s) - ‘terraform_0.13.0_linux_amd64.zip’ saved [34851622/34851622]

Розпакуйте завантажений архів.

[email protected]:~$ unzip terraform_0.13.0_linux_amd64.zip
Archive:
terraform_0.13.0_linux_amd64.zip
inflating: terraform

Перемістіть виконуваний файл terraform у зазначений нижче шлях та перевірте версію Terraform.

[email protected]:~$ sudo mv terraform /usr/local/bin/
[sudo] password for techukraine.net:
[email protected]:~$ terraform -v
Terraform v0.13.0

Тепер ви можете побачити список доступних команд Terraform.

[email protected]:~$ terraform
Usage: terraform [-version] [-help] <command> [args]

The available commands for execution are listed below.
The most common, useful commands are shown first, followed by
less common or more advanced commands. If you're just getting
started with Terraform, stick with the common commands. For the
other commands, please read the help and docs before usage.

Common commands:
apply Builds or changes infrastructure
console Interactive console for Terraform interpolations
destroy Destroy Terraform-managed infrastructure
env Workspace management
fmt Rewrites config files to canonical format
get Download and install modules for the configuration
graph Create a visual graph of Terraform resources
import Import existing infrastructure into Terraform
init Initialize a Terraform working directory
login Obtain and save credentials for a remote host
logout Remove locally-stored credentials for a remote host
output Read an output from a state file
plan Generate and show an execution plan
providers Prints a tree of the providers used in the configuration
refresh Update local state file against real resources
show Inspect Terraform state or plan
taint Manually mark a resource for recreation
untaint Manually unmark a resource as tainted
validate Validates the Terraform files
version Prints the Terraform version
workspace Workspace management

All other commands:
0.12upgrade Rewrites pre-0.12 module source code for v0.12
0.13upgrade Rewrites pre-0.13 module source code for v0.13
debug Debug output management (experimental)
force-unlock Manually unlock the terraform state
push Obsolete command for Terraform Enterprise legacy (v1)
state Advanced state management

Створення екземпляра AWS EC2 за допомогою Terraform

У цьому прикладі ми запустимо новий екземпляр AWS EC2 за допомогою Terraform.

Створіть робочу директорію для цього прикладу Terraform.

[email protected]:~$ mkdir terraform_demo

Перейдіть до директорії та створіть файл конфігурації Terraform, де ви визначите провайдера та ресурси для запуску екземпляра AWS EC2.

[email protected]:~/terraform_demo$ gedit awsec2.tf

provider "aws" {
access_key = "B5KG6Fe5GUKIATUF5UD"
secret_key = "R4gb65y56GBF6765ejYSJA4YtaZ+T6GY7H"
region = "us-west-2"
}

resource "aws_instance" "terraform_demo" {
ami = "ami-0a634ae95e11c6f91"
instance_type = "t2.micro"
}

Примітка: ключі доступу та секретні ключі у прикладі змінено, вам потрібно використовувати свої власні облікові дані.

У наведеній конфігурації ви бачите, що ми вказуємо провайдера, наприклад, AWS. Всередині провайдера ми надаємо облікові дані користувача AWS та регіон, де має бути запущений екземпляр.

В розділі ресурсів ми вказуємо AMI для Ubuntu (ami-0a634ae95e11c6f91) і задаємо тип інстансу t2.micro.

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

terraform init

Першим кроком є ініціалізація Terraform.

[email protected]:~/terraform_demo$ terraform init

Initializing the backend...

Initializing provider plugins...
- Using previously-installed hashicorp/aws v3.2.0

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, we recommend adding version constraints in a required_providers block
in your configuration, with the constraint strings suggested below.

* hashicorp/aws: version = "~> 3.2.0"

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.

terraform plan

Наступний крок – планування. Terraform створить план виконання для створення інфраструктури.

[email protected]:~/terraform_demo$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create

Terraform will perform the following actions:

# aws_instance.terraform_demo will be created
+ resource "aws_instance" "terraform_demo" {
+ ami = "ami-0a634ae95e11c6f91"
+ arn = (known after apply)
+ associate_public_ip_address = (known after apply)
+ availability_zone = (known after apply)
+ cpu_core_count = (known after apply)
+ cpu_threads_per_core = (known after apply)
+ get_password_data = false
+ host_id = (known after apply)
+ id = (known after apply)
+ instance_state = (known after apply)
+ instance_type = "t2.micro"
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply)
+ key_name = (known after apply)
+ outpost_arn = (known after apply)
+ password_data = (known after apply)
+ placement_group = (known after apply)
+ primary_network_interface_id = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ secondary_private_ips = (known after apply)
+ security_groups = (known after apply)
+ source_dest_check = true
+ subnet_id = (known after apply)
+ tenancy = (known after apply)
+ volume_tags = (known after apply)
+ vpc_security_group_ids = (known after apply)

+ ebs_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ snapshot_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}

+ ephemeral_block_device {
+ device_name = (known after apply)
+ no_device = (known after apply)
+ virtual_name = (known after apply)
}

+ metadata_options {
+ http_endpoint = (known after apply)
+ http_put_response_hop_limit = (known after apply)
+ http_tokens = (known after apply)
}

+ network_interface {
+ delete_on_termination = (known after apply)
+ device_index = (known after apply)
+ network_interface_id = (known after apply)
}

+ root_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
}

Plan: 1 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

terraform apply

На етапі застосування, Terraform виконає конфігураційний файл та запустить екземпляр AWS EC2. Коли ви запустите команду apply, вона запитає вас: “Ви хочете виконати ці дії?”, вам потрібно ввести yes і натиснути Enter.

[email protected]:~/terraform_demo$ terraform apply

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create

Terraform will perform the following actions:

# aws_instance.terraform_demo will be created
+ resource "aws_instance" "terraform_demo" {
+ ami = "ami-0a634ae95e11c6f91"
+ arn = (known after apply)
+ associate_public_ip_address = (known after apply)
+ availability_zone = (known after apply)
+ cpu_core_count = (known after apply)
+ cpu_threads_per_core = (known after apply)
+ get_password_data = false
+ host_id = (known after apply)
+ id = (known after apply)
+ instance_state = (known after apply)
+ instance_type = "t2.micro"
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply)
+ key_name = (known after apply)
+ outpost_arn = (known after apply)
+ password_data = (known after apply)
+ placement_group = (known after apply)
+ primary_network_interface_id = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ secondary_private_ips = (known after apply)
+ security_groups = (known after apply)
+ source_dest_check = true
+ subnet_id = (known after apply)
+ tenancy = (known after apply)
+ volume_tags = (known after apply)
+ vpc_security_group_ids = (known after apply)

+ ebs_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ snapshot_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}

+ ephemeral_block_device {
+ device_name = (known after apply)
+ no_device = (known after apply)
+ virtual_name = (known after apply)
}

+ metadata_options {
+ http_endpoint = (known after apply)
+ http_put_response_hop_limit = (known after apply)
+ http_tokens = (known after apply)
}

+ network_interface {
+ delete_on_termination = (known after apply)
+ device_index = (known after apply)
+ network_interface_id = (known after apply)
}

+ root_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
}

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.

Enter a value: yes

aws_instance.terraform_demo: Creating...
aws_instance.terraform_demo: Still creating... [10s elapsed]
aws_instance.terraform_demo: Still creating... [20s elapsed]
aws_instance.terraform_demo: Still creating... [30s elapsed]
aws_instance.terraform_demo: Still creating... [40s elapsed]
aws_instance.terraform_demo: Creation complete after 44s [id=i-0eec33286ea4b0740]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Перейдіть до панелі керування AWS EC2, і ви побачите, що створено новий екземпляр з ідентифікатором, зазначеним в кінці команди застосування.

Отже, ви успішно запустили екземпляр AWS EC2 за допомогою Terraform.

terraform destroy

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

[email protected]:~/terraform_demo$ terraform destroy
aws_instance.terraform_demo: Refreshing state... [id=i-0eec33286ea4b0740]

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
- destroy

Terraform will perform the following actions:

# aws_instance.terraform_demo will be destroyed
- resource "aws_instance" "terraform_demo" {
- ami = "ami-0a634ae95e11c6f91" -> null
- arn = "arn:aws:ec2:us-west-2:259212389929:instance/i-0eec33286ea4b0740" -> null
- associate_public_ip_address = true -> null
- availability_zone = "us-west-2c" -> null
- cpu_core_count = 1 -> null
- cpu_threads_per_core = 1 -> null
- disable_api_termination = false -> null
- ebs_optimized = false -> null
- get_password_data = false -> null
- hibernation = false -> null
- id = "i-0eec33286ea4b0740" -> null
- instance_state = "running" -> null
- instance_type = "t2.micro" -> null
- ipv6_address_count = 0 -> null
- ipv6_addresses = [] -> null
- monitoring = false -> null
- primary_network_interface_id = "eni-02a46f2802fd15634" -> null
- private_dns = "ip-172-31-13-160.us-west-2.compute.internal" -> null
- private_ip = "172.31.13.160" -> null
- public_dns = "ec2-34-221-77-94.us-west-2.compute.amazonaws.com" -> null
- public_ip = "34.221.77.94" -> null
- secondary_private_ips = [] -> null
- security_groups = [
- "default",
] -> null
- source_dest_check = true -> null
- subnet_id = "subnet-5551200c" -> null
- tags = {} -> null
- tenancy = "default" -> null
- volume_tags = {} -> null
- vpc_security_group_ids = [
- "sg-b5b480d1",
] -> null

- credit_specification {
- cpu_credits = "standard" -> null
}

- metadata_options {
- http_endpoint = "enabled" -> null
- http_put_response_hop_limit = 1 -> null
- http_tokens = "optional" -> null
}

- root_block_device {
- delete_on_termination = true -> null
- device_name = "/dev/sda1" -> null
- encrypted = false -> null
- iops = 100 -> null
- volume_id = "vol-0be2673afff6b1a86" -> null
- volume_size = 8 -> null
- volume_type = "gp2" -> null
}
}

Plan: 0 to add, 0 to change, 1 to destroy.

Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.

Enter a value: yes

aws_instance.terraform_demo: Destroying... [id=i-0eec33286ea4b0740]
aws_instance.terraform_demo: Still destroying... [id=i-0eec33286ea4b0740, 10s elapsed]
aws_instance.terraform_demo: Still destroying... [id=i-0eec33286ea4b0740, 20s elapsed]
aws_instance.terraform_demo: Still destroying... [id=i-0eec33286ea4b0740, 30s elapsed]
aws_instance.terraform_demo: Destruction complete after 34s

Destroy complete! Resources: 1 destroyed.

Якщо ви знову перевірите панель керування EC2, то побачите, що екземпляр було завершено.

Висновок

Сподіваюся, що ця стаття допомогла вам зрозуміти, як почати працювати з Terraform. Спробуйте приклад, який ми розглянули.

Рекомендую дослідити цей інструмент для автоматизації інфраструктури.

Якщо вас цікавить більш глибоке вивчення Terraform, я рекомендую ознайомитись з навчальним курсом з DevOps та Terraform.