通过 Terraform 安装 EFS 时,ECS Fargate 任务卡在挂起状态
ECS Fargate Tasks stuck in pending when mounting EFS via Terraform
在 Terraform 中安装 EFS 时,我的 ECS Fargate 任务卡在挂起状态。我在我的集群所在的两个子网中都有挂载点,并且我在 2049 上有一个用于挂载点的 sec 组,它允许应用程序的 sec 组进入。我想这可能是角色或 IAM 问题,但我不确定最好的配置并且对 AWS 和 Terraform 很陌生。非常感谢您审阅我的问题并提供帮助。
EFS 文件
# Creating Amazon EFS File system
resource "aws_efs_file_system" "myfilesystem" {
lifecycle_policy {
transition_to_ia = "AFTER_30_DAYS"
}
}
# Creating the EFS access point for AWS EFS File system
resource "aws_efs_access_point" "test" {
file_system_id = aws_efs_file_system.myfilesystem.id
}
# Creating the AWS EFS System policy to transition files into and out of the file system.
resource "aws_efs_file_system_policy" "policy" {
file_system_id = aws_efs_file_system.myfilesystem.id
policy = <<POLICY
{
"Version": "2012-10-17",
"Id": "Policy01",
"Statement": [
{
"Sid": "Statement",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Resource": "${aws_efs_file_system.myfilesystem.arn}",
"Action": [
"elasticfilesystem:ClientMount",
"elasticfilesystem:ClientRootAccess",
"elasticfilesystem:ClientWrite"
],
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
}
]
}
POLICY
}
# AWS EFS Mount point uses File system ID to launch.
resource "aws_efs_mount_target" "alpha" {
file_system_id = aws_efs_file_system.myfilesystem.id
subnet_id = "subnet-09469abaeaf483de5"
security_groups = [aws_security_group.efs.id]
depends_on = [
aws_security_group.efs
]
}
resource "aws_efs_mount_target" "beta" {
file_system_id = aws_efs_file_system.myfilesystem.id
subnet_id = "subnet-04903e6b225a67aeb"
security_groups = [aws_security_group.efs.id]
depends_on = [
aws_security_group.efs
]
}
安全组和任务定义
//Grafana Application Security Group
resource "aws_security_group" "grafana" {
name = "grafana"
description = "Grafana Application Security Group"
vpc_id = var.vpc_id
ingress {
description = "Allows the load balancer to access Grafana"
from_port = 0
to_port = 65535
protocol = "tcp"
security_groups = [aws_security_group.grafana-lb-sec.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Name = "grafana"
}
//EFS Mount Point Security Group that Allows Traffic from ECS to EFS
resource "aws_security_group" "efs" {
name = "efs-sec-group"
description = "EFS Security Group"
vpc_id = var.vpc_id
ingress {
description = "Allows ECS to access EFS"
from_port = 2049
to_port = 2049
protocol = "tcp"
security_groups = [aws_security_group.grafana.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Name = "fargate-grafana"
}
depends_on = [
aws_security_group.grafana
]
}
//ECS Cluster
resource "aws_ecs_cluster" "grafana" {
name = "grafana"
}
//Task Definition
resource "aws_ecs_task_definition" "grafana" {
family = "grafana"
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
cpu = "512"
memory = "1024"
task_role_arn = "arn:aws:iam::692869463706:role/ecsTaskExecutionRole"
container_definitions = <<DEFINITION
[
{
"memory": 128,
"cpu": 10,
"portMappings": [
{
"hostPort": 3000,
"containerPort": 3000,
"protocol": "tcp"
}
],
"essential": true,
"mountPoints": [
{
"containerPath": "/var/lib/grafana",
"sourceVolume": "efs-html",
"readOnly": null
}
],
"name": "grafana",
"image": "grafana/grafana:latest"
}
]
DEFINITION
volume {
name = "efs-html"
efs_volume_configuration {
file_system_id = aws_efs_file_system.myfilesystem.id
root_directory = "/"
transit_encryption = "ENABLED"
transit_encryption_port = 2999
}
}
}
//ECS Service
resource "aws_ecs_service" "grafana" {
name = "grafana"
cluster = aws_ecs_cluster.grafana.id
task_definition = aws_ecs_task_definition.grafana.arn
desired_count = 1
health_check_grace_period_seconds = 300
network_configuration {
subnets = var.subnets
security_groups = [aws_security_group.grafana.id]
assign_public_ip = true
}
load_balancer {
target_group_arn = aws_lb_target_group.grafana-test-tg.arn
container_name = "grafana"
container_port = 3000
}
launch_type = "FARGATE"
platform_version = "1.4.0"
}
您目前没有使用您正在创建的接入点。您在 ECS 任务的卷配置中缺少访问点信息。将任务定义中的卷配置更改为以下内容:
volume {
name = "efs-html"
efs_volume_configuration {
file_system_id = aws_efs_file_system.myfilesystem.id
root_directory = "/"
transit_encryption = "ENABLED"
transit_encryption_port = 2999
authorization_config {
access_point_id = aws_efs_access_point.test.id
iam = "ENABLED"
}
}
}
此外,您的 EFS 策略将不起作用。如果 aws:secureTransport
是 false
,您目前只允许访问您的 EFS 系统。这意味着如果请求是安全的,您将拒绝所有访问文件系统的请求。这几乎肯定与您想要的相反。在该条件下,EFS 策略的 Effect
应该是 Deny
,而不是 Allow
。
最后,您分配给 ECS 任务的 IAM 角色:arn:aws:iam::692869463706:role/ecsTaskExecutionRole
需要添加适当的 EFS
权限(elasticfilesystem:ClientMount
、elasticfilesystem:ClientWrite
、 and/or elasticfilesystem:ClientRootAccess
),如果还没有。
在 Terraform 中安装 EFS 时,我的 ECS Fargate 任务卡在挂起状态。我在我的集群所在的两个子网中都有挂载点,并且我在 2049 上有一个用于挂载点的 sec 组,它允许应用程序的 sec 组进入。我想这可能是角色或 IAM 问题,但我不确定最好的配置并且对 AWS 和 Terraform 很陌生。非常感谢您审阅我的问题并提供帮助。
EFS 文件
# Creating Amazon EFS File system
resource "aws_efs_file_system" "myfilesystem" {
lifecycle_policy {
transition_to_ia = "AFTER_30_DAYS"
}
}
# Creating the EFS access point for AWS EFS File system
resource "aws_efs_access_point" "test" {
file_system_id = aws_efs_file_system.myfilesystem.id
}
# Creating the AWS EFS System policy to transition files into and out of the file system.
resource "aws_efs_file_system_policy" "policy" {
file_system_id = aws_efs_file_system.myfilesystem.id
policy = <<POLICY
{
"Version": "2012-10-17",
"Id": "Policy01",
"Statement": [
{
"Sid": "Statement",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Resource": "${aws_efs_file_system.myfilesystem.arn}",
"Action": [
"elasticfilesystem:ClientMount",
"elasticfilesystem:ClientRootAccess",
"elasticfilesystem:ClientWrite"
],
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
}
]
}
POLICY
}
# AWS EFS Mount point uses File system ID to launch.
resource "aws_efs_mount_target" "alpha" {
file_system_id = aws_efs_file_system.myfilesystem.id
subnet_id = "subnet-09469abaeaf483de5"
security_groups = [aws_security_group.efs.id]
depends_on = [
aws_security_group.efs
]
}
resource "aws_efs_mount_target" "beta" {
file_system_id = aws_efs_file_system.myfilesystem.id
subnet_id = "subnet-04903e6b225a67aeb"
security_groups = [aws_security_group.efs.id]
depends_on = [
aws_security_group.efs
]
}
安全组和任务定义
//Grafana Application Security Group
resource "aws_security_group" "grafana" {
name = "grafana"
description = "Grafana Application Security Group"
vpc_id = var.vpc_id
ingress {
description = "Allows the load balancer to access Grafana"
from_port = 0
to_port = 65535
protocol = "tcp"
security_groups = [aws_security_group.grafana-lb-sec.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Name = "grafana"
}
//EFS Mount Point Security Group that Allows Traffic from ECS to EFS
resource "aws_security_group" "efs" {
name = "efs-sec-group"
description = "EFS Security Group"
vpc_id = var.vpc_id
ingress {
description = "Allows ECS to access EFS"
from_port = 2049
to_port = 2049
protocol = "tcp"
security_groups = [aws_security_group.grafana.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Name = "fargate-grafana"
}
depends_on = [
aws_security_group.grafana
]
}
//ECS Cluster
resource "aws_ecs_cluster" "grafana" {
name = "grafana"
}
//Task Definition
resource "aws_ecs_task_definition" "grafana" {
family = "grafana"
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
cpu = "512"
memory = "1024"
task_role_arn = "arn:aws:iam::692869463706:role/ecsTaskExecutionRole"
container_definitions = <<DEFINITION
[
{
"memory": 128,
"cpu": 10,
"portMappings": [
{
"hostPort": 3000,
"containerPort": 3000,
"protocol": "tcp"
}
],
"essential": true,
"mountPoints": [
{
"containerPath": "/var/lib/grafana",
"sourceVolume": "efs-html",
"readOnly": null
}
],
"name": "grafana",
"image": "grafana/grafana:latest"
}
]
DEFINITION
volume {
name = "efs-html"
efs_volume_configuration {
file_system_id = aws_efs_file_system.myfilesystem.id
root_directory = "/"
transit_encryption = "ENABLED"
transit_encryption_port = 2999
}
}
}
//ECS Service
resource "aws_ecs_service" "grafana" {
name = "grafana"
cluster = aws_ecs_cluster.grafana.id
task_definition = aws_ecs_task_definition.grafana.arn
desired_count = 1
health_check_grace_period_seconds = 300
network_configuration {
subnets = var.subnets
security_groups = [aws_security_group.grafana.id]
assign_public_ip = true
}
load_balancer {
target_group_arn = aws_lb_target_group.grafana-test-tg.arn
container_name = "grafana"
container_port = 3000
}
launch_type = "FARGATE"
platform_version = "1.4.0"
}
您目前没有使用您正在创建的接入点。您在 ECS 任务的卷配置中缺少访问点信息。将任务定义中的卷配置更改为以下内容:
volume {
name = "efs-html"
efs_volume_configuration {
file_system_id = aws_efs_file_system.myfilesystem.id
root_directory = "/"
transit_encryption = "ENABLED"
transit_encryption_port = 2999
authorization_config {
access_point_id = aws_efs_access_point.test.id
iam = "ENABLED"
}
}
}
此外,您的 EFS 策略将不起作用。如果 aws:secureTransport
是 false
,您目前只允许访问您的 EFS 系统。这意味着如果请求是安全的,您将拒绝所有访问文件系统的请求。这几乎肯定与您想要的相反。在该条件下,EFS 策略的 Effect
应该是 Deny
,而不是 Allow
。
最后,您分配给 ECS 任务的 IAM 角色:arn:aws:iam::692869463706:role/ecsTaskExecutionRole
需要添加适当的 EFS
权限(elasticfilesystem:ClientMount
、elasticfilesystem:ClientWrite
、 and/or elasticfilesystem:ClientRootAccess
),如果还没有。