Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Terraform DevOps: Управление инфраструктурой

Ниже приведён пример подготовки инфраструктуры с помощью Terraform

Пример файла terraform/main.tf

// Для удобства всё находится в одном файле
// При необходимости разделяется на отдельные .tf файлы

// https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs
terraform {
  required_providers {
    digitalocean = {
      source = "digitalocean/digitalocean"
      version = "1.22.2"
    }
  }
}

provider "digitalocean" {
  // Использование переменной (токен доступа к DO)
  // https://www.terraform.io/docs/language/values/variables.html
  token = var.do_token
}

// Токен DO и путь к приватному ключу, будут передаваться через CLI
variable "do_token" {}

// Ключ можно либо получить созданный, либо создать новый
// resource "digitalocean_ssh_key" "default" {
//   name       = "Terraform Homework"
//   public_key = file("~/.ssh/id_rsa.pub")
// }
// Используется data source - ресурс не создаётся. Terraform запрашивает информацию о ресурсе
// https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs/data-sources/droplet
data "digitalocean_ssh_key" "example" {
  // Имя под которым ключ сохранён в DO
  // https://cloud.digitalocean.com/account/security
  name = "key"
}

// Создаём дроплет
// https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs/resources/droplet
resource "digitalocean_droplet" "web1" {
  image  = "ubuntu-18-04-x64"
  name   = "web-1"
  region = "nyc1"
  size   = "s-1vcpu-1gb"

  // Добавление приватного ключа на создаваемый сервер
  // Обращение к datasource выполняется через data.
  ssh_keys = [
    data.digitalocean_ssh_key.example.id
  ]
}

resource "digitalocean_droplet" "web2" {
  image  = "ubuntu-18-04-x64"
  name   = "web-1"
  region = "nyc1"
  size   = "s-1vcpu-1gb"

  // Добавление приватного ключа на создаваемый сервер
  ssh_keys = [
    data.digitalocean_ssh_key.example.id
  ]
}

// Создание балансировщика нагрузки
// https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs/resources/loadbalancer
resource "digitalocean_loadbalancer" "example" {
  name = "example"
  region = "nyc1"

  forwarding_rule {
    // Порт по которому балансировщик принимает запросы
    entry_port = 80
    entry_protocol = "http"

    // Порт по которому балансировщик передает запросы (на другие сервера)
    target_port = 8080
    target_protocol = "http"
  }

  // Порт, протокол, путь по которому балансировщик проверяет, что дроплет живой и принимает запросы
  healthcheck {
    port = 8080
    protocol = "http"
    path = "/"
  }

  droplet_ids = [
    digitalocean_droplet.web1.id,
    digitalocean_droplet.web2.id
  ]
}

// Создание домена
// https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs/resources/domain
resource "digitalocean_domain" "example" {
  name = "hexlet.devops-baby.club"
  ip_address = digitalocean_loadbalancer.example.ip
}

// Outputs похожи на возвращаемые значения. Они позволяют сгруппировать информацию или распечатать то, что нам необходимо
// https://www.terraform.io/docs/language/values/outputs.html
output "droplets_ips" {
  // Обращение к ресурсу. Каждый ресурс имеет атрибуты, ккоторым можно получить доступ
  value = [
    digitalocean_droplet.web1.ipv4_address,
    digitalocean_droplet.web2.ipv4_address
  ]
}

Пример файла terraform/.terraform.lock.hcl

# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.

