Выбрать главу

resource "aws_security_group" "instance" {

  name = "terraform-example-instance"

  ingress {

    from_port   = var.server_port

    to_port     = var.server_port

    protocol    = "tcp"

    cidr_blocks = ["0.0.0.0/0"]

  }

}

Хорошей идеей будет использование одной и той же переменной при задании порта в скрипте user_data. Указать ссылку внутри строкового литерала можно с помощью строковой интерполяции, которая имеет следующий синтаксис:

"${...}"

Внутри фигурных скобок можно разместить любую корректную ссылку, и Terra­form преобразует ее в строку. Например, вот как можно воспользоваться значением ­var.server_port внутри строки user_data:

user_data = <<-EOF

            #!/bin/bash

            echo "Hello, World" > index.html

            nohup busybox httpd -f -p ${var.server_port} &

            EOF

Помимо входных переменных, Terraform позволяет определять и выходные. Для этого предусмотрен такой синтаксис:

output "<NAME>" {

  value = <VALUE>

   [CONFIG ...]

}

NAME — это имя выходной переменной, а в качестве VALUE можно указать любое выражение Terraform, которое вы хотите вывести. CONFIG может иметь два дополнительных (и необязательных) параметра.

•description. Этот параметр всегда желательно применять для документирования того, как используется выходная переменная.

•sensitive. Если присвоить данному параметру true, Terraform не станет сохранять этот вывод в журнал после выполнения команды terraformapply. Это полезно, когда переменная содержит деликатный материал или конфиденциальные данные, такие как пароли или секретные ключи.

Например, вместо того, чтобы вручную бродить по консоли EC2 в поисках IP-адреса своего сервера, вы можете вывести его в виде выходной переменной:

output "public_ip" {

  value       = aws_instance.example.public_ip

  description = "The public IP address of the web server"

}

Здесь мы опять ссылаемся на атрибуты, на этот раз на атрибут public_ip ресурса aws_instance. Если снова выполнить команду apply, Terraform не внесет никаких изменений (поскольку вы не меняли никакие ресурсы), но покажет вам в самом конце новый вывод:

$ terraform apply

(...)

aws_security_group.instance: Refreshing state... [id=sg-078ccb4f9533d2c1a]

aws_instance.example: Refreshing state... [id=i-028cad2d4e6bddec6]

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

Outputs:

public_ip = 54.174.13.5

Как видите, после выполнения terraformapply выходная переменная выводится в консоли, что может пригодиться пользователям Terraform (например, вы будете знать, какой IP-адрес нужно проверить после развертывания веб-сервера). Вы также можете ввести команду terraformoutput, чтобы вывести список всех выходных значений без применения каких-либо изменений:

$ terraform output

public_ip = 54.174.13.5

Чтобы посмотреть значение определенной выходной переменной, можно воспользоваться командой terraformoutput<ИМЯ_ПЕРЕМЕННОЙ>:

$ terraform output public_ip

54.174.13.5

Это будет особенно полезно при написании скриптов. Например, вы можете создать скрипт развертывания, который развертывает веб-сервер с помощью команды terraformapply, берет его публичный IP-адрес из terraformoutputpublic_ip и обращается к этому адресу, используя curl. В итоге получится проверка по горячим следам, которая подтвердит, что развертывание работает.

Входные и выходные переменные также являются неотъемлемыми составляющими при создании конфигурируемого инфраструктурного кода, пригодного к повторному применению. Подробнее об этом — в главе 4.

Развертывание кластера веб-серверов

Запуск одного сервера — хорошее начало. Однако в реальном мире это означает наличие единой точки отказа. Если этот сервер выйдет из строя или перестанет справляться с нагрузкой из-за слишком большого объема трафика, пользователи не смогут открыть ваш сайт. В качестве решения можно запустить кластер серверов: если один из них откажет, запросы допускается перенаправить к другому серверу, а размер самого кластера можно увеличивать и уменьшать в зависимости от трафика32.

Ручное управление таким кластером потребует много усилий. К счастью, как показано на рис. 2.9, AWS может позаботиться об этом за вас, используя группу автомасштабирования (англ. auto scaling group, или ASG). ASG автоматически выполняет множество задач, включая запуск кластера серверов EC2, мониторинг работоспособности каждого сервера, замену неисправных серверов и изменение размера кластера в зависимости от нагрузки.

Рис. 2.9. Вместо одного веб-сервера группа автомасштабирования запускает кластер веб-серверов

Первое, что нужно сделать при создании ASG, — это написать конфигурацию запуска, которая определяет, как нужно настроить каждый сервер EC2 в вашей группе. Ресурс aws_launch_configuration использует почти все те же параметры, что и aws_instance (только у двух из них отличаются имена: image_id вместо ami и security_groups вместо vpc_security_group_ids), поэтому вы можете их легко заменить: