使用Terraform构建Fargate的蓝/绿色部署环境

首先

本文介绍了如何用Terraform构建ECS的Fargate环境和Blue/Green部署的管道(CodeCommit + CodeBuild + CodeDeploy +CodePipeline)的步骤。

用Terraform构建整个架构图。

00_fargate_blue_green_deploy.png

用Terraform构建AWS资源的BlackBelt资料

网络VPC
应用负载均衡ALB
弹性云服务器ECS
代码存储库CodeCommit
代码构建器CodeBuild
代码部署器CodeDeploy
代码管道CodePipeline
云监控事件CloudWatchEvents
身份和访问管理IAM

Terraform 的代码和配置

$ tree aws-tf-fargate-blue-green-deploy
aws-tf-fargate-blue-green-deploy
├── modules
│   ├── ecs
│   │   ├── alb.tf
│   │   ├── alb_listener.tf
│   │   ├── alb_security_group.tf
│   │   ├── alb_target_group.tf
│   │   ├── buildspec.yml
│   │   ├── cloudwatch_event.tf
│   │   ├── codebuild.tf
│   │   ├── codecommit.tf
│   │   ├── codedeploy.tf
│   │   ├── codepipeline.tf
│   │   ├── ecr_docker_push.tf
│   │   ├── ecr_repository.tf
│   │   ├── ecs_cluster.tf
│   │   ├── ecs_security_group.tf
│   │   ├── ecs_service.tf
│   │   ├── ecs_task.tf
│   │   ├── ecs_task_role.tf
│   │   ├── ecs_taskdef.json
│   │   ├── files
│   │   │   ├── Dockerfile
│   │   │   └── index.html
│   │   ├── iam_policy
│   │   │   ├── cloudwatch_event_policy.json
│   │   │   ├── cloudwatch_event_trust_policy.json
│   │   │   ├── codebuild_policy.json
│   │   │   ├── codebuild_trust_policy.json
│   │   │   ├── codedeploy_trust_policy.json
│   │   │   ├── codepipeline_policy.json
│   │   │   ├── codepipeline_trust_policy.json
│   │   │   ├── ecs_task_policy.json
│   │   │   └── ecs_task_trust_policy.json
│   │   ├── iam_role.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   └── network
│       ├── internet_gateway.tf
│       ├── outputs.tf
│       ├── route_table.tf
│       ├── subnet.tf
│       ├── variables.tf
│       └── vpc.tf
├── main.tf
├── provider.tf
├── outputs.tf
├── variables.tf
├── sample-app
│   ├── Dockerfile
│   ├── appspec.yaml
│   ├── index.html
│   └── taskdef.json
└── terraform.tfvars-

使用Terraform构建的每个资源名称

リソース名前(デフォルト)VPC 名prefix-dev-vpcALB 名prefix-dev-sample-app-albALB セキュリティグループ名prefix-dev-sample-app-alb-sgECS クラスタ名prefix-dev-clusterECR リポジトリ名prefix-sample-appタスク定義名prefix-dev-sample-app-taskコンテナ名prefix-sample-appサービス名prefix-dev-sample-app-svcサービス セキュリティグループ名prefix-dev-sample-app-svc-sgCodePipeline 名prefix-dev-sample-app-cpCloudWatch Events名prefix-dev-sample-app-cp-eventCodeCommit リポジトリ名prefix-sample-appCodeBuild プロジェクト名prefix-dev-sample-app-cbCodeDeploy アプリケーション名prefix-dev-sample-appCodeDeoloy デプロイグループ名dev

把参数传递给模块

###################
# Network SAMPLE
###################
module "network" {
  source = "./modules/network"

  vpc = {
    name = "${var.prefix}-${var.env}-vpc"
    cidr = "10.0.0.0/16"
  }

  igw_name = "${var.prefix}-${var.env}-igw"

  public_subnet_a = {
    name = "${var.prefix}-${var.env}-public-a"
    cidr = "10.0.1.0/24"
  }

  public_subnet_c = {
    name = "${var.prefix}-${var.env}-public-c"
    cidr = "10.0.2.0/24"
  }

  private_subnet_a = {
    name = "${var.prefix}-${var.env}-private-a"
    cidr = "10.0.10.0/24"
  }

  private_subnet_c = {
    name = "${var.prefix}-${var.env}-private-c"
    cidr = "10.0.20.0/24"
  }

}

############################################
# ECS on Fargate Blue/Green Deploy SAMPLE
############################################
module "ecs" {
  source = "./modules/ecs"

  ## AWS Account ID
  aws_account_id = data.aws_caller_identity.current.account_id

  ## Region
  aws_region = var.aws_region

  ## Network
  vpc_id = module.network.vpc_id
  subnet_ids = [
    module.network.public_subnet_a_id,
    module.network.public_subnet_c_id,
  ]
  my_remote_ip = var.my_remote_ip

  ## ALB
  alb_name = "${var.prefix}-${var.env}-sample-app-alb"

  ## ECS Cluster
  cluster_name = "${var.prefix}-${var.env}-cluster"

  ## ECR
  ecr_name = "${var.prefix}-sample-app"

  ## ECS Task
  task_definition = {
    name           = "${var.prefix}-${var.env}-sample-app-task"
    container_name = "${var.prefix}-sample-app"
    cwlogs_name    = "/aws/ecs/${var.prefix}-sample-app"
    cwlogs_prefix  = var.env

  }

  ## ECS Service
  service_name  = "${var.prefix}-${var.env}-sample-app-svc"
  desired_count = 1

  ## CodePipeline
  codepipeline_name = "${var.prefix}-${var.env}-sample-app-cp"

