Опубликован: 18.04.2021 | Доступ: свободный | Студентов: 875 / 418 | Длительность: 04:36:00
Лекция 5:

Infrastructure as a Code

< Лекция 4 || Лекция 5 || Лекция 6 >

Исторически сложилось что всю инфраструктуру конфигурировали вручную, потому что это были физические устройства.

Вам нужен новый сервер? - Купите новый физический сервер, подождите доставку, сконфигурируйте, настройте, вставьте в серверную стойку и подключите к сети.

Вам нужно больше клиентских устройств в сети? - Купите новый коммутатор, подождите доставку, настройте под ваши сети, вставьте в стойку и подключите устройства.

У вас вышел из строя жёсткий диск в файловом хранилище? - Купите новый жёсткий диск, подождите доставки, подойдите к стойке, достаньте вышедший из строя и вставьте новый.

Нужно дополнительное дисковое пространство? - Сделайте примерно тоже самое, только возможно ещё и настроите файловое хранилище с нуля.

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

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

Поскольку ручной подход не мог гарантировать одинаковости окружений, а также занимал чудовищное количество времени, родилась парадигма разработки Infrastructure as a Code.

Infrastructure as a Code (IaC) - подход в описании и конфигурировании инфраструктуры, когда компоненты инфраструктуры описываются при помощи кода, а не настраиваются вручную. Подход к описанию может быть как декларативный, так и итеративный, однако декларативный используется намного чаще.

Императивный подход - программа, выполни вот эти действия. Программа выполнит указанное вне зависимости от предыдущих действий и состояния компонент инфраструктуры в текущий момент.

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

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

Какие главные преимущества даёт подход Infrastructure as Code?

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

Для примера давайте рассмотрим один из популярнейших инструментов - terraform.

Terraform - программное обеспечение с открытым исходным кодом, которое предназначено для управления конфигурациями инфраструктуры реализующими парадигму Infrastructure as Code. Для конфигурационных файлов использует язык Hashicorp Configuration Language (HCL), опционально можно использовать JSON.

Основные понятия Terraform

provider - внутренний интерфейс представляющий собой некоторого провайдера сервиса. Может быть как удалённым, так и локальным.

state и statefile. State - текущее состояние инфраструктуры. Statefile - файл который содержит state.

backend - блок кода который определяет способ хранения состояния инфраструктуры (state).

resource - блок кода определяющий ресурс предоставляемый провайдером.

data source (data) - блок кода который позволяет получить информацию о существующем ресурсе в системе провайдера.

variable - переменная которая может быть задана в процессе исполнения процесса конфигурации.

locals - локальные динамические или статические значения к которым можно обращаться из кода.

output - блок кода определяющий значение которое будет передано в вывод программы после исполнения конфигурации.

module - некоторый набор кода который обособлен в отдельный модуль и может быть вызван в других конфигурациях.

Основные команды

terraform init - инициализация локального проекта, включает в себя подключение к определенному в коде backend'у или инициализация statefile с нуля, загрузка требуемых плагинов и провайдеров.

terraform plan - на основе изменений в коде создает предполагаемый план изменений для инфраструктуры на основе текущего состояния из statefile.

terraform apply - применяет ранее созданный план к существующей инфраструктуре.

terraform destroy - удаляет все указанные в statefile компоненты инфраструктуры.

Примеры работы с кодом terraform

Примеры представлены с помощью null провайдера, или пустышки. Этот провайдер применяется для тестов, а также для условного ресурса в цикле, который используется для взаимодействия с другими ресурсами.

Объявление провайдера:

provider "null" {}

Объявление локальных переменных

locals {
  sample_local = "local value! "
}

Блок ресурса

resource "null_resource" "example" {}

Итерирование создания ресурса с целью избежать повторяемости кода

resource "null_resource" "example" {
  count = 5
}

Блок получаемых данных

data "null_data_source" "example" {
  inputs = {
	sample_value = "Here is a sample value from variable: ${var.sample_input}!"
	sample_local = "Here is a sample value from locals ${local.sample_local}!"
  }
}

Блок переменной вводимой в процессе применения изменений

variable "sample_input" {
  type = string
  sensitive = true
}

Пример блока вывода результата

output "sample_var_output" {
  value = data.null_data_source.example.outputs["sample_value"]
}

Пример работы с модулями

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "2.77.0"
}

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

Работа с модулем расположенным в локальной директории проекта

module "vpc" {
  source  = "./module_folder/module_name"
}

Работа с модулем находящемся в git репозитории

module "vpc" {
  source  = "git@github.com:user_name/user_repo.git?ref=v1.0.0"
}

В случае с git репозиторием версионирование указывается через тэги в формате git/

Основная документация используемая при написании Infrastructure as Code с помощью terraform:

  1. Архитектурная документация инфраструктуры
  2. Документация провайдера terraform с описанием имеющихся ресурсов и источников данных
  3. Документация модулей, если они используются в проекте

Создадим пример инфраструктуры в облаке AWS

Инфраструктура включает в себя:

  • VPC в AWS со сконфигурированным NAT gateway
  • 6 приватных и публичных подсетей в AWS VPC
  • 5 ec2 инстансов, присутствующих в приватных подсетях

Пример кода:

# провайдер определяющий работу с aws в регионе eu-west-1
provider "aws" {
  region = "eu-west-1"
}

# локальные значения определяющие адресацию виртуального сегмента сети и подсетей
locals {
  cidr_block      = "10.0.0.0/16"
  private_subnets = ["10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24"]
  public_subnets  = ["10.0.3.0/24", "10.0.4.0/24", "10.0.5.0/24"]
}

# переменная через которую можно указать образ из которого будут запущены инстансы
variable "instance_ami" {
  type        = string
}

# переменная определяющая тип инстансов
variable "instance_type" {
  type        = string
}

# переменная определяющая количество инстансов и имеющая стандартное значение
variable "instance_count" {
  type        = number
  default    = 5
}

# ресурс типа data, возвращающий список доступных зон доступности
data "aws_availability_zones" "available" {
  state = "available"
}

# используя модуль, определение VPC и подсетей
# как источник используется terraform registry (официальный репозиторий инструмента terraform)
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "2.77.0"

  cidr               = local.cidr_block
  azs                = data.aws_availability_zones.available
  private_subnets    = local.private_subnets
  public_subnets     = local.public_subnets
  enable_nat_gateway = true
  enable_vpn_gateway = false
}

# используя модуль, определение 5 инстансов 
module "ec2_instances" {
  source                 = "terraform-aws-modules/ec2-instance/aws"
  version                = "~> 2.0"

  name                   = "instances"
  instance_count    = var.instance_count

  ami                    = var.instance_ami
  instance_type    = var.instance_type
  subnet_ids         = local.private_subnets

  tags = {
    Terraform   = "true"
  }
}

Выводы

Infrastructure as Code - одна из основных парадигм использующихся в данный момент при разработке простых и сложных платформ на уровне инфраструктуры. Данная парадигма даёт высокую гибкость в изменении кода и отслеживании этих изменений в будущем для аудита. Экономию времени путём переиспользования кода и унификации окружений. Уверенность в том, что одно окружение будет максимально приближено к другому и тесты будут релевантными. Плюс программная реализация управления инфраструктурой даёт широкие возможности по автоматизации задач развертывания окружений и доставки изменений.

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

< Лекция 4 || Лекция 5 || Лекция 6 >
Рустам Тагаев
Рустам Тагаев

Очень много ошибок в тестах. Другие люди их тоже нашли. Но прошло очень много времени и похоже что ошибки не собираются исправлять. Очень обидно что на такой большой платформе такая медленная реакция.