使用 Terraform 在 Fargate 上部署 ECS 并创建 Nginx
首先
由于一开始在ECS on Fargate × Terraform上构建具有前端和后端分离的Web应用程序似乎很困难,所以这次我决定降低难度,尝试启动一个Nginx服务器。目标是能够通过任务的公共IP访问Nginx服务器的初始页面。
环境
苹果笔记本Pro使用英特尔处理器
macOS Monterey 版本12.6
Terraform v1.4.5
Docker 版本20.10.21
我们将使用VPC、子网、安全组和任务执行角色的默认设置。
步骤
-
- 创建Dockerfile
-
- 创建ECR存储库
-
- 将映像推送到存储库
-
- 创建ECS集群
-
- 创建任务定义
- 创建服务
创建Dockerfile
我将创建一个Nginx的Dockerfile。
FROM nginx:latest
创建 ECR 代码库
创建一个空的私人存储库,并在此处进行一次申请。
### ECR ###
resource "aws_ecr_repository" "nginx_repo" {
name = "nginx-repo"
}
把图像推送到仓库中
参考マネジメントコンソール的推送命令,将构建的Docker镜像推送至创建的存储库。这次我们进行了标记,以便知道版本。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
123456789098.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-img v1 hog1e1b34az5 2 weeks ago 143MB
nginx-img v1 hog1e1b34az5 2 weeks ago 143MB
# リポジトリへpush
docker push 123456789098.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-img:v1
创建ECS集群
接下来将开始建立ECS。我们将创建一个集群。
### クラスター ###
resource "aws_ecs_cluster" "cluster" {
name = "cluster"
}
创建任务定义
只需要启动Web服务器,因此没有特别需要设置的部分,但是在container_definitions的image中,需要指定准确的仓库URI。如果没有使用标签(-t)选项,则附加 :latest。
### タスク定義 ###
resource "aws_ecs_task_definition" "task_def" {
family = "task-def"
cpu = 512
memory = 1024
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
execution_role_arn = module.ecs_task_execution_role.iam_role_arn
container_definitions = jsonencode([
{
name = "nginx-container"
image = "${aws_ecr_repository.nginx_repo.repository_url}:v1"
memory = 512
essential = true
portMappings = [
{
containerPort = 80
hostPort = 80
protocol = "tcp"
}
]
}
])
}
### タスク実行ロール ###
# ~省略~
在中国,通过 aws_ecr_repository.リポジトリ名.repository_url 是无法获取准确的URI。
$ terraform state show aws_ecr_repository.nginx_repo
# aws_ecr_repository.nginx_repo:
resource "aws_ecr_repository" "nginx_repo" {
arn = "arn:aws:ecr:ap-northeast-1:123456789098:repository/nginx-repo"
id = "nginx-repo"
image_tag_mutability = "MUTABLE"
name = "nginx-repo"
registry_id = "123456789098"
repository_url = "123456789098.dkr.ecr.ap-northeast-1.amazonaws.com/nginx-repo"
# ~省略~
}
创建服务
这是最后一步操作!将任务定义加载到集群服务中。一旦应用后,就可以访问Nginx!
resource "aws_ecs_service" "service" {
name = "service"
cluster = aws_ecs_cluster.cluster.arn
task_definition = aws_ecs_task_definition.task_def.arn
desired_count = 1
launch_type = "FARGATE"
platform_version = "1.4.0"
network_configuration {
subnets = data.aws_subnets.default.ids
security_groups = [data.aws_security_group.default.id]
assign_public_ip = true
}
lifecycle {
ignore_changes = [task_definition]
}
}
摘要
我只在管理控制台上操作时确认了ECR的推送命令。Terraform太厉害了! (虽然只是简单的标签更改,不确认也可以完成,哈哈)
通过将CI/CD流水线集成到这次的架构中,我们可以省去每次更新应用程序源代码时都要麻烦地推送Docker镜像的步骤。