- webserver_cluster in ../../../modules/services/webserver-cluster
Initializing the backend...
Initializing provider plugins...
Terraform has been successfully initialized!
Теперь вы знаете обо всех хитростях в арсенале команды init. Она сама умеет загружать провайдеры и модули, а также конфигурировать ваши хранилища.
Прежде чем применять этот код, нужно упомянуть об одном недостатке модуля webserver-cluster: все имена в нем прописаны вручную. Это касается групп безопасности, ALB и других ресурсов. Таким образом, при попытке повторного использования этого модуля вы получите конфликты имен. Прямо в коде прописаны даже параметры для обращения к базе данных, поскольку файл main.tf, который вы скопировали в modules/services/webserver-cluster, берет адрес и порт БД из источника данных terraform_remote_state, а тот написан лишь с расчетом на тестовую среду.
Чтобы исправить эти проблемы, необходимо добавить в модуль webserver-cluster конфигурируемые входные параметры. Это позволит ему менять свое поведение в зависимости от окружения.
Входные параметры модуля
В языке программирования общего назначения, таком как Ruby, функцию можно сделать конфигурируемой, передав ей входные параметры:
def example_function(param1, param2)
puts "Hello, #{param1} #{param2}"
end
# Другие участки вашего кода
example_function("foo", "bar")
Модули Terraform тоже могут иметь параметры. Для их определения используется уже знакомый вам механизм: входные переменные. Откройте файл modules/services/webserver-cluster/variables.tf и добавьте три новых блока variable:
variable "cluster_name" {
description = "The name to use for all the cluster resources"
type = string
}
variable "db_remote_state_bucket" {
description = "The name of the S3 bucket for the database's remote state"
type = string
}
variable "db_remote_state_key" {
description = "The path for the database's remote state in S3"
type = string
}
Далее пройдитесь по файлу modules/services/webserver-cluster/main.tf и подставьте var.cluster_name прописанных вручную имен (скажем, "terraform-asgexample"). Например, вот как это сделать в группе безопасности ALB:
resource "aws_security_group" "alb" {
name = "${var.cluster_name}-alb"
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
Обратите внимание на то, что параметру name присваивается "${var.cluster_name}-alb". Аналогичные изменения нужно внести и в другой ресурс aws_security_group (можете назвать его "${var.cluster_name}-instance"), а также в aws_alb и раздел tag ресурса aws_autoscaling_group.
Вы также должны обновить источник данных terraform_remote_state, чтобы он использовал db_remote_state_bucket и db_remote_state_key в качестве параметров bucket и соответственно key. Это позволит ему считывать файл состояния из правильной среды:
data "terraform_remote_state" "db" {
backend = "s3"
config = {
bucket = var.db_remote_state_bucket
key = var.db_remote_state_key
region = "us-east-2"
}
}
Теперь можете аналогичным образом задать эти новые входные переменные в тестовой среде в файле stage/services/webserver-cluster/main.tf:
module "webserver_cluster" {
source = "../../../modules/services/webserver-cluster"
cluster_name = "webservers-stage"
db_remote_state_bucket = "(YOUR_BUCKET_NAME)"
db_remote_state_key = "stage/data-stores/mysql/terraform.tfstate"
}
То же самое нужно сделать для промышленной среды в файле prod/services/webserver-cluster/main.tf:
module "webserver_cluster" {
source = "../../../modules/services/webserver-cluster"
cluster_name = "webservers-prod"
db_remote_state_bucket = "(YOUR_BUCKET_NAME)"
db_remote_state_key = "prod/data-stores/mysql/terraform.tfstate"
}
Промышленная база данных еще не существует. В качестве упражнения попробуйте добавить ее самостоятельно по аналогии с тестовой.
Как видите, для установки входных переменных модуля и аргументов ресурса используется один и тот же синтаксис. Входящие переменные являются API модуля и определяют то, как он себя ведет в разных окружениях. В этом примере мы задаем разные имена для разных сред, но вы можете сделать конфигурируемыми и другие параметры. Предположим, чтобы сэкономить деньги, в тестовой среде можно запускать небольшой кластер веб-серверов, но в промышленных условиях вам понадобится большой кластер, способный справиться с сильными нагрузками. Для этого в файл modules/services/webserver-cluster/variables.tf можно добавить еще три входные переменные:
variable "instance_type" {
description = "The type of EC2 Instances to run (e.g. t2.micro)"
type = string
}
variable "min_size" {
description = "The minimum number of EC2 Instances in the ASG"
type = number
}
variable "max_size" {
description = "The maximum number of EC2 Instances in the ASG"
type = number
}
Дальше нужно обновить конфигурацию запуска в файле modules/services/webserver-cluster/main.tf, присвоив параметру instance_type новую входную переменную var.instance_type: