【Terragrunt】需要更多的暂存环境?只要准备足够的数量就可以了
简述
这次!我使用Terragrunt + GitHub Actions成功创建了一个可以为多个成员设置环境的基础设施,我打算解释一下它。
期待收到您的建议和意见٩( ᐛ )و
环境
$ terragrunt -v
terragrunt version v0.46.2
$ terraform -v
Terraform v1.3.7
方法
技术选择
-
- Terraform
- Terragrunt
Terragrunt是Terraform的封装工具。我们选择使用它是因为
-
- 在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将会读取并进行相应的部署。
架构
暂时我们已经完成了!
无论是在本地还是在GitHub Actions上,都可以触发workflow_dispatch并进行此资源的配置。
根据执行GitHub用户的名称,创建如下所示的资源。
首次部署时
-
- 在Route53上注册子域名(<你的github用户名>.<你的域名>)
-
- 添加ALB监听规则
- 创建ECS集群和服务
在执行一次后,随后的第二次及之后的操作将会使用GitHubActions推送到ECR的镜像作为基础,来更新任务定义并更新服务。
结论
你觉得怎么样呢?
这是一个用于在每个用户中使用GitHub Actions创建环境的架构方案。
可能还有更好的方法,但现在对我来说这是最佳解决方案?
如果你愿意,可以参考一下?
将来
非常详细,但是Fargate即使在运行时间也会产生费用,所以对于staging环境而言,想要在夜间(业务时间之外)停止它是很理解的。如果是在ECS on EC2中,通过ASG可以将特定时间段的容器实例数量设置为0来实现,但是在Fargate的情况下应该怎么办呢…?
嗯…?晚上不是非工作时间吗?
对、对不起?