Pull to refresh

Comments 5

Спасибо за добротный разбор.

Я видел еще пару интересных концепций:

  • Использование дефолтного объекта. Например, параметры ami, instance_type, create_before_destroy и tag можно собрать в одну переменную default_instance. Теперь мы все эти параметры можем как переопределять, так и вовсе не указывать (хотя для читаемости параметр instance_type можно и оставить). Однако это может нарушать принципы, изложенные в п.1.11 статьи.

Hidden text
variable "instances" {
  description = "Instances with parameters"
  type = map(object({
#    instance_type = string
    instance_name = string
    idx           = number
  }))
}

variable "default_instance" {
  description = "Default Instance parameters"
  type = object({
    instance_type = string
    ami = string
    create_before_destroy = bool
    tags = map(string)
  })
}

# default_instance = {
#   instance_type = "t2.micro"
#   ami = "ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"
#   create_before_destroy = true
#   tags = { lb = "nlb" }
# }
# instances = {
#   instance1 = { instance_name = "instance-1", idx = 0 }
#   instance2 = { instance_name = "instance-2", idx = 1 }
# }

locals {
instances = { for k, v in var.instances: k => merge(var.default_instance, v) }
}

resource "aws_instance" "instance" {
  for_each             = local.instances
  ami                  = data.aws_ami.ubuntu.id
  instance_type        = each.value.instance_type
  subnet_id            = data.aws_subnets.subnets.ids[each.value.idx]
  iam_instance_profile = aws_iam_instance_profile.instance_profile.name
  lifecycle {
    create_before_destroy = each.value.create_before_destroy
  }
  tags = merge(each.value.tags, { Name = each.value.instance_name })
}

  • Использование yaml файлов для задания переменных. Если требуется использовать один конфиг для нескольких инструментов (например, для terraform и ansible или helm), то вместо *.auto.tfvars может подойти более универсальный формат. Код terraform при этом не сильно усложняется

Hidden text
default_instance:
  instance_type: t2.micro
  ami: "ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"
  create_before_destroy: true
  tags:
    lb: nlb

instances:
  instance1: 
    instance_name: instance-1
    idx: 0
  instance2: 
    instance_name: instance-2 
    idx: 1

# variable "config_path" {
#   description = "Path to yaml config"
#   path = string
# }

# locals {
#   config = yamldecode(file(${var.config_path}"))
#   instances = local.config.instances
# }

1.3. Использование нижнего подчеркивания "_" вместо тире "-" в наименовании module, resource, data source, variable, output, etc.

К сожалению, этот пункт никак не прокомментирован. Зачем всё же у объекта и управляющего им ресурса делать разные имена, ещё и сильно похожие? :)

Спасибо за бестррактис. Неплохо бы дополнить это репом с пуликом на рефакторинг для наглядности

Все вышеперечисленные аргументы не относятся только к преимуществам Terraform, скорее больше в целом к преимуществам IaC. Да и у Terraform существуют аналоги, например, Pulumi, CloudFormation для AWS. Поэтому, если вы используете любой другой аналог Terraform, который поддерживает концепцию IaC, это уже хорошо, и однозначно лучше, чем "натыкивать" инфраструктуру руками.

Между Terraform и Pulumi есть кардинальное концептуальное отличие. Terraform - это декларативная портянка, в которой придется на еще одном декларативном синтаксисе описывать километровые конфигурационные файлы. Это тоже самое, что CloudFormation Template в AWS.

Pulumi (и родной AWS CDK) - это модель описания инфраструктуры реальным кодом (обычно с поддержкой нескольких ЯП), где портянка из п.1 авто-генерируется на основе написанного кода.

Любой, кто работал с CFN Templates на реальной инфраструктуре, больше к декларативному подходу возвращаться не захочет.

Мы в компании давно выбрали CDK и ни разу не пожалели. Рекомендую всем изучить этот вопрос, и четко ответить на вопрос - нужен ли вам Тераформ.

Кстати HashiCorp осознали фатальный недостаток декларативных портянок и тоже делают https://github.com/hashicorp/terraform-cdk. Можно его тоже рассмотреть.

Так-то да, нативные языки лучше. Но надо учитывать такую вещь, как "отраслевой стандарт". Если вы готовы на несколько месяцев дольше искать человека в случае необходимости замены или расширения команды - то никаких проблем. Job security разными методами достигается.

Sign up to leave a comment.

Articles