Mul*_*ule 17 terraform terraform-provider-gcp
Terraform 有没有办法在尝试创建资源之前检查 Google Cloud 中的资源是否存在?
我想检查作业期间我的 CircleCI CI/CD 管道中是否存在以下资源。我可以访问终端命令、bash 和 gcloud 命令。如果资源确实存在,我想使用它们。如果它们不存在,我想创建它们。我在 CircleCI 的 config.yml 中执行此逻辑,作为我可以访问终端命令和 bash 的步骤。我的目标是在需要时在 GCP 中创建必要的基础设施(资源),否则在创建后使用它们,而不会在 CI/CD 构建中出现 Terraform 错误。
如果我尝试创建已存在的资源,Terraform apply 将导致错误,提示“您已经拥有此资源”,现在我的 CI/CD 作业失败。
下面是描述我想要获取的资源的伪代码。
resource "google_artifact_registry_repository" "main" {
# this is the repo for hosting my Docker images
# it does not have a data source afaik because it is beta
}
Run Code Online (Sandbox Code Playgroud)
对于我的google_artifact_registry_repository资源。我的一种方法是使用数据源块执行 Terraform 应用并查看是否返回值。问题在于 google_artifact_registry_repository 没有数据源块。因此,我必须使用资源块创建此资源一次,之后的每个 CI/CD 构建都可以依赖它的存在。有没有解决方法可以读取它的存在?
resource "google_storage_bucket" "bucket" {
# bucket containing the folder below
}
resource "google_storage_bucket_object" "content_folder" {
# folder containing Terraform default.tfstate for my Cloud Run Service
}
Run Code Online (Sandbox Code Playgroud)
对于我的google_storage_bucket和google_storage_bucket_object资源。如果我使用数据源块执行 Terraform 应用来查看这些是否存在,我遇到的一个问题是当找不到资源时,Terraform 需要永远返回该状态。如果我能够在 10-15 秒之内确定资源是否存在,并且如果不存在则假设这些资源不存在,那就太好了。
data "google_storage_bucket" "bucket" {
# bucket containing the folder below
}
output bucket {
value = data.google_storage_bucket.bucket
}
Run Code Online (Sandbox Code Playgroud)
当资源存在时,我可以使用 Terraform 输出存储桶来获取该值。如果不存在,Terraform 需要很长时间才能返回响应。对此有什么想法吗?
感谢 Marcin 的建议,我有一个工作示例,说明如何解决使用 Terraform 的外部数据源检查 GCP 中是否存在资源的问题检查 GCP 中是否存在资源的问题。这是一种有效的方法。我确信还有其他方法。
我有一个 CircleCI config.yml,其中有一份使用运行命令和 bash 的工作。在 bash 中,我将初始化/应用一个 Terraform 脚本来检查我的资源是否存在,如下所示。
data "external" "get_bucket" {
program = ["bash","gcp.sh"]
query = {
bucket_name = var.bucket_name
}
}
output "bucket" {
value = data.external.get_bucket.result.name
}
Run Code Online (Sandbox Code Playgroud)
然后在我的 gcp.sh 中,我使用 gsutil 来获取我的存储桶(如果存在)。
#!/bin/bash
eval "$(jq -r '@sh "BUCKET_NAME=\(.bucket_name)"')"
bucket=$(gsutil ls gs://$BUCKET_NAME)
if [[ ${#bucket} -gt 0 ]]; then
jq -n --arg name "" '{name:"'$BUCKET_NAME'"}'
else
jq -n --arg name "" '{name:""}'
fi
Run Code Online (Sandbox Code Playgroud)
然后在我的 CircleCI config.yml 中,我将它们放在一起。
terraform init
terraform apply -auto-approve -var bucket_name=my-bucket
bucket=$(terraform output bucket)
Run Code Online (Sandbox Code Playgroud)
此时,我检查是否返回了存储桶名称,并根据该名称确定如何继续。
| 归档时间: |
|
| 查看次数: |
59612 次 |
| 最近记录: |