AWS上具有Terraform的多个可用性区域 [英] Multiple availability zones with terraform on AWS
问题描述
我正在使用的VPC具有3个逻辑层:Web,App和DB。对于每个层,每个可用性区域中都有一个子网。我正在使用的区域中共有6个子网。
The VPC I'm working on has 3 logical tiers: Web, App and DB. For each tier there is one subnet in each availability zone. Total of 6 subnets in the region I'm using.
我正在尝试使用模块和 count $创建EC2实例。 c $ c>参数,但我不知道如何告诉terraform使用App层的两个子网。我的另一个限制是使用静态IP地址(或使用具有确定性的私有名称的方式)
I'm trying to create EC2 instances using a module and the count
parameter but I don't know how to tell terraform to use the two subnets of the App tier. An additional constraint I have is to use static IP addresses (or a way to have a deterministic private name)
我在玩弄资源
resource "aws_instance" "app_server" {
...
count = "${var.app_servers_count}"
# Not all at the same time, though!
availability_zone = ...
subnet_id = ...
private_ip = ...
}
到目前为止我已经尝试过/想到的事情:
Things I've tried/thought so far:
- 使用
数据 aws_subnet all_app_subnets {...}
,按名称过滤,获取所有匹配的子网并将其用作列表。但是aws_subnet
无法返回列表; - 使用
data aws_availability_zones {...}
查找所有区域。但是我仍然有分配正确子网的问题; - 使用
data aws_subnet_ids {...}
最好的选择。但是显然,它没有用于匹配网络名称的过滤器选项。 - 将子网ID作为字符串列表传递给模块。但是我不想硬编码ID,这不是自动化;
- 将子网硬编码为
data aws_subnet app_subnet_1 {...}
,数据 aws_subnet app_subnet_2 {...}
,但是我必须为每个子网使用不同的变量集, t like; - 像上面提到的那样获取每个子网的信息,然后创建一个
地图
以列表的形式进行访问。但是不可能在变量定义中使用插值; - 不使用模块并为每个环境对每个实例进行硬编码。嗯...真的吗?
- Use
data "aws_subnet" "all_app_subnets" {...}
, filter by name, get all the subnets that match and use them as a list. Butaws_subnet
cannot return a list; - Use
data "aws_availability_zones" {...}
to find all the zones. But I still have the problem of assigning the correct subnet; - Use
data "aws_subnet_ids" {...}
which looks like the best option. But apparently it doesn't have a filter option to match the networks namel - Pass the subnets IDs as list of strings to the module. But I don't want to hard code the IDs, it's not automation;
- Hard code the subnets as
data "aws_subnet" "app_subnet_1" {...}
,data "aws_subnet" "app_subnet_2" {...}
but then I have to use separate sets of variables for each subnet which I don't like; - Get information for each subnet like in the point above but then create a
map
to access it as a list. But it's not possibile to use interpolation in variables definition; - Not using modules and hard-code each instance for each environment. Mmmm... really?
我真的没有想法了。似乎没有人需要在特定子网中部署实例并保持良好的抽象度。我仅看到未指定子网或人们仅对所有内容使用默认值的示例。
I really ran out of ideas. It seems that nobody has to deploy instances in specific subnetworks and keep a good degree of abstration. I see only examples where subnetworks are not specified or where people just use default values for everything. Is this really something so unusual?
在此先感谢大家。
推荐答案
最后,我想出了解决方法,使用 data aws_subnet_ids {...}
,更重要的是理解terraform在使用时会从资源中创建列表 count
:
At the end I figured out how to do it, using data "aws_subnet_ids" {...}
and more importantly understanding that terraform creates lists out of resources when using 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)}"
...
}
这篇关于AWS上具有Terraform的多个可用性区域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!