定位除 terraform 中的资源之外的所有资源(与“-target”参数相反)

JSe*_*ity 6 terraform terraform-provider-azure terraform0.12+

我的 terraform 配置至少管理 20 个资源,我想部署除一个之外的所有资源,我知道我可以添加“-target”参数,但我必须指定所有资源的名称(至少 20 个资源的名称) resources)以“-target”为目标对我来说这是一个问题,因为我经常在我的terraform配置中添加/删除资源,所以我需要是否有一个与“-target”相反的解决方案来仅指定一个资源应用 terraform 配置时被忽略。

PS:我不想删除我的资源配置被忽略

Hig*_*ife 10

目前 Terraform 中没有任何特性或功能可以让您在计划或应用中排除资源,这与 -target 标志相反 有一个开放功能请求(几年)来将此功能添加到地形。

与此同时,最好的替代方案之一是使用交换机控制您的资源。

resource "aws_instance" "example" {
  count = var.exclude_ec2_instance ? 0 : 1
  ... 
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用以下命令排除资源:

terraform plan -out=tfplan -var='exclude_ec2_instance=true'
Run Code Online (Sandbox Code Playgroud)


小智 1

目前无法在 terraform 中执行此操作。
这是bash我用作解决方法的脚本,您可能会感兴趣:

terraform-apply-exclude.bash

#!/usr/bin/env bash

WORKFILE=terraform-apply-exclude-cmd.bash
RESOURCE_TO_IGNORE="$1"

reset_workfile() {
  if [ -d $WORKFILE ]; then
    rm $WORKFILE
  fi
  echo "#!/usr/bin/env bash" > $WORKFILE
  echo "terraform apply \\" >> $WORKFILE
}
write_resources_to_apply_in_workfile() {
  local RESOURCES_TO_APPLY="$1"
  # Formatting to ensure the cmd will be runnable:
  # - Single quote around all resource paths
  # - Escape double quotes if any inside the squarebrakets
  echo -e "${RESOURCES_TO_APPLY//\"/\\\"}" | xargs -I {} echo " -target '{}'  \\" >> $WORKFILE
}

# Extract all the resources that would be updated, created or destroyed
RESOURCES_TO_APPLY=$(terraform plan -no-color | grep --color=never "  # " | grep -E --color=never 'will be updated|created|destroy|must be replaced' | awk -F' ' '{print $2}' )

reset_workfile

if [ -z "$RESOURCE_TO_IGNORE" ]; then
  echo "If you want to ignore 1 resource, use the following syntax:"
  echo "$0 \"terraform_path_of_the_resource_you_want_to_ignore\"."
  echo "No resource to ignore. Still putting result in '$WORKFILE'."
  echo "If you want to exclude more than 1 resource, you can manually edit the file '$WORKFILE' and then run it."
  write_resources_to_apply_in_workfile "$RESOURCES_TO_APPLY"
  exit 1;
fi
RESOURCE_TO_IGNORE=${RESOURCE_TO_IGNORE//\"/\\\"}
RESOURCE_TO_IGNORE=${RESOURCE_TO_IGNORE//[/\\[}  # ]] Fix syntaxing highlighting for code editor
RESOURCE_TO_IGNORE=${RESOURCE_TO_IGNORE//]/\\]} 
echo "Resource to ignore: $RESOURCE_TO_IGNORE"

RESOURCES_TO_APPLY=$(echo "$RESOURCES_TO_APPLY" | grep --color=never -E -v "$RESOURCE_TO_IGNORE")
write_resources_to_apply_in_workfile "$RESOURCES_TO_APPLY"
Run Code Online (Sandbox Code Playgroud)

使用它时,请确保转义"要排除的资源的路径内部。

它应该看起来像这样:

# Basic example, with no exclusion up-front (the easiest way, but a bit more manual)
$ bash terraform-apply-exclude.bash
$ <edit the 'terraform-apply-exclude-cmd.bash' file and remove the resource to exclude>
$ bash terraform-apply-exclude-cmd.bash

# Simple resource path example
$ bash terraform-apply-exclude.bash "aws_s3_bucket.bucket" 
$ bash terraform-apply-exclude-cmd.bash

# Example with a more complex setup, in this case, a module with a `for_each` meta-argument
$ bash terraform-apply-exclude.bash "module.buckets[\"vacation_pictures\"].aws_s3_bucket.bucket"
$ bash terraform-apply-exclude-cmd.bash
Run Code Online (Sandbox Code Playgroud)

如果您想知道为什么如此复杂,并且您还不知道countfor_each,这就是 bash 字符串解析的原因。


另外,如果您遇到错误,可能是因为我们没有运行相同的bash,grep和/或awk版本。这是我正在运行的版本:

  • 重击:GNU bash, version 5.2.2(1)-release (x86_64-pc-linux-gnu)
  • awk:GNU Awk 5.1.0, API: 3.0 (GNU MPFR 4.1.0, GNU MP 6.2.1)
  • 格列普:grep (GNU grep) 3.8