我有一个Terraform项目布局,类似于
stage
└ Makefile
└ terraform.tfvars
└ vpc
└ services
└ frontend-app
└ backend-app
└ vars.tf
└ outputs.tf
└ main.tf
└ data-storage
└ mysql
└ redis其中Makefile的内容类似于
.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发布于 2017-03-30 03:33:40
另一种解决方案可以是在每次运行时创建一个tmp文件夹,并使用terraform init ...和terraform get...,如下所示(该示例还显示了使用部分配置进行远程状态管理):
readonly orig_path=$(pwd) && \
mkdir tmp && \
cd tmp && \
terraform init -backend=true -backend-config="$tf_backend_config" -backend-config="key=${account}/${envir}/${project}.json" $project_path && \
terraform get $project_path && \
terraform apply && \
cd $orig_path && \
rm -fR tmp或者将上面的内容包装到一个shell脚本中,然后从make文件中调用它,在"apply“下面。
--添加本节以解决Sam的评论/问题--
一般来说,用当前版本的terraform处理项目的方式,我们确实希望提前思考如何构建我们的项目,以及如何将它们分解为可管理的、仍然具有功能的部分。这就是为什么我们通常将它们分解成“基础”项目,如VPC、VPN、SecurityGroups、IAM-策略、堡垒等,而'functional“如"db”、“web-集群”等,我们通常只运行一次或偶尔地运行/部署/修改“基本”部分,而“功能”部分可能每天重新部署几次。
这意味着,随着IaC代码的碎片化,我们也将相应地分割远程状态,并执行我们的项目部署。
对于反映“哲学”的项目结构,我们通常会得到类似于此的项目结构(未显示通用模块):
├── projects
│ └── application-name
│ ├── dev
│ │ ├── bastion
│ │ ├── db
│ │ ├── vpc
│ │ └── web-cluster
│ ├── prod
│ │ ├── bastion
│ │ ├── db
│ │ ├── vpc
│ │ └── web-cluster
│ └── backend.config
└── run-tf.sh对于每个项目都是一个子文件夹,对于每个application_name/env/component =文件夹(即dev/vpc),我们添加了一个占位符后端配置文件:backend.tf
terraform {
backend "s3" {
}
}其中每个组件的文件夹内容将包含类似于以下内容的文件:
│ ├── prod
│ │ ├── vpc
│ │ │ ├── backend.tf
│ │ │ ├── main.tf
│ │ │ ├── outputs.tf
│ │ │ └── variables.tf在"application_name/“或"application_name/env”级别,我们添加了一个backend.config文件,其中包含一个内容:
bucket = "BUCKET_NAME"
region = "region_name"
lock = true
lock_table = "lock_table_name"
encrypt = true我们的包装外壳脚本期望参数应用程序-名称、环境、组件和实际的terraform运行。
run-tf.sh脚本(简化)的内容:
#!/bin/bash
application=$1
envir=$2
component=$3
cmd=$4
tf_backend_config="root_path/$application/$envir/$component/backend.config"
terraform init -backend=true -backend-config="$tf_backend_config" -backend-config="key=tfstate/${application}/${envir}/${component}.json"
terraform get
terraform $cmd下面是一个典型的run-tf.sh调用的样子(从Makefile执行):
$ run-tf.sh application_name dev vpc plan
$ run-tf.sh application_name prod bastion apply发布于 2017-03-28 14:48:39
我们使用shell脚本来处理这个精确的用例,它更好地处理cd。
但是,可以通过使用环境变量或直接在命令行中设置Make变量来设置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并配置远程状态的目标,但是现在设置这个目标应该很简单。
https://stackoverflow.com/questions/43071798
复制相似问题