Col*_*RiX 10 amazon-ec2 amazon-web-services availability-zone terraform
我正在开发的VPC有3个逻辑层:Web,App和DB.对于每个层,每个可用区中都有一个子网.我正在使用的地区共有6个子网.
我正在尝试使用模块和count参数创建EC2实例,但我不知道如何告诉terraform使用App层的两个子网.我有一个额外的约束是使用静态IP地址(或具有确定性私有名称的方式)
我正在玩这个资源
resource "aws_instance" "app_server" {
...
count = "${var.app_servers_count}"
# Not all at the same time, though!
availability_zone = ...
subnet_id = ...
private_ip = ...
}
Run Code Online (Sandbox Code Playgroud)
到目前为止我尝试/想过的事情:
data "aws_subnet" "all_app_subnets" {...}按名称过滤,获取匹配的所有子网并将其用作列表.但aws_subnet不能退回清单;data "aws_availability_zones" {...}查找所有的区域.但我仍然有分配正确子网的问题;data "aws_subnet_ids" {...}看起来是最好的选择.但显然它没有匹配网络名称的过滤选项data "aws_subnet" "app_subnet_1" {...},data "aws_subnet" "app_subnet_2" {...}但是我必须为每个我不喜欢的子网使用单独的变量集;map以列表形式访问它.但是在变量定义中使用插值是不可能的;我真的没想到了.似乎没有人必须在特定的子网中部署实例并保持良好的程度.我只看到未指定子网的示例或人们只使用默认值的示例.这真的很不寻常吗?
在此先感谢大家.
Tom*_*ime 10
可以使用模数在多个区域中均匀分布实例。
variable "zone" {
description = "for single zone deployment"
default = "europe-west4-b"
}
variable "zones" {
description = "for multi zone deployment"
default = ["europe-west4-b", "europe-west4-c"]
}
resource "google_compute_instance" "default" {
count = "${var.role.count}"
...
zone = "${var.zone != "" ? var.zone: var.zones[ count.index % length(var.zones) ]}"
...
}
Run Code Online (Sandbox Code Playgroud)
这种分布机制允许跨区域均匀分布节点。
例如 zone = [A,B] - instance-1 将在 A 中,instance-2 将在 B 中,instance-3 将再次在 A 中。
通过将区域 C 添加到区域会将实例 3 转移到 C。
小智 8
如果您的实例多于子网,资源中的计数索引将引发错误。使用 Terraform 中的元素插值
element(list, index) - 返回列表中给定索引处的单个元素。如果索引大于元素数量,该函数将使用标准 mod 算法换行。此函数仅适用于平面列表。
subnet_id = "${element(data.aws_subnet_ids.app_tier_ids.ids, count.index)}"
Run Code Online (Sandbox Code Playgroud)
最后,我弄清楚了如何使用data "aws_subnet_ids" {...},更重要的是理解terraform在使用时会浪费资源,这是如何做到的count:
variable "target_vpc" {}
variable "app_server_count" {}
variable "app_server_ip_start" {}
# Discover VPC
data "aws_vpc" "target_vpc" {
filter = {
name = "tag:Name"
values = ["${var.target_vpc}"]
}
}
# Discover subnet IDs. This requires the subnetworks to be tagged with Tier = "AppTier"
data "aws_subnet_ids" "app_tier_ids" {
vpc_id = "${data.aws_vpc.target_vpc.id}"
tags {
Tier = "AppTier"
}
}
# Discover subnets and create a list, one for each found ID
data "aws_subnet" "app_tier" {
count = "${length(data.aws_subnet_ids.app_tier_ids.ids)}"
id = "${data.aws_subnet_ids.app_tier_ids.ids[count.index]}"
}
resource "aws_instance" "app_server" {
...
# Create N instances
count = "${var.app_server_count}"
# Use the "count.index" subnet
subnet_id = "${data.aws_subnet_ids.app_tier_ids.ids[count.index]}"
# Create an IP address using the CIDR of the subnet
private_ip = "${cidrhost(element(data.aws_subnet.app_tier.*.cidr_block, count.index), var.app_server_ip_start + count.index)}"
...
}
Run Code Online (Sandbox Code Playgroud)