  ## Stage > Source > CodeCommit 
  repository_name        = "${var.prefix}-sample-app"
  repository_description = "Sample App"

  ## Stage > Build > CodeBuild
  build_project_name = "${var.prefix}-${var.env}-sample-app-cb"

  ## Stage > Deploy > CodeDeploy
  codedeploy_app_name              = "${var.prefix}-sample-app"
  codedeploy_deployment_group_name = var.env

}

事先准备

・安装Docker Desktop
・安装Terraform
・安装tfenv
・为执行Terraform所需的IAM访问密钥和秘密密钥
・用于与CodeCommit进行HTTPS连接的Git身份验证信息
・安装AWS CLI

Terraform的验证环境.

$ terraform -version
Terraform v1.0.4
on darwin_amd64
+ provider registry.terraform.io/hashicorp/aws v3.59.0
+ provider registry.terraform.io/hashicorp/null v3.1.0
+ provider registry.terraform.io/hashicorp/template v2.2.0

Your version of Terraform is out of date! The latest version
is 1.0.7. You can update by downloading from https://www.terraform.io/downloads.html

使用Terrraform构建环境的步骤

假设在Mac环境下进行,按照以下步骤操作:
下载Terraform的代码。

$ git clone https://github.com/okubo-t/aws-tf-fargate-blue-green-deploy.git

转到具有Terraform代码的目录。

$ cd aws-tf-fargate-blue-green-deploy/

创建terraform.tfvars 文件。

$ cp -p terraform.tfvars- terraform.tfvars

根据环境的需要,可以随意修改 terraform.tfvars 文件中的每个参数。

# リージョン
aws_region = "ap-northeast-1"

# リソース名のプレフィックス
prefix = "prefix"

# リソースの環境
env = "dev"

# ALBに HTTPアクセスする時の送信元 IPアドレス
my_remote_ip = "0.0.0.0/0"

确认Docker Desktop已经启动。

$ docker info

确认已安装AWS CLI。(已经验证AWS CLI可运行环境)

$ aws --version
aws-cli/1.19.92 Python/3.7.4 Darwin/18.7.0 botocore/1.20.92

设置AWS认证信息。

$ export AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXX     # アクセスキー
$ export AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXX  # シークレットアクセスキー
$ export AWS_DEFAULT_REGION=ap-northeast-1      # デフォルトリージョン 

使用以下命令对 Terraform 进行初始设置。

$ terraform init

使用以下命令,执行环境部署。

$ terraform apply

在部署完成后,将记录输出的内容。(以下数值仅为示例。)

Apply complete! Resources: 53 added, 0 changed, 0 destroyed.

Outputs:

codecommit_repository = "https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/prefix-sample-app"
prod_url = "http://prefix-dev-sample-app-alb-1234567890.ap-northeast-1.elb.amazonaws.com"
test_url = "http://prefix-dev-sample-app-alb-1234567890.ap-northeast-1.elb.amazonaws.com:10080"

通过Terraform,环境的构建已经完成了。

执行蓝/绿色的部署流水线。

这里有一个选项:

我们可以通过在 ALB 的生产环境侦听器上执行 curl 命令,来确认是否显示“Hello World v1”。我们可以参考已记录的输出中的 prod_url 值来进行确认。

$ curl http://prefix-dev-sample-app-alb-1234567890.ap-northeast-1.elb.amazonaws.com
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>Hello</title>
    </head>
    <body>
        <h1>Hello World v1</h1>
    </body>
</html>

运行以下命令,克隆 CodeCommit 储存库。(请参考之前备忘录中的 codecommit_repository 值。)

$ git clone https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/prefix-sample-app

将Terraform代码中的目录(sample-app)中的每个文件复制到克隆的存储库中。

$ cp -p ./sample-app/* [クローンしたリポジトリ名]

我切换到克隆的仓库。

$ cd [クローンしたリポジトリ名]
$ ls
Dockerfile  appspec.yaml    index.html  taskdef.json
$ cat index.html 
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>Hello</title>
    </head>
    <body>
        <h1>Hello World v2</h1>
    </body>
</html>

将标有「Hello World v2」的代码推送到代码库中。

$ git add .
$ git commit -m "Hello World v2"
$ git push
01_fargate_blue_green_deploy.png
02_fargate_blue_green_deploy.png

请确保[部署状态]处于第2步骤,并针对ALB的测试监听器执行curl命令,以确认显示”Hello World v2″。(请参考记录的Outputs中的test_url值。)

$ curl http://prefix-dev-sample-app-alb-1234567890.ap-northeast-1.elb.amazonaws.com:10080
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>Hello</title>
    </head>
    <body>
        <h1>Hello World v2</h1>
    </body>
</html>

点击[路由重新定向],将流量切换到ALB的生产监听器上。

03_fargate_blue_green_deploy.png
04_fargate_blue_green_deploy.png
05_fargate_blue_green_deploy.png

执行以下命令来更改ALB的生产监听器,如果切换到“Hello World v2”,则蓝/绿部署环境已经建立完成。(请参考已记录的 Outputs 中的 prod_url 值。)

$ curl http://prefix-dev-sample-app-alb-1234567890.ap-northeast-1.elb.amazonaws.com
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>Hello</title>
    </head>
    <body>
        <h1>Hello World v2</h1>
    </body>
</html>

请在管理控制台上查看每个资源的详细配置。

整理收拾

使用以下命令,删除使用 Terraform 创建的 AWS 环境。

$ terraform destroy

最后

希望这能对初学者学习Fargate环境和Blue/Green部署流程有所帮助。

请参考以下网站。

如何在用于ECS Fargate部署的CodePipeline的taskdef.json文件中添加变量。

广告
将在 10 秒后关闭
bannerAds