【Terragrunt】需要更多的暂存环境?只要准备足够的数量就可以了

简述

みるく-milk.gif

这次!我使用Terragrunt + GitHub Actions成功创建了一个可以为多个成员设置环境的基础设施,我打算解释一下它。

期待收到您的建议和意见٩( ᐛ )و

环境

$ terragrunt -v
terragrunt version v0.46.2

$ terraform -v
Terraform v1.3.7

方法

技术选择

    • Terraform

 

    Terragrunt

Terragrunt是Terraform的封装工具。我们选择使用它是因为

    1. 在tfstate之间定义依赖关系很容易

可以在backend块中访问环境变量。

这将是两个重要的要点。

tfstate之间的依赖关系定义很简单。

尽管我们说要将环境分离,但并不意味着完全独立创建资源。
例如,VPC和ALB等都是一些共同引用的内容。
新环境将依赖于这些值(如id和ARN),但通过Terraform在tfstate之间传递值是比较麻烦的。
具体而言,需要将tfstate1中输出的值硬编码到tfstate2的tfvars中,或者在运行时明确传递值。

通过使用依赖块,Terragrunt可以轻松在tfstate之间共享值。

dependency "common" {
  config_path = "../common_resources"
}

由于成员的环境的tfstate存在共同的依赖关系,因此该描述非常匹配。

在后端块中能够访问环境变量。

由于考虑到在GitHub Actions中执行Terragrunt,因此不能将tfstate文件保存在本地。
另外,需要为每个用户分别管理tfstate的键。

在Terraform中,无法直接在backend块内引用环境变量。相反,需要使用-backend-config选项作为terraform init的一部分来传递参数。这需要在每个环境中手动操作。

  backend "s3" {
     bucket = "dummy-terraform"
     key    = "staging/terraform.tfstate"
     region = "ap-northeast-1"
  }
$ terraform init \
 -backend-config="bucket=real-terraform"\
 -backend-config="key=userA/terraform.tfstate"\
 -backend-config="region=us-east-1"

在 Terragrunt 中,可以直接在 backend 块中引用环境变量。

remote_state {
  backend = "s3"
  config = {
    bucket         = "${get_env("STATE_BUCKET", 'hogehoge-terraform')}"
    key            = "${get_env("ENVIRONMENT", 'staging')}/terraform.tfstate"
    region         = "ap-northeast-1"
  }
}
$ export STATE_BUCKET=real-terraform
$ export ENVIRONMENT=userA
$ terragrunt init 

如果在GitHub Actions中将从秘钥中获取到的环境变量设置好,Terragrunt将会读取并进行相应的部署。

架构

暂时我们已经完成了!

 

名称未設定ファイル.drawio (9).png

无论是在本地还是在GitHub Actions上,都可以触发workflow_dispatch并进行此资源的配置。
根据执行GitHub用户的名称,创建如下所示的资源。

名称未設定ファイル.drawio (10).png

首次部署时

    1. 在Route53上注册子域名(<你的github用户名>.<你的域名>)

 

    1. 添加ALB监听规则

 

    创建ECS集群和服务

在执行一次后,随后的第二次及之后的操作将会使用GitHubActions推送到ECR的镜像作为基础,来更新任务定义并更新服务。

结论

你觉得怎么样呢?
这是一个用于在每个用户中使用GitHub Actions创建环境的架构方案。
可能还有更好的方法,但现在对我来说这是最佳解决方案?
如果你愿意,可以参考一下?

将来

非常详细,但是Fargate即使在运行时间也会产生费用,所以对于staging环境而言,想要在夜间(业务时间之外)停止它是很理解的。如果是在ECS on EC2中,通过ASG可以将特定时间段的容器实例数量设置为0来实现,但是在Fargate的情况下应该怎么办呢…?

嗯…?晚上不是非工作时间吗?
对、对不起?

广告
将在 10 秒后关闭
bannerAds