使用Terraform创建“随机”实例-自动创建有效的配置

时间:2020-08-23 20:28:59

标签: terraform

我是Terraform的新手,喜欢创建“随机”实例。 操作系统,设置脚本等某些设置将保持不变。通常,区域/区域会发生变化。

我该怎么做? Terraform似乎已经知道哪些组合有效。例如,对于AWS EC2或lightail,如果选择错误的组合,它将发出抱怨。我想这会减少工作量。我想知道这是否对每个提供商都有效。

如何在每次Terraform运行时仅更改区域或区域的情况下自动创建有效的配置?

编辑:配置如下:

    terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
    }
  }
}

provider "aws" {
#  profile    = "default"
#  region     = "us-west-2"
   accesskey = ...
   secretkey = ...
}

resource "aws_instance" "example" {
  ami           = "ami-830c94e3"
  instance_type = "t2.micro"
}

2 个答案:

答案 0 :(得分:1)

以AWS为例,aws_instance具有两个必需参数:amiinstance_type

因此,要创建一个实例,您需要同时提供它们:

resource "aws_instance" "my" {
  ami           = "ami-02354e95b39ca8dec"
  instance_type = "t2.micro"
}

所有其他内容都将推论或设置为默认值。在可用性区域和子网方面,如果未明确指定,则将“随机”选择它们(AWS决定如何放置它们,因此,如果它们可以全部位于一个可用区中,则为)。

因此,要在不同的子网和可用区中创建3个实例,您只需执行以下操作:

provider "aws" {
  region     = "us-east-1"
}


data "aws_ami" "al2_ami" {

    most_recent = true

    owners = ["amazon"]

   filter {
     name   = "name"
     values = ["amzn2-ami-hvm*"]
   }
}

resource "aws_instance" "my" {
  count         = 3
  ami           = data.aws_ami.al2_ami.id
  instance_type = "t2.micro"
}

答案 1 :(得分:1)

不幸的是,像Terraform这样的声明性系统对随机性不是很友好,因为它希望该系统收敛于期望状态,但是随机配置将意味着期望状态将在每个动作上发生变化,因此它将永远不会收敛。在可能的情况下,我建议您使用云服务提供商内置的“随机化”或“分布”机制,例如通过多个子网进行AWS自动扩展。

但是,要务实,Terraform确实有一个random provider,它表示将随机数的生成表示为一种有趣的Terraform资源,因此可以在同一运行中从一次运行到另一次运行保留随机结果Terraform记住从一次运行到下一次运行的EC2实例的ID的方式。

The random_shuffle resource对于这种“选择这些选项中的任何一个(或N个)”情况很有用。

以随机选择AWS区域和可用区的示例为例,第一步是枚举您可以从以下选项中选择的所有选项:

locals {
  possible_regions = toset([
    "us-east-1",
    "us-east-2",
    "us-west-1",
    "us-west-2",
  ])
  possible_availability_zones = tomap({
    us-east-1 = toset(["a", "b", "e"])
    us-east-2 = toset(["a", "c")
    us-west-1 = toset(["a", "b"])
    us-west-2 = toset(["b", "c"])
  })
}

然后您可以将这些输入传递到random_shuffle资源中,以选择例如一个区域,然后从该区域中选择两个可用区域:

resource "random_shuffle" "region" {
  input        = local.possible_regions
  result_count = 1
}

resource "random_shuffle" "availability_zones" {
  input        = local.possible_availability_zones[local.chosen_region]
  result_count = 2
}

locals {
  local.chosen_region = random_shuffle.region.result[0]
  local.chosen_availability_zones = random_shuffle.availability_zones.result
}

然后可以在配置的其他位置使用local.chosen_regionlocal.chosen_availability_zones

但是,随机选择区域存在一个重要的陷阱:AWS提供者被设计为需要一个区域,因为每个AWS区域都是一组完全不同的端点,因此提供者将无法成功如果在应用步骤之前不知道该区域,请自行配置,就像您在提供者配置中写入region = local.chosen_region一样。

要解决此问题,将需要对-target使用仅用于特殊用途的terraform apply选项,将Terraform引导为首先仅专注于生成随机区域,然后忽略所有其他内容,直到成功:

# First apply with just the random region targeted
terraform apply -target=random_shuffle.region

# After that succeeds, run apply again normally to
# create everything else.
terraform apply