Рубрики
Uncategorized

Введение в Terraform

Благодаря масштабному внедрению «облака», различные инструменты даются для упрощения Dev / SYS. администратор … Помечено терраформ, IAC, DevOps, AWS.

Благодаря масштабному внедрению «облака», различные инструменты даются для упрощения Dev/SYS. Административные жизни. Эти инструменты создали новый способ борьбы с инфраструктурой, инфраструктурой как кода IAC. Честно говоря, облако — хорошее слово, но давайте посмотрим правде в глаза, вы просто запускаете виртуальные машины на кого -то другом серверах. Большой плюс для использования — это то, что с помощью простого вызова API вы можете предоставить, предоставить и уничтожить инфраструктуру на своем взгляде. Было бы здорово написать несколько сценариев для автоматической заполнения ваших VPC на AWS, но также призывая Azure, чтобы предоставить некоторое хранилище и т. Д. Ну, в конце концов, вы можете заболеть. Почему бы не создать инструмент, который будет иметь дело со всеми призывами API для вас? Ну, это то, что такое Terraform, и давайте посмотрим, как мы можем использовать этот удивительный инструмент.

Отказ от ответственности: этот урок будет использовать AWS в качестве облачного провайдера. Любая копейка, которую вы потратите на платформу, находится на всей вашей ответственности, и вы знаете, что прочитаете эту статью, которую вам придется потратить, если вы не имеете права на получение AWS Free Leier

Начало детских шагов

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

Прежде всего, давайте установим Terraform

Монтаж

  • Mac: Вареть установить Terraform
  • Ubuntu: sudo apt-get установить терраформ
  • Windows: Загрузите двоичный файл на странице загрузки Terraform и добавьте его на свой путь.

Настройка учетной записи AWS

Вам нужно пойти в консоли AWS и настроить конкретного пользователя для использования Terraform. Перейти в Iam Панель и создайте пользователя. my_terraform

Первый проект

Давайте создадим main.tf. Если вы имеете право на получение бесплатного уровня AWS, не стесняйтесь использовать это, если нет, вам нужно вывести немного денег (извините). Вам также нужен пользователь IAM, чтобы получить ключ доступа и секретный ключ.

Мы начнем с нуля, так что:

mkdir terraform_lab
cd terraform_lab
git init
git remote add origin git://my_git_repo.git
provider "aws" {
    access_key = "your_access_key"
    secret_key = "your_secret_key"
    region = "eu-west-1" # You can change the region for the one your prefer
}

