我在这个 ecs fargate 脚本中需要两个 aws_iam_policy_document 吗?
Do I need two aws_iam_policy_document in this ecs fargate script?
这是我的 terraform 脚本
variable "aws_region" { }
variable "flavor" { } # test or prod
variable "task_worker_service_name" { }
variable "task_cpu" {}
variable "task_memory" {}
variable "az_count" {}
terraform {
required_version = "= 0.12.6"
}
provider "aws" {
version = "~> 2.21.1"
region = "${var.aws_region}"
}
data "aws_availability_zones" "available" {}
data "aws_iam_policy_document" "ecs_service_policy" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = [ "ecs.amazonaws.com" ]
}
}
}
data "aws_iam_policy_document" "task_worker_iam_role_policy" {
statement {
actions = [ "sts:AssumeRole" ]
principals {
type = "Service"
identifiers = [
"ecs-tasks.amazonaws.com"
]
}
}
}
data "aws_iam_policy_document" "assume_role_policy" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = [ "ecs-tasks.amazonaws.com" ]
}
}
}
resource "aws_iam_role" "ecs_service_role" {
name = "${var.flavor}-task-ecs-service-role"
path = "/"
assume_role_policy = "${data.aws_iam_policy_document.ecs_service_policy.json}"
}
resource "aws_iam_role_policy_attachment" "ecs_service_role_attachment" {
role = "${aws_iam_role.ecs_service_role.name}"
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole"
}
resource "aws_vpc" "ecs" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
instance_tenancy = "default"
tags = {
Name = "ecs"
}
}
resource "aws_security_group" "vpc_ecs_task_worker" {
name = "${var.flavor}-vpc_ecs_task_worker"
description = "ECS Allowed Ports"
ingress {
from_port = 32768
to_port = 65535
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"]
}
}
resource "aws_iam_role" "ecs_task_execution_role" {
name = "${var.flavor}-ecs-task-worker-task-execution-role"
assume_role_policy = data.aws_iam_policy_document.assume_role_policy.json
}
resource "aws_iam_role" "task_worker_iam_role" {
name = "${var.flavor}-task-worker-role"
path = "/"
assume_role_policy = data.aws_iam_policy_document.task_worker_iam_role_policy.json
}
# Create var.az_count private subnets, each in a different AZ
resource "aws_subnet" "private" {
count = "${var.az_count}"
cidr_block = "${cidrsubnet(aws_vpc.ecs.cidr_block, 8, count.index)}"
availability_zone = "${data.aws_availability_zones.available.names[count.index]}"
vpc_id = "${aws_vpc.ecs.id}"
}
resource "aws_ecs_task_definition" "task_worker" {
family = "${var.flavor}-${var.task_worker_service_name}"
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
cpu = var.task_cpu
memory = var.task_memory
execution_role_arn = aws_iam_role.ecs_task_execution_role.arn
task_role_arn = aws_iam_role.task_worker_iam_role.arn
container_definitions = <<JSON
[
{
"dnsSearchDomains": null,
"logConfiguration": null,
"entryPoint": null,
"portMappings": [],
"command": null,
"linuxParameters": null,
"cpu": ${var.task_cpu},
"environment": [],
"resourceRequirements": null,
"ulimits": null,
"dnsServers": null,
"mountPoints": [],
"workingDirectory": null,
"secrets": null,
"dockerSecurityOptions": null,
"memory": null,
"memoryReservation": ${var.task_memory},
"volumesFrom": [],
"stopTimeout": null,
"image": "us-west-2.amazonaws.com/task:4383669",
"startTimeout": null,
"dependsOn": null,
"disableNetworking": null,
"interactive": null,
"healthCheck": null,
"essential": true,
"links": null,
"hostname": null,
"extraHosts": null,
"pseudoTerminal": null,
"user": null,
"readonlyRootFilesystem": null,
"dockerLabels": null,
"systemControls": null,
"privileged": null,
"name": "task-worker"
}
]
JSON
}
resource "aws_ecs_cluster" "task_pool" {
name = "${var.flavor}-task-pool"
}
resource "aws_ecs_service" "task_service" {
name = "${var.flavor}-task-worker-service"
cluster = "${aws_ecs_cluster.task_pool.id}"
task_definition = "${aws_ecs_task_definition.task_worker.arn}"
launch_type = "FARGATE"
desired_count = 2
network_configuration {
subnets = "${aws_subnet.private[*].id}"
security_groups = ["${aws_security_group.vpc_ecs_task_worker.id}" ]
assign_public_ip = "true"
}
}
在这个脚本中我添加了两个 'aws_iam_policy_document':
data "aws_iam_policy_document" "pdf_conversion_iam_role_policy"
,以及
data "aws_iam_policy_document" "assume_role_policy"
分别
它们基本相同,即
data "aws_iam_policy_document" "assume_role_policy" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = [ "ecs-tasks.amazonaws.com" ]
}
}
}
我在 aws_iam_role.ecs_task_execution_role
中使用了 assume_role_policy
,在 aws_iam_role.pdf_conversion_iam_role
中使用了 pdf_conversion_iam_role_policy
。
我的问题是:在这种情况下是否有必要有两个aws_iam_policy_document
?另外,您对这种 terraform 资源名称的命名约定有什么好的建议吗?
如果您使用的是最新版本的 Terraform,那么您可以使用资源 for_each
功能编写此代码,以从单个 data
块中生成 aws_iam_policy_document
的多个实例:
data "aws_iam_policy_document" "assume_role" {
for_each = toset([
"ecs-tasks.amazonaws.com",
"ecs.amazonaws.com",
])
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = [each.value]
}
}
}
resource "aws_iam_role" "service" {
for_each = data.aws_iam_policy_document.assume_role
name = "${var.flavor}-${each.key}-service-role"
assume_role_policy = each.value.json
}
resource "aws_iam_role_policy_attachment" "ecs_service" {
role = aws_iam_role.service["ecs.amazonaws.com"].name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole"
}
for_each
在 data
或 resource
块中使对资源的引用产生资源对象的映射。在这种情况下,我们的映射键是服务标识符。这为我们提供了一些具有以下地址的资源:
data.aws_iam_policy_document.assume_role["ecs.amazonaws.com"]
data.aws_iam_policy_document.assume_role["ecs-tasks.amazonaws.com"]
aws_iam_role.service["ecs.amazonaws.com"]
aws_iam_role.service["ecs-tasks.amazonaws.com"]
aws_iam_role_policy_attachment.ecs_service
资源然后直接引用 ecs.amazonaws.com
的特定角色对象,允许它表示唯一附加到该角色的策略,即使我们概括了角色本身的创建.
我们可以向 data "aws_iam_policy_document" "assume_role"
中的 for_each
添加更多服务标识符,或者甚至可能将此模式分解到一个模块中,该模块将服务主机名集作为输入变量并导出角色通过输出值命名,如果您发现自己创建了很多这样的名称。
这是我的 terraform 脚本
variable "aws_region" { }
variable "flavor" { } # test or prod
variable "task_worker_service_name" { }
variable "task_cpu" {}
variable "task_memory" {}
variable "az_count" {}
terraform {
required_version = "= 0.12.6"
}
provider "aws" {
version = "~> 2.21.1"
region = "${var.aws_region}"
}
data "aws_availability_zones" "available" {}
data "aws_iam_policy_document" "ecs_service_policy" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = [ "ecs.amazonaws.com" ]
}
}
}
data "aws_iam_policy_document" "task_worker_iam_role_policy" {
statement {
actions = [ "sts:AssumeRole" ]
principals {
type = "Service"
identifiers = [
"ecs-tasks.amazonaws.com"
]
}
}
}
data "aws_iam_policy_document" "assume_role_policy" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = [ "ecs-tasks.amazonaws.com" ]
}
}
}
resource "aws_iam_role" "ecs_service_role" {
name = "${var.flavor}-task-ecs-service-role"
path = "/"
assume_role_policy = "${data.aws_iam_policy_document.ecs_service_policy.json}"
}
resource "aws_iam_role_policy_attachment" "ecs_service_role_attachment" {
role = "${aws_iam_role.ecs_service_role.name}"
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole"
}
resource "aws_vpc" "ecs" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
instance_tenancy = "default"
tags = {
Name = "ecs"
}
}
resource "aws_security_group" "vpc_ecs_task_worker" {
name = "${var.flavor}-vpc_ecs_task_worker"
description = "ECS Allowed Ports"
ingress {
from_port = 32768
to_port = 65535
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"]
}
}
resource "aws_iam_role" "ecs_task_execution_role" {
name = "${var.flavor}-ecs-task-worker-task-execution-role"
assume_role_policy = data.aws_iam_policy_document.assume_role_policy.json
}
resource "aws_iam_role" "task_worker_iam_role" {
name = "${var.flavor}-task-worker-role"
path = "/"
assume_role_policy = data.aws_iam_policy_document.task_worker_iam_role_policy.json
}
# Create var.az_count private subnets, each in a different AZ
resource "aws_subnet" "private" {
count = "${var.az_count}"
cidr_block = "${cidrsubnet(aws_vpc.ecs.cidr_block, 8, count.index)}"
availability_zone = "${data.aws_availability_zones.available.names[count.index]}"
vpc_id = "${aws_vpc.ecs.id}"
}
resource "aws_ecs_task_definition" "task_worker" {
family = "${var.flavor}-${var.task_worker_service_name}"
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
cpu = var.task_cpu
memory = var.task_memory
execution_role_arn = aws_iam_role.ecs_task_execution_role.arn
task_role_arn = aws_iam_role.task_worker_iam_role.arn
container_definitions = <<JSON
[
{
"dnsSearchDomains": null,
"logConfiguration": null,
"entryPoint": null,
"portMappings": [],
"command": null,
"linuxParameters": null,
"cpu": ${var.task_cpu},
"environment": [],
"resourceRequirements": null,
"ulimits": null,
"dnsServers": null,
"mountPoints": [],
"workingDirectory": null,
"secrets": null,
"dockerSecurityOptions": null,
"memory": null,
"memoryReservation": ${var.task_memory},
"volumesFrom": [],
"stopTimeout": null,
"image": "us-west-2.amazonaws.com/task:4383669",
"startTimeout": null,
"dependsOn": null,
"disableNetworking": null,
"interactive": null,
"healthCheck": null,
"essential": true,
"links": null,
"hostname": null,
"extraHosts": null,
"pseudoTerminal": null,
"user": null,
"readonlyRootFilesystem": null,
"dockerLabels": null,
"systemControls": null,
"privileged": null,
"name": "task-worker"
}
]
JSON
}
resource "aws_ecs_cluster" "task_pool" {
name = "${var.flavor}-task-pool"
}
resource "aws_ecs_service" "task_service" {
name = "${var.flavor}-task-worker-service"
cluster = "${aws_ecs_cluster.task_pool.id}"
task_definition = "${aws_ecs_task_definition.task_worker.arn}"
launch_type = "FARGATE"
desired_count = 2
network_configuration {
subnets = "${aws_subnet.private[*].id}"
security_groups = ["${aws_security_group.vpc_ecs_task_worker.id}" ]
assign_public_ip = "true"
}
}
在这个脚本中我添加了两个 'aws_iam_policy_document':
data "aws_iam_policy_document" "pdf_conversion_iam_role_policy"
,以及
data "aws_iam_policy_document" "assume_role_policy"
分别
它们基本相同,即
data "aws_iam_policy_document" "assume_role_policy" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = [ "ecs-tasks.amazonaws.com" ]
}
}
}
我在 aws_iam_role.ecs_task_execution_role
中使用了 assume_role_policy
,在 aws_iam_role.pdf_conversion_iam_role
中使用了 pdf_conversion_iam_role_policy
。
我的问题是:在这种情况下是否有必要有两个aws_iam_policy_document
?另外,您对这种 terraform 资源名称的命名约定有什么好的建议吗?
如果您使用的是最新版本的 Terraform,那么您可以使用资源 for_each
功能编写此代码,以从单个 data
块中生成 aws_iam_policy_document
的多个实例:
data "aws_iam_policy_document" "assume_role" {
for_each = toset([
"ecs-tasks.amazonaws.com",
"ecs.amazonaws.com",
])
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = [each.value]
}
}
}
resource "aws_iam_role" "service" {
for_each = data.aws_iam_policy_document.assume_role
name = "${var.flavor}-${each.key}-service-role"
assume_role_policy = each.value.json
}
resource "aws_iam_role_policy_attachment" "ecs_service" {
role = aws_iam_role.service["ecs.amazonaws.com"].name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole"
}
for_each
在 data
或 resource
块中使对资源的引用产生资源对象的映射。在这种情况下,我们的映射键是服务标识符。这为我们提供了一些具有以下地址的资源:
data.aws_iam_policy_document.assume_role["ecs.amazonaws.com"]
data.aws_iam_policy_document.assume_role["ecs-tasks.amazonaws.com"]
aws_iam_role.service["ecs.amazonaws.com"]
aws_iam_role.service["ecs-tasks.amazonaws.com"]
aws_iam_role_policy_attachment.ecs_service
资源然后直接引用 ecs.amazonaws.com
的特定角色对象,允许它表示唯一附加到该角色的策略,即使我们概括了角色本身的创建.
我们可以向 data "aws_iam_policy_document" "assume_role"
中的 for_each
添加更多服务标识符,或者甚至可能将此模式分解到一个模块中,该模块将服务主机名集作为输入变量并导出角色通过输出值命名,如果您发现自己创建了很多这样的名称。