3

我的 terraform 根目录中有 3 个 .tf 文件:

  • vpc.tf
  • 子网.tf
  • 实例.tf
  • 连同运行 terraform init 后的 .terraform 目录

我只想部署运行类似的 vpc.tf:

terraform apply vpc.tf #here, vpc.tf is a terraform file

但它不起作用(我收到一个 Go 错误:“zip:不是有效的 zip 文件”)。如果我只是跑

terraform apply

它将尝试在所有 3 个 terraform 文件(vpc.tf、subnets.tf 和 instances.tf)中应用所有配置,这不是我想要的。似乎让它工作的方法是,拥有一个完全不同的文件夹,然后运行类似的东西

terraform apply vpc/ #here, vpc/ is a folder that containers vpc.tf file

哪个有效。这种方法的问题在于,如果我在 vpc/ 文件夹中有 2 个或更多 terraform 文件,我会再次回到第一个问题。似乎解决方案是在特定文件夹中拥有特定资源,但这似乎并不干净,因为我可以预见,如果基础设施增长,我最终会得到几个包含一些 terraform 文件的文件夹。所以问题是:

有没有办法“terraform 应用”特定的 terraform 文件,而忽略文件夹中的所有其他文件?我错过了关于 terraform 的一些基本知识吗?

4

3 回答 3

3

虽然您可以按照manojlds 的回答-target中提到的方式使用每次运行时针对的特定资源,但这意味着当您发生一些奇怪的事情并且需要忽略将应用于其他资源的更改时那个区域。

Terraform 文档中-target直接提到了这一点:

此定位功能是为特殊情况提供的,例如从错误中恢复或解决 Terraform 限制。不建议将 -target 用于例行操作,因为这可能会导致未检测到的配置漂移和混淆资源的真实状态如何与配置相关。

相反,您应该考虑您愿意作为一个集合更改哪些内容,并将.tf应该作为一个单元更改的 Terraform 文件放在同一目录中,并为它们使用相同的状态文件。

如果您不希望同时更改两件事(例如,设置 VPC 并设置位于该 VPC 中的应用程序或设置应用程序的测试和生产版本),那么这些应该位于不同的目录中并使用不同的状态文件。

这提供了很好的事物分离,最小化爆炸半径,但仍然可以更容易地同时应用相关的事物块。

在您的特定情况下,我会质疑为什么您不想同时应用 VPC 和子网,因为这通常只是被视为运行事物所需的基本网络配置的一部分。一起管理这些通常会使很有意义,并且允许您更改 VPC 的名称以及重命名相同的子网之类的操作apply

于 2019-06-14T07:28:32.017 回答
0

不,很遗憾,Terraform没有应用特定 .tf 文件的功能。Terraform应用同一目录中的所有 .tf 文件

但是您可以应用带有注释取消注释的特定代码。例如,您在同一目录中有 2 个 .tf 文件“1st.tf”“2nd.tf”来为GCP(Google Cloud Platform)创建资源:

在此处输入图像描述

然后,“1st.tf”的代码如下:

provider "google" {
  credentials = file("myCredentials.json")
  project     = "myproject-113738"
  region      = "asia-northeast1"
}

resource "google_project_service" "project" {
  service = "iam.googleapis.com"
  disable_dependent_services = true
}

“2nd.tf”的代码如下:

resource "google_service_account" "service_account_1" {
  display_name = "Service Account 1"
  account_id   = "service-account-1"
}

resource "google_service_account" "service_account_2" {
  display_name = "Service Account 2"
  account_id   = "service-account-2"
}

现在,首先,您只想应用“1st.tf”中的代码,因此您需要注释掉“2nd.tf”中的代码:

1st.tf

provider "google" {
  credentials = file("myCredentials.json")
  project     = "myproject-113738"
  region      = "asia-northeast1"
}

resource "google_project_service" "project" {
  service = "iam.googleapis.com"
  disable_dependent_services = true
}

2nd.tf(注释掉)

# resource "google_service_account" "service_account_1" {
#   display_name = "Service Account 1"
#   account_id   = "service-account-1"
# }

# resource "google_service_account" "service_account_2" {
#   display_name = "Service Account 2"
#   account_id   = "service-account-2"
# }

然后,您申请:

terraform apply -auto-approve

接下来,另外,您要应用“2nd.tf”中的代码,因此您需要取消注释“2nd.tf”中的代码:

1st.tf

provider "google" {
  credentials = file("myCredentials.json")
  project     = "myproject-113738"
  region      = "asia-northeast1"
}

resource "google_project_service" "project" {
  service = "iam.googleapis.com"
  disable_dependent_services = true
}

2nd.tf(取消注释)

resource "google_service_account" "service_account_1" {
  display_name = "Service Account 1"
  account_id   = "service-account-1"
}

resource "google_service_account" "service_account_2" {
  display_name = "Service Account 2"
  account_id   = "service-account-2"
}

然后,您申请:

terraform apply -auto-approve

这样,您可以应用带有注释取消注释的特定代码

于 2022-01-31T23:41:15.870 回答
0

另一种选择,它不能解决您的确切需求,但可行的是使用-target参数进行资源定位,例如:

terraform plan -target digitalocean_loadbalancer.public -out run.plan

https://www.terraform.io/docs/commands/plan.html#resource-targeting

于 2019-06-14T05:23:47.123 回答