You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Terraform在AWS ECS Fargate部署HashiCorp Vault?

在AWS ECS Fargate通过Terraform部署HashiCorp Vault的配置方案

一、你的任务定义分析与优化

你提供的任务定义基本可行,但存在几个生产环境下的风险点,需要调整优化:

核心问题与修正:

  1. 镜像标签风险:vault:latest会自动拉取最新镜像,可能导致版本不一致或意外更新,建议指定具体稳定版本(如vault:1.15.3)。
  2. 存储持久化缺失:当前file后端存储在容器本地路径/vault/file,Fargate容器重启后数据会彻底丢失,必须挂载EFS文件系统持久化Vault数据。
  3. VAULT_ADDR配置优化:容器内可直接设置为http://0.0.0.0:8200,不影响内部访问,外部访问通过后续服务的网络配置实现。

优化后的任务定义(包含EFS挂载):

resource "aws_ecs_task_definition" "vault" {
  family                   = "vault-task"
  container_definitions    = <<DEFINITION
  [
    {
      "name": "vault",
      "image": "vault:1.15.3",
      "essential": true,
      "portMappings": [
        {
          "containerPort": 8200,
          "hostPort": 8200,
          "protocol": "tcp"
        }
      ],
      "environment": [
        {
          "name": "VAULT_ADDR",
          "value": "http://0.0.0.0:8200"
        },
        {
          "name": "VAULT_LOCAL_CONFIG",
          "value": "{ \"backend\": {\"file\": {\"path\": \"/vault/file\"}}, \"default_lease_ttl\": \"168h\", \"max_lease_ttl\": \"720h\", \"listener\": [{ \"tcp\": { \"address\": \"0.0.0.0:8200\", \"tls_disable\": true }}] }"
        }
      ],
      "memory": 512,
      "cpu": 256,
      "mountPoints": [
        {
          "sourceVolume": "vault-storage",
          "containerPath": "/vault/file",
          "readOnly": false
        }
      ]
    }
  ]
  DEFINITION
  requires_compatibilities = ["FARGATE"]
  network_mode             = "awsvpc"
  memory                   = 512
  cpu                      = 256
  execution_role_arn       = aws_iam_role.ecs_task_execution_role.arn
  task_role_arn            = aws_iam_role.ecs_task_role.arn # 用于访问EFS/KMS等资源

  volume {
    name = "vault-storage"
    efs_volume_configuration {
      file_system_id     = aws_efs_file_system.vault.id
      root_directory     = "/vault-data"
      transit_encryption = "ENABLED"
    }
  }
}

二、ECS服务定义

通过以下Terraform代码定义ECS服务,管理Vault任务的运行:

resource "aws_ecs_service" "vault" {
  name            = "vault-service"
  cluster         = aws_ecs_cluster.vault_cluster.id
  task_definition = aws_ecs_task_definition.vault.arn
  desired_count   = 1 # Vault单节点部署,集群需额外配置Raft后端
  launch_type     = "FARGATE"

  network_configuration {
    subnets          = [aws_subnet.private_subnet_1.id, aws_subnet.private_subnet_2.id] # 推荐用私有子网,通过ALB暴露服务
    security_groups  = [aws_security_group.vault_sg.id]
    assign_public_ip = false # 私有子网无需公网IP
  }

  # 可选:配置负载均衡(外部访问Vault时需添加)
  load_balancer {
    target_group_arn = aws_lb_target_group.vault_tg.id
    container_name   = "vault"
    container_port   = 8200
  }

  deployment_controller {
    type = "ECS"
  }

  lifecycle {
    ignore_changes = [desired_count] # 避免terraform apply时重置实例数
  }
}

三、关键配套资源配置

1. EFS文件系统(持久化存储)

resource "aws_efs_file_system" "vault" {
  creation_token = "vault-storage"
  tags = {
    Name = "vault-storage"
  }
}

resource "aws_efs_mount_target" "vault" {
  count             = length(aws_subnet.private_subnet)
  file_system_id    = aws_efs_file_system.vault.id
  subnet_id         = aws_subnet.private_subnet[count.index].id
  security_groups   = [aws_security_group.efs_sg.id]
}

2. 安全组配置

  • Vault安全组:仅允许负载均衡或指定IP访问8200端口
resource "aws_security_group" "vault_sg" {
  name        = "vault-sg"
  description = "Allow Vault traffic"
  vpc_id      = aws_vpc.main.id

  ingress {
    from_port       = 8200
    to_port         = 8200
    protocol        = "tcp"
    security_groups = [aws_security_group.alb_sg.id]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

3. IAM角色配置

  • 任务执行角色:需具备拉取镜像、访问EFS的权限
resource "aws_iam_role" "ecs_task_execution_role" {
  name = "ecs-task-execution-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "ecs-tasks.amazonaws.com"
        }
      }
    ]
  })
}

resource "aws_iam_role_policy_attachment" "ecs_task_execution_role_policy" {
  role       = aws_iam_role.ecs_task_execution_role.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
}

resource "aws_iam_role_policy" "efs_access_policy" {
  name   = "efs-access-policy"
  role   = aws_iam_role.ecs_task_execution_role.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = ["elasticfilesystem:ClientMount", "elasticfilesystem:ClientWrite"]
        Effect = "Allow"
        Resource = aws_efs_file_system.vault.arn
      }
    ]
  })
}

四、Vault初始化与Unseal

Fargate启动Vault后,需手动完成初始化:

  1. 进入容器终端:aws ecs execute-command --cluster <集群名> --task <任务ID> --container vault --interactive --command "/bin/sh"
  2. 初始化Vault:vault operator init,保存生成的根令牌和unseal密钥
  3. Unseal Vault:vault operator unseal <unseal密钥>(默认需执行3次)

若需自动Unseal,可配置AWS KMS作为后端,修改VAULT_LOCAL_CONFIG中的seal节点:

"seal": {
  "awskms": {
    "kms_key_id": "<你的KMS密钥ARN>"
  }
}

内容的提问来源于stack exchange,提问作者Benjamin Volk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 14:25:47