# Nice copy pasta from the doc (https://www.terraform.io/docs/providers/aws/r/instance.html)
data "aws_ami" "ubuntu" {
  most_recent = true

  filter {
    name = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-trusty-14.04-amd64-server-*"]
  }

  filter {
    name = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["099720109477"] # Canonical
}

resource "aws_vpc" "default" {
    cidr_block = "172.16.0.0/16"
}

resource "aws_internet_gateway" "default"{
    vpc_id = "${aws_vpc.default.id}"
}

resource "aws_subnet" "default" {
    vpc_id = "${aws_vpc.default.id}"
    cidr_block = "172.16.0.0/16" # Just one big subnet covering the whole VPC. Of course do not use that in production.
}

resource "aws_security_group" "open_bar" {
    name = "open_bar"
    description = "Allow all connections inbound and outbound"
    vpc_id = "${aws_vpc.default.id}"
    ingress {
        from_port = "0"
        to_port = "0"
        protocol = "-1"
        cidr_blocks = ["0.0.0.0/0"]
    }
    egress {
        from_port = "0"
        to_port = "0"
        protocol = "-1"
        cidr_blocks = ["0.0.0.0/0"]
    }
}

resource "aws_instance" "simple_instance" {
    ami = "${data.aws_ami.ubuntu.id}"
    instance_type = "t2.micro"
    subnet_id = "${aws_subnet.default.id}"
}

Вы видите прямо, какие компоненты вы создаете с помощью Terraform, по сравнению со сценарием Bash, полным кудрей, это более ясно, верно?

Теперь давайте посмотрим, как использовать этот файл, и разбил его.

Планирование

Прежде чем делать что -то прискорбно, давайте посмотрим, что сделает Terraform. Для этого:

Терраформский план

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

Я советую вам сохранить каждый план, который вы делаете, прежде чем применять его. При таком способе, вы уверены, что будет применен тот план, который будет применен, и ничего более/меньше.

Для этого просто укажите имя файла/путь, по которому вы хотите сохранить свой план.

План Terraform -out ./my AWS план

Затем, будучи довольным тем, что будет делать план, давайте применим его.

Terraform Apply ./my_aws_plans

И если вы пойдете в консоли, вы увидите, что у вас есть совершенно новый VPC, подсеть и экземпляр.

Давайте уничтожим все это время, когда я объясню вам, что мы только что написали в этом файле Main.tf.

Для этого: Terraform Drouss Анкет

И Тада, ты возвращаешься в свое первоначальное состояние, очень легко, не так ли?

Что сейчас произошло?

Терраформский план

Планирование в Terraform — лучший способ проверить, контролировать и контролировать, что сделает Terraform. Каждый раз, когда вы хотите проверить свой проект Terraform -> Plan, вы увидите синтаксис/логические ошибки. Планирование не мешает вопросам поставщика, хотя. Например, вы создаете подсеть с диапазоном, таким как 172.0.0. 132 (Это всего лишь пример), и вы определяете экземпляр EC2 внутри подсети с частным IP, таким как 192.168.1.1, Terraform получит ошибку только после того, как вы примените свое изменение, так как AWS вернет ошибку, когда Terraform сделает вызов API Анкет

Итак, в нашей первой попытке план Terraform создал только материал, что нормально, как мы начинали с нуля, но как Terraform будет знать, как изменить инфраю с предыдущего пробега? Если вы посмотрите в папке проекта, у вас есть файл terraform.tfstate. Это то, что использует Terraform, чтобы знать состояние компонентов, которые вы определили в своем main.tf в облаке.

Когда вы выполняете план, если существует этот файл terraform.tfstate, Terraform выведет фактическую конфигурацию инфраструктуры, обновите свой файл TFState и сравните то, что находится в TFState, и что вы определили в Main.tf, и подскажет вам, что изменится, когда вы запустите Применить.

Терраформ применяется

Это действие на самом деле будет выполнять вызовы API к вашему облачному провайдеру, если не указан Plan_file Terraform обновит файл состояния до Применить и будет обновлять после. Вот почему вам лучше использовать план постоянно в случае изменения вашей архитектуры между вашим планом и вашим применением.

Синтаксис Terraform

Синтаксис Terraform является общим синтаксисом, если вы раньше использовали другие инструменты Hashicorps. Они используют созданный формат. (Хорошо, сейчас я не могу найти ничего еще, у тебя есть момент).

В Terraform у вас в основном два вида определения:

  • terraform_keyword имя
  • terraform_keyword component_type component_id

Для первого синтаксиса может быть:

  • Поставщик: предоставит аутентификацию для облачного провайдера
  • Переменная: Создайте переменную для объема вашей терраформы подать заявление
  • Конфигурация: используется для настройки Terraform, полезно для конфигурации бэкэндов (мы увидим это позже)

Все вещи, определенные с Terraform в вашем облачном провайдере, будут иметь одинаковую структуру {...}

Ключевое слово Terraform может варьироваться между:

  • Ресурс: Создайте новый компонент в облаке, используя поставщик настроен
  • Данные: получить информацию о существующем компоненте

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

И чтобы закончить component_id, может быть все, что вам нравится, время, когда вы понимаете, что это такое. Он используется Terraform для определения различных созданных компонентов. Например, если бы мы определили бы два разных вида AWS_INSTANCE, было бы здорово использовать 2 разных компонента_ида, таких как «Front_end» или «Back_end» и т. Д.

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

Раздел поставщика

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

Конечно, вы можете использовать несколько поставщиков на случай, если вы напишите свои файлы Terraform для Azure, AWS, VMware и т. Д.

Ресурсы разделы

Здесь вы определяете все компоненты, которые хотите Создать в облаке. Они конкретно поставщика, и после того, как они созданы, вы можете получить доступ к различным переменным, которые вам предоставит этот ressource. Например, создавая экземпляр EC2, мы повторно используем идентификатор подсету, которые мы создали ранее.

Еще раз, все подробно для каждого ресурса в документации Terraform.

Интерполяция

Если вы прочитали то, что я написал чуть выше в разделе «Ресурсы», вы поняли, что варварский синтаксис, используемый для определения подсети наших AWS_INSTANCE, является переменным значением. В Terraform вы можете использовать строки с \ $ {}, чтобы дать некоторую логику для определения атрибутов. Вы можете повторно использовать идентификаторы компонентов, которые вы создали (как мы это делали), вы даже можете использовать петли, условия, карты и даже некоторую математическую функцию.

Рафис нашего проекта

Со временем ваш проект может стать больше, чем Я имею в виду, что ваш файл main.tf может содержать тысячи строк, что затрудняет поддержание. Давайте начнем с интуитивно понятного подхода: сократите наш файл main.tf на части.

Руть Main.tf

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

Давайте сначала поместим поставщика в другой файл. Давайте создадим поставщики.tf Файл в текущей папке, содержащей только наши авторитетные кредиты AWS.

# providers.tf

provider "aws" {
    access_key = "your_access_key"
    secret_key = "your_secret_key"
    region = "eu-west-1"
}

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

Давайте проверим это!

Терраформ применяется

Хорошо, вы не читаете всю статью. Я сказал, чтобы проверить, мы используем План не применить Анкет Ну, в любом случае, если вы попали в ловушку, это ничего не должно было изменить.

Давайте продолжим с нашей конфигурацией сети. Давайте поместим VPC, шлюз в него.

# vpc.tf

resource "aws_vpc" "default" {
    cidr_block = "172.16.0.0/16"
}

resource "aws_internet_gateway" "default"{
    vpc_id = "${aws_vpc.default.id}"
}

Давайте сделаем то же самое с подсети, безопасностью_ группировки и экземпляры

# subnets.tf

resource "aws_subnet" "default" {
    vpc_id = "${aws_vpc.default.id}"
    cidr_block = "172.16.0.0/16" # Just one big subnet covering the whole VPC. Of course do not use that in production.
}
# security_groups.tf

resource "aws_security_group" "open_bar" {
    name = "open_bar"
    description = "Allow all connections inbound and outbound"
    vpc_id = "${aws_vpc.default.id}"
    ingress {
        from_port = "0"
        to_port = "0"
        protocol = "-1"
        cidr_blocks = ["0.0.0.0/0"]
    }
    egress {
        from_port = "0"
        to_port = "0"
        protocol = "-1"
        cidr_blocks = ["0.0.0.0/0"]
    }
}
# instances.tf

# Yeah I put the ami with instances. No need elsewhere.
data "aws_ami" "ubuntu" {
  most_recent = true

  filter {
    name = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-trusty-14.04-amd64-server-*"]
  }

  filter {
    name = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["099720109477"] # Canonical
}

resource "aws_instance" "simple_instance" {
    ami = "${data.aws_ami.ubuntu.id}"
    instance_type = "t2.micro"
    subnet_id = "${aws_subnet.default.id}"
}

В конце рефакторинга вы получите более приятную структуру. Эта структура будет длиться несколько раз, пока вы не начнете увеличиваться. Со временем вы увидите некоторый предел, как в случае сложных зависимостей или даже о SOC (разделение проблем)

Итак, здесь приходят модули.

Модули

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

Архитектура

Для начала с модулей вам нужно создать папку модулей в корне вашего проекта и создать папку с именем модуля, который вы хотите создать. Внутри последней папки вам просто нужно создать три файла, и вы создали свой первый модуль! Эти файлы:

  • variables.tf: Этот файл содержит все переменные, которые вы хотели бы параметризировать ваш модуль. Например, вы пройдете немного VPC_ID или амиса.

  • main.tf: Как и наш первый main.tf, он содержит все определение ресурса вашего модуля.

  • outputs.tf: содержит все переменные, которые вам понадобятся после выполнения модулей. Наиболее распространенное использование — выход Общественные IPS будущего создали экземпляры.

Используй это

В нашем примере инфра довольно проста, поэтому этот модуль будет также. Мы просто поместим нашу Simple_instance в модуль. Но в некотором смысле, как мы можем настроить на какую подсеть, какой это будет AZ.

Давайте начнем создавать модуль.

mkdir -p modules/my\_cluster\_of\_instances touch modules/my\_cluster\_of\_instances/{main,variables,output}.tf

Давайте поместим наше определение «simple_instance» в main.tf

# main.tf

resource "aws_instance" "simple_instance" {
    ami = "${var.ami_id}"
    instance_type = "${var.instance_type}"
    subnet_id = "${var.subnet_ids}"
    count = "${cluster_size}"
}

Если вы видели, я изменил переменную на что -то определено из файла variable.tf. Я добавил атрибут графа на случай, если мы хотим расширить этот модуль

Теперь давайте настроим переменные:

# variables.tf

variable "subnet_ids" {
    description = "The list of subnet id"
}

variable "cluster_size" {
    description "The number of instance you want"
    default = 1
}

variable "instance_type" {
    description = "The type of instance you want"
    default = "t2.micro"
}

variable "ami_id" {
    description = "The AMI to use on these instances"
}

# output.tf

output "private_ips" {
    value = ["${aws_instance.simple_instance.*.private_ip}"]
}

Последний использует подстановку, так как мы не знаем, сколько экземпляров будет создано в модуле. Это означает » Вывод Список случаев частных IPS «

Итак, теперь давайте создадим main.tf в корне нашего проекта, который называет этот модуль:

# main.tf

# Everything we had a bit earlier ... (vpcs, subnets until the instance resource)

module "awesome_instance" {
    module_path = "modules/my_cluster_of_instances"
    ami_id = "${data.aws_ami.ubuntu.id}"
    subnet_id = "${aws_subnet.default.id}"
    instance_type = "t2.micro" # No need of this line as there's a default value
    cluster_size = 2 # Here we override the default value
}

aws_security_group_rule "a_simple_sg_rule" {
    security_group_id = "${}"
    type = "ingress"
    from = 0
    to_port = 0
    protocol = -1
    cidr_block = ["${module.awesome_instance.private_ips}"] # Using here the output of our module
}

В командной строке:

terraform get # Will create reference to our module
terraform plan # Should destroy what we had before

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

Заключение о структуре проекта

До сих пор структура модуля — лучшая, которую я встретил в данный момент. Обычно я поставляется с несколькими папками в корне своих проектов:

  1. модули/
  2. env1/
  3. env2/

И использование ENVX в качестве правильной отделения между окружающей средой. Это действительно удобно, когда у вас есть много различий между окружающей средой.

Другие команды с Terraform

Чтобы закончить это супер длинный Статья, я кратко расскажу о команде, которую мы не видели в статье.

Арестовать

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

Из примера нашего модуля мы бы использовали его так:

Terraform Taint Extance.0

Таким образом, вам нужно указать, к какому модулю вы портите ресурс. И после этого resource_name.which_one.

Предупреждение : Там нет поддержки для подстановочного знака в соответствии с Эта проблема GitHub

График

Если в вашем ноутбуке установлен Graphviz, вы можете создать график ресурсов Terraform, которые вы определяете.

импорт

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

Например, если мы создали экземпляр EC2 в пользовательском интерфейсе. Мы бы добавили это так в файле TFState.

terraform import aws\_instance.my\_instance the\_id\_of\_the\_instance

Вывод

О Terraform еще многое можно сказать Но я остановлюсь здесь, когда достиг почти 2500 слов … мы видели, что Terraform — отличный инструмент для управления инфраструктурой с кодом. Их формат .tf — это действительно хорошая вещь по сравнению с простым определением JSON. И Terraform довольно разрешительна, поэтому вы можете начать с простого проекта и закончить с сотнями модулей, которые называют друг друга, делая применение инструмента довольно простым. В любом случае я оставляю вас наслаждаться Терраформ уничтожает

Sur ce, Codez Bien! Чао!

Оригинал: «https://dev.to/juan__wolf/introduction-to-terraform-21cj»