将Makefile与Terraform和拆分项目布局一起使用
我有一个类似于将Makefile与Terraform和拆分项目布局一起使用,makefile,terraform,Makefile,Terraform,我有一个类似于 stage └ Makefile └ terraform.tfvars └ vpc └ services └ frontend-app └ backend-app └ vars.tf └ outputs.tf └ main.tf └ data-storage └ mysql └ redis .PHONY: all plan apply destroy
stage
└ Makefile
└ terraform.tfvars
└ vpc
└ services
└ frontend-app
└ backend-app
└ vars.tf
└ outputs.tf
└ main.tf
└ data-storage
└ mysql
└ redis
.PHONY: all plan apply destroy
all: plan
plan:
terraform plan -var-file terraform.tfvars -out terraform.tfplan
apply:
terraform apply -var-file terraform.tfvars
destroy:
terraform plan -destroy -var-file terraform.tfvars -out terraform.tfplan
terraform apply terraform.tfplan
其中Makefile
的内容与
stage
└ Makefile
└ terraform.tfvars
└ vpc
└ services
└ frontend-app
└ backend-app
└ vars.tf
└ outputs.tf
└ main.tf
└ data-storage
└ mysql
└ redis
.PHONY: all plan apply destroy
all: plan
plan:
terraform plan -var-file terraform.tfvars -out terraform.tfplan
apply:
terraform apply -var-file terraform.tfvars
destroy:
terraform plan -destroy -var-file terraform.tfvars -out terraform.tfplan
terraform apply terraform.tfplan
据我所知,Terraform
将只在当前目录中的模板上运行。所以我需要cd-stage/services/backend-app
并在那里运行terraform-apply
但是,我希望能够从Makefile管理整个堆栈。我还没有看到一种将参数传递给make
的干净方法
我的目标是制定如下目标:
make s3 plan # verify syntax
make s3 apply # apply plan
除非有更好的方法从父目录运行terraform?是否有类似的情况:
make all plan # create stage plan
make all apply # apply stage plan
│ ├── prod
│ │ ├── vpc
│ │ │ ├── backend.tf
│ │ │ ├── main.tf
│ │ │ ├── outputs.tf
│ │ │ └── variables.tf
我们使用shell脚本来处理这个确切的用例,它可以更好地处理
cd
ing
但是,您可以通过使用环境变量或直接在目标后面的命令行上设置Make变量,如下所示:
make target FOO=bar
因此,在您的情况下,您可能需要以下内容:
ifndef LOCATION
$(error LOCATION is not set)
endif
.PHONY: all plan apply destroy
all: plan
plan:
cd $(LOCATION) && \
terraform plan -var-file terraform.tfvars -out terraform.tfplan
apply:
cd $(LOCATION) && \
terraform apply -var-file terraform.tfvars
destroy:
cd $(LOCATION) && \
terraform plan -destroy -var-file terraform.tfvars -out terraform.tfplan
terraform apply terraform.tfplan
我可能倾向于有一个运行
terraformget
并配置远程状态的目标,但现在设置起来应该很简单。我们使用shell脚本来处理这个确切的用例,它可以更好地处理cd
ing
但是,您可以通过使用环境变量或直接在目标后面的命令行上设置Make变量,如下所示:
make target FOO=bar
因此,在您的情况下,您可能需要以下内容:
ifndef LOCATION
$(error LOCATION is not set)
endif
.PHONY: all plan apply destroy
all: plan
plan:
cd $(LOCATION) && \
terraform plan -var-file terraform.tfvars -out terraform.tfplan
apply:
cd $(LOCATION) && \
terraform apply -var-file terraform.tfvars
destroy:
cd $(LOCATION) && \
terraform plan -destroy -var-file terraform.tfvars -out terraform.tfplan
terraform apply terraform.tfplan
我可能倾向于让一个目标运行
terraform get
,也配置远程状态,但现在设置起来应该很简单。另一个解决方案是在每次运行时创建一个tmp文件夹,并使用terraform init…
和terraform get…
,如下所示(该示例还显示了使用部分配置的远程状态管理):
或者将上面的代码包装成一个shell脚本,并从makefile的“apply”下调用它
--添加此部分以解决Sam Hammamy的评论/问题--
总的来说,对于当前版本的terraform处理项目的方式,我们确实希望提前思考如何构建我们的项目,以及如何将它们分解为可管理的、仍然具有功能的部分。这就是为什么我们通常将它们分解为“基础性”的原因VPC、VPN、安全组、IAM策略、堡垒等项目与“db”、“web群集”等“功能性”项目相比,我们通常运行/部署/修改“基本”项目一次或偶尔一次,而“功能性”项目我们可能一天重新部署几次
这意味着,通过像这样对IaC代码进行分段,我们也将相应地对远程状态进行分段,并执行项目部署
对于反映“理念”的项目结构,我们通常以类似的项目结构结束(未显示常见模块):
其中每个项目都是一个子文件夹,对于每个应用程序_name/env/component=文件夹(即dev/vpc),我们添加了一个占位符后端配置文件:backend.tf:
terraform {
backend "s3" {
}
}
其中,每个组件的文件夹内容将包含类似以下内容的文件:
make all plan # create stage plan
make all apply # apply stage plan
│ ├── prod
│ │ ├── vpc
│ │ │ ├── backend.tf
│ │ │ ├── main.tf
│ │ │ ├── outputs.tf
│ │ │ └── variables.tf
在“application\u name/”或“application\u name/env”级别,我们添加了一个backend.config文件,其内容如下:
bucket = "BUCKET_NAME"
region = "region_name"
lock = true
lock_table = "lock_table_name"
encrypt = true
我们的包装器shell脚本需要参数应用程序名称、环境、组件和实际运行的terraform cmd
run-tf.sh脚本的内容(简化):
下面是典型的run-tf.sh调用(从Makefile执行)的样子:
另一种解决方案是在每次运行时创建一个tmp文件夹,并使用
terraform init…
和terraform get…
,如下所示(该示例还显示了使用部分配置的远程状态管理):
或者将上面的代码包装成一个shell脚本,并从makefile的“apply”下调用它
--添加此部分以解决Sam Hammamy的评论/问题--
总的来说,对于当前版本的terraform处理项目的方式,我们确实希望提前思考如何构建我们的项目,以及如何将它们分解为可管理的、仍然具有功能的部分。这就是为什么我们通常将它们分解为“基础的”“VPC、VPN、安全组、IAM策略、堡垒等项目与“db”、“web群集”等“功能性”项目相比,我们通常会运行/部署/修改“基本”项目一次或偶尔一次,而“功能性”项目则可能一天重新部署几次
这意味着,通过像这样对IaC代码进行分段,我们也将相应地对远程状态进行分段,并执行项目部署
对于反映“理念”的项目结构,我们通常以类似的项目结构结束(未显示常见模块):
其中每个项目都是一个子文件夹,对于每个应用程序_name/env/component=文件夹(即dev/vpc),我们添加了一个占位符后端配置文件:backend.tf:
terraform {
backend "s3" {
}
}
其中,每个组件的文件夹内容将包含类似以下内容的文件:
make all plan # create stage plan
make all apply # apply stage plan
│ ├── prod
│ │ ├── vpc
│ │ │ ├── backend.tf
│ │ │ ├── main.tf
│ │ │ ├── outputs.tf
│ │ │ └── variables.tf
在“application\u name/”或“application\u name/env”级别,我们添加了一个backend.config文件,其内容如下:
bucket = "BUCKET_NAME"
region = "region_name"
lock = true
lock_table = "lock_table_name"
encrypt = true
我们的包装器shell脚本需要参数应用程序名称、环境、组件和实际运行的terraform cmd
run-tf.sh脚本的内容(简化):
下面是典型的run-tf.sh调用(从Makefile执行)的样子:
远程状态如何以这种方式包含所有组件?在每次应用
terraform
后,远程状态都会更新。因此,如果您正在保存$project\u path,子目录如何包含在此状态中?我在上面添加了一个新的部分,以详细介绍示例,解释每个子项目的远程状态管理,以及