provider "registry.terraform.io/digitalocean/digitalocean" {
  version     = "1.22.2"
  constraints = "1.22.2"
  hashes = [
    "h1:VNz0Gte3Rmd/yhUh96FuStEXJWRYx8x2LMolm54U7Rw=",
    "zh:406d8f4704f7ff17a5b60c394674e4e85910c86a0090c9f4bb4b33196e132d2b",
    "zh:476d9600a13e1d425540c3750a6966d5867ea5d6d5dbfa2d8c8dc6a6ea07b1ac",
    "zh:56f56d312ec707e9f33db833876a5086af4f07043eb0c471e002b42339a31bf5",
    "zh:669cf9c9dd7e9c812e8896fae34a22cdc938854f6d91778ad74a12083744f4ae",
    "zh:714ed181254a95f774de372fac3afdf6ae9658f18b5fe13324df31cb12892f76",
    "zh:7762077125a6df36b28cdd4966356d2a7fddb187d010d06aca05a8ecf7ce1612",
    "zh:877cb27bf81c56c2e863d9574e34716e1eb49bcb0de0a48578c828bef1863d87",
    "zh:92049f21072b76fe5bb9a49842d820eda3ca86098e01bd936ef031b44f0d0207",
    "zh:b4fec336c0fa22fd2a053cf3c6a9a4b8622557c18aba622127c86d0f14a1bf52",
    "zh:d4df235797896ba7efb16ace5a8f5e27e5751b7bddc102a4f2617d80f71c0cb2",
    "zh:ea5ca95527064e3740183f997aecd6e39313bd63d155447d338e2aa7818209b6",
  ]
}

Пример файла .gitignore

.terraform

Пример файла ansible/playbook.yml

---
# плейбук состоит из списка плеев объектов в которых описаны хосты, задачи и тд
# https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html
- hosts: all # Хосты для которых выполняется ansible
  gather_facts: yes

  tasks:
    - name: Install packages
      apt:
        name: python3-pip
        update_cache: yes

    - name: Install Docker Module for Python
      pip:
        name: docker

    - name: Run container
      # Используем модуль community.docker.docker_container
      # Для совместимости важно указывать полное имя модуля
      community.docker.docker_container:
        name: devops-example
        image: hexlet/hexlet-example # Имя используемого образа
        # Публикуемые порты. Слева порт внутри контейнера,
        # справа порт по которому он будет доступен снаружи
        published_ports: 80:8080
        restart_policy: always
        restart: yes
        container_default_behavior: no_defaults
        pull: yes
        # Задаём переменные окружения внутри контейнера
        env:
          SERVER_MESSAGE: "{{ server_message }}"

Пример файла ansible/requirements.yml

roles: []

# Определяем коллекцию
# https://galaxy.ansible.com/community/docker
collections:
  - name: community.docker

Пример файла ansible/hosts

; определяем один хост в группе webservers
; указываем алиас, IP-адрес хоста, пользователя для подключения
[webservers]
web1 ansible_host=168.100.41.220 ansible_user=root
web2 ansible_host=189.166.122.250 ansible_user=root

Примеры команд

# Инициализация проекта терраформ
# может добавляться флаг -chdir=<dirname> если нужно команда выполняется не в директории с tf файлами
terraform init

# В примерах ниже используется переменная окружения для токена Digital Ocean
export DO_PAT=<token>

# Посмотреть изменения без их выполнения
# https://www.terraform.io/docs/cli/commands/plan.html
terraform plan -var "do_token=$DO_PAT"

# Применить изменения
# https://www.terraform.io/docs/cli/commands/apply.html
terraform apply -var "do_token=$DO_PAT"

# Удалить созданную инфраструктуру
# https://www.terraform.io/docs/cli/commands/destroy.html
terraform destroy -var "do_token=$DO_PAT"

# После применения изменений сохраняется состояние инфраструктуры. Её можно посмотреть
terraform show

# Форматирование
# https://www.terraform.io/docs/cli/commands/fmt.html
terraform fmt

# Проверка стиля (формата) с выводом диффа
terraform fmt -check -diff

# Проверка конфигурации
# https://www.terraform.io/docs/cli/commands/validate.html
terraform validate

Домашнее задание

hexlet program download devops-for-programmers terraform

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.

Об обучении на Хекслете

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
900
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

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

  • 130 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Изображение Тото

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