Terraform (0.12.29) 导入未按预期工作;导入成功,但计划显示销毁并重新创建

2024-01-07

一些背景:我们有 terraform 代码来创建各种 AWS 资源。其中一些资源是根据 AWS 账户创建的,因此被构造为存储在account-scope我们项目中的文件夹。当时我们只有一个 AWS 区域。现在我们的应用程序是多区域的,因此将为每个 AWS 账户的每个区域创建这些资源。

为此,我们现在已将这些 TF 脚本移至region-scope将按区域运行的文件夹。由于这些资源不再是‘账户范围’我们已将它们从帐户范围中删除地形状态。 现在当我尝试导入这些资源时

通过运行此命令导入资源xyz-region-scope目录:

terraform import -var-file=config/us-west-2/default.tfvars -var-file=variables.tfvars -var-file=../globals.tfvars -var profile=xyz-stage -var region=us-west-2 -var tfstate_bucket=ab-xyz-stage-tfstate-5b8873b8 -no-color <RESOURCE_NAME> <RESOURCE_ID>

资源的示例之一是:

RESOURCE_NAME=module.buckets.aws_s3_bucket.cloudtrail_logging_bucket 
RESOURCE_ID="ab-xyz-stage-cloudtrail-logging-72a2c5cd"

我期望导入会更新本地计算机上 terraform 状态文件中的资源,但在下创建的 terraform 状态文件xyz-region-scope/state/xyz-stage/terraform.tfstate没有更新。

通过以下方式验证进口:

terraform show

运行地形计划:

terraform plan -var-file=config/us-west-2/default.tfvars -var-file=variables.tfvars -var-file=../globals.tfvars -var profile=xyz-stage -var region=us-west-2 -var tfstate_bucket=ab-xyz-stage-tfstate-5b8873b8 -no-color

但地形计划输出显示Plan: 6 to add, 0 to change, 5 to destroy.也就是说,这些资源将被销毁并重新创建。

我不清楚为什么会这样,我是否遗漏了一些东西并且做得不对?

Please note we store the remote state in S3 bucket but I currently do not have the remote TF state file created in S3 bucket for region scope (I do have one for account scope though). I was expecting that the Import..Plan..Apply process will create one for region scope as well.

EDIT:我看到运行导入后在 S3 中为区域范围创建的远程 TF 状态文件。我发现这个新的区域范围 tf 状态文件与旧的帐户范围文件之间的一个区别是:新文件没有任何"depends_on"阻止在任何资源下resources[] > instances[]

环境:

Local machine: macOS v10.14.6

Terraform v0.12.29
+ provider.aws v3.14.1
+ provider.null v2.1.2
+ provider.random v2.3.1
+ provider.template v2.1.2


EDIT 2:

这是我的导入和地形计划:

terraform import module.buckets.random_id.cloudtrail_bucket_suffix cqLFzQ
terraform import module.buckets.aws_s3_bucket.cloudtrail_logging_bucket "ab-xyz-stage-cloudtrail-logging-72a2c5cd"
terraform import  module.buckets.aws_s3_bucket_policy.cloudtrail_logging_bucket "ab-xyz-stage-cloudtrail-logging-72a2c5cd"
terraform import  module.buckets.module.access_logging_bucket.aws_s3_bucket.default "ab-xyz-stage-access-logging-9d8e94ff"
terraform import  module.buckets.module.access_logging_bucket.random_id.bucket_suffix  nY6U_w
terraform import module.encryption.module.data_key.aws_iam_policy.decrypt "arn:aws:iam::123412341234:policy/ab_data_key_xyz_stage_decrypt"
terraform import module.encryption.module.data_key.aws_iam_policy.encrypt "arn:aws:iam::123412341234:policy/ab_data_key_xyz_stage_encrypt"



mymachine:xyz-region-scope kuldeepjain$ ../scripts/terraform.sh xyz-stage plan -no-color
+ set -o posix
+ IFS='
    '
++ blhome
+ BASH_LIB_HOME=/usr/local/lib/mycompany/ab/bash_library/0.0.1-SNAPSHOT
+ source /usr/local/lib/mycompany/ab/bash_library/0.0.1-SNAPSHOT/s3/bucket.sh
+ main xyz-stage plan -no-color
+ '[' 3 -lt 2 ']'
+ local env=xyz-stage
+ shift
+ local command=plan
+ shift
++ get_region xyz-stage
++ local env=xyz-stage
++ shift
+++ aws --profile xyz-stage configure get region
++ local region=us-west-2
++ '[' -z us-west-2 ']'
++ echo us-west-2
+ local region=us-west-2
++ _get_bucket xyz-stage xyz-stage-tfstate
++ local env=xyz-stage
++ shift
++ local name=xyz-stage-tfstate
++ shift
+++ _get_bucket_list xyz-stage xyz-stage-tfstate
+++ local env=xyz-stage
+++ shift
+++ local name=xyz-stage-tfstate
+++ shift
+++ aws --profile xyz-stage --output json s3api list-buckets --query 'Buckets[?contains(Name, `xyz-stage-tfstate`) == `true`].Name'
++ local 'bucket_list=[
    "ab-xyz-stage-tfstate-5b8873b8"
]'
+++ _count_buckets_in_json '[
    "ab-xyz-stage-tfstate-5b8873b8"
]'
+++ local 'json=[
    "ab-xyz-stage-tfstate-5b8873b8"
]'
+++ shift
+++ echo '[
    "ab-xyz-stage-tfstate-5b8873b8"
]'
+++ jq '. | length'
++ local number_of_buckets=1
++ '[' 1 == 0 ']'
++ '[' 1 -gt 1 ']'
+++ echo '[
    "ab-xyz-stage-tfstate-5b8873b8"
]'
+++ jq -r '.[0]'
++ local bucket_name=ab-xyz-stage-tfstate-5b8873b8
++ echo ab-xyz-stage-tfstate-5b8873b8
+ local tfstate_bucket=ab-xyz-stage-tfstate-5b8873b8
++ get_config_file xyz-stage us-west-2
++ local env=xyz-stage
++ shift
++ local region=us-west-2
++ shift
++ local config_file=config/us-west-2/xyz-stage.tfvars
++ '[' '!' -f config/us-west-2/xyz-stage.tfvars ']'
++ config_file=config/us-west-2/default.tfvars
++ echo config/us-west-2/default.tfvars
+ local config_file=config/us-west-2/default.tfvars
+ export TF_DATA_DIR=state/xyz-stage/
+ TF_DATA_DIR=state/xyz-stage/
+ terraform get
+ terraform plan -var-file=config/us-west-2/default.tfvars -var-file=variables.tfvars -var-file=../globals.tfvars -var profile=xyz-stage -var region=us-west-2 -var tfstate_bucket=ab-xyz-stage-tfstate-5b8873b8 -no-color
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

module.encryption.module.data_key.data.null_data_source.key: Refreshing state...
module.buckets.data.template_file.dependencies: Refreshing state...
module.buckets.module.access_logging_bucket.data.template_file.dependencies: Refreshing state...
module.encryption.module.data_key.data.aws_region.current: Refreshing state...
module.buckets.module.access_logging_bucket.data.aws_caller_identity.current: Refreshing state...
data.aws_caller_identity.current: Refreshing state...
module.buckets.module.access_logging_bucket.data.aws_kms_alias.encryption_key_alias: Refreshing state...
module.buckets.data.aws_caller_identity.current: Refreshing state...
module.encryption.module.data_key.data.aws_caller_identity.current: Refreshing state...
module.encryption.module.data_key.data.aws_kms_alias.default: Refreshing state...
module.buckets.module.access_logging_bucket.data.template_file.encryption_configuration: Refreshing state...
module.encryption.module.data_key.data.aws_iam_policy_document.decrypt: Refreshing state...
module.encryption.module.data_key.data.aws_iam_policy_document.encrypt: Refreshing state...
module.buckets.module.access_logging_bucket.random_id.bucket_suffix: Refreshing state... [id=nY6U_w]
module.encryption.module.data_key.aws_iam_policy.decrypt: Refreshing state... [id=arn:aws:iam::123412341234:policy/ab_data_key_xyz_stage_decrypt]
module.encryption.module.data_key.aws_iam_policy.encrypt: Refreshing state... [id=arn:aws:iam::123412341234:policy/ab_data_key_xyz_stage_encrypt]
module.buckets.module.access_logging_bucket.aws_s3_bucket.default: Refreshing state... [id=ab-xyz-stage-access-logging-9d8e94ff]
module.buckets.random_id.cloudtrail_bucket_suffix: Refreshing state... [id=cqLFzQ]
module.buckets.aws_s3_bucket.cloudtrail_logging_bucket: Refreshing state... [id=ab-xyz-stage-cloudtrail-logging-72a2c5cd]
module.buckets.data.aws_iam_policy_document.restrict_access_cloudtrail: Refreshing state...
module.buckets.aws_s3_bucket_policy.cloudtrail_logging_bucket: Refreshing state... [id=ab-xyz-stage-cloudtrail-logging-72a2c5cd]

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create
-/+ destroy and then create replacement
 <= read (data resources)

Terraform will perform the following actions:

  # module.buckets.data.aws_iam_policy_document.restrict_access_cloudtrail will be read during apply
  # (config refers to values not yet known)
 <= data "aws_iam_policy_document" "restrict_access_cloudtrail"  {
      + id   = (known after apply)
      + json = (known after apply)

      + statement {
          + actions   = [
              + "s3:GetBucketAcl",
            ]
          + effect    = "Allow"
          + resources = [
              + (known after apply),
            ]
          + sid       = "AWSCloudTrailAclCheck"

          + principals {
              + identifiers = [
                  + "cloudtrail.amazonaws.com",
                ]
              + type        = "Service"
            }
        }
      + statement {
          + actions   = [
              + "s3:PutObject",
            ]
          + effect    = "Allow"
          + resources = [
              + (known after apply),
            ]
          + sid       = "AWSCloudTrailWrite"

          + condition {
              + test     = "StringEquals"
              + values   = [
                  + "bucket-owner-full-control",
                ]
              + variable = "s3:x-amz-acl"
            }

          + principals {
              + identifiers = [
                  + "cloudtrail.amazonaws.com",
                ]
              + type        = "Service"
            }
        }
    }

  # module.buckets.aws_s3_bucket.cloudtrail_logging_bucket must be replaced
-/+ resource "aws_s3_bucket" "cloudtrail_logging_bucket" {
      + acceleration_status         = (known after apply)
      + acl                         = "private"
      ~ arn                         = "arn:aws:s3:::ab-xyz-stage-cloudtrail-logging-72a2c5cd" -> (known after apply)
      ~ bucket                      = "ab-xyz-stage-cloudtrail-logging-72a2c5cd" -> (known after apply) # forces replacement
      ~ bucket_domain_name          = "ab-xyz-stage-cloudtrail-logging-72a2c5cd.s3.amazonaws.com" -> (known after apply)
      ~ bucket_regional_domain_name = "ab-xyz-stage-cloudtrail-logging-72a2c5cd.s3.us-west-2.amazonaws.com" -> (known after apply)
      + force_destroy               = false
      ~ hosted_zone_id              = "Z3BJ6K6RIION7M" -> (known after apply)
      ~ id                          = "ab-xyz-stage-cloudtrail-logging-72a2c5cd" -> (known after apply)
      ~ region                      = "us-west-2" -> (known after apply)
      ~ request_payer               = "BucketOwner" -> (known after apply)
        tags                        = {
            "mycompany:finance:accountenvironment"   = "xyz-stage"
            "mycompany:finance:application"          = "ab-platform"
            "mycompany:finance:billablebusinessunit" = "my-dev"
            "name"                                = "Cloudtrail logging bucket"
        }
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)

      ~ lifecycle_rule {
          - abort_incomplete_multipart_upload_days = 0 -> null
            enabled                                = true
          ~ id                                     = "intu-lifecycle-s3-int-tier" -> (known after apply)
          - tags                                   = {} -> null

            transition {
                days          = 32
                storage_class = "INTELLIGENT_TIERING"
            }
        }

      - logging {
          - target_bucket = "ab-xyz-stage-access-logging-9d8e94ff" -> null
          - target_prefix = "logs/cloudtrail-logging/" -> null
        }
      + logging {
          + target_bucket = (known after apply)
          + target_prefix = "logs/cloudtrail-logging/"
        }

      ~ versioning {
          ~ enabled    = false -> (known after apply)
          ~ mfa_delete = false -> (known after apply)
        }
    }

  # module.buckets.aws_s3_bucket_policy.cloudtrail_logging_bucket must be replaced
-/+ resource "aws_s3_bucket_policy" "cloudtrail_logging_bucket" {
      ~ bucket = "ab-xyz-stage-cloudtrail-logging-72a2c5cd" -> (known after apply) # forces replacement
      ~ id     = "ab-xyz-stage-cloudtrail-logging-72a2c5cd" -> (known after apply)
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = "s3:GetBucketAcl"
                      - Effect    = "Allow"
                      - Principal = {
                          - Service = "cloudtrail.amazonaws.com"
                        }
                      - Resource  = "arn:aws:s3:::ab-xyz-stage-cloudtrail-logging-72a2c5cd"
                      - Sid       = "AWSCloudTrailAclCheck"
                    },
                  - {
                      - Action    = "s3:PutObject"
                      - Condition = {
                          - StringEquals = {
                              - s3:x-amz-acl = "bucket-owner-full-control"
                            }
                        }
                      - Effect    = "Allow"
                      - Principal = {
                          - Service = "cloudtrail.amazonaws.com"
                        }
                      - Resource  = "arn:aws:s3:::ab-xyz-stage-cloudtrail-logging-72a2c5cd/*"
                      - Sid       = "AWSCloudTrailWrite"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
    }

  # module.buckets.random_id.cloudtrail_bucket_suffix must be replaced
-/+ resource "random_id" "cloudtrail_bucket_suffix" {
      ~ b64         = "cqLFzQ" -> (known after apply)
      ~ b64_std     = "cqLFzQ==" -> (known after apply)
      ~ b64_url     = "cqLFzQ" -> (known after apply)
        byte_length = 4
      ~ dec         = "1923270093" -> (known after apply)
      ~ hex         = "72a2c5cd" -> (known after apply)
      ~ id          = "cqLFzQ" -> (known after apply)
      + keepers     = {
          + "aws_account_id" = "123412341234"
          + "env"            = "xyz-stage"
        } # forces replacement
    }

  # module.buckets.module.access_logging_bucket.aws_s3_bucket.default must be replaced
-/+ resource "aws_s3_bucket" "default" {
      + acceleration_status         = (known after apply)
      + acl                         = "log-delivery-write"
      ~ arn                         = "arn:aws:s3:::ab-xyz-stage-access-logging-9d8e94ff" -> (known after apply)
      ~ bucket                      = "ab-xyz-stage-access-logging-9d8e94ff" -> (known after apply) # forces replacement
      ~ bucket_domain_name          = "ab-xyz-stage-access-logging-9d8e94ff.s3.amazonaws.com" -> (known after apply)
      ~ bucket_regional_domain_name = "ab-xyz-stage-access-logging-9d8e94ff.s3.us-west-2.amazonaws.com" -> (known after apply)
      + force_destroy               = false
      ~ hosted_zone_id              = "Z3BJ6K6RIION7M" -> (known after apply)
      ~ id                          = "ab-xyz-stage-access-logging-9d8e94ff" -> (known after apply)
      ~ region                      = "us-west-2" -> (known after apply)
      ~ request_payer               = "BucketOwner" -> (known after apply)
        tags                        = {
            "mycompany:finance:accountenvironment"   = "xyz-stage"
            "mycompany:finance:application"          = "ab-platform"
            "mycompany:finance:billablebusinessunit" = "my-dev"
            "name"                                = "Access logging bucket"
        }
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)

      - grant {
          - permissions = [
              - "READ_ACP",
              - "WRITE",
            ] -> null
          - type        = "Group" -> null
          - uri         = "http://acs.amazonaws.com/groups/s3/LogDelivery" -> null
        }
      - grant {
          - id          = "0343271a8c2f184152c171b223945b22ceaf5be5c9b78cf167660600747b5ad8" -> null
          - permissions = [
              - "FULL_CONTROL",
            ] -> null
          - type        = "CanonicalUser" -> null
        }

      - lifecycle_rule {
          - abort_incomplete_multipart_upload_days = 0 -> null
          - enabled                                = true -> null
          - id                                     = "intu-lifecycle-s3-int-tier" -> null
          - tags                                   = {} -> null

          - transition {
              - days          = 32 -> null
              - storage_class = "INTELLIGENT_TIERING" -> null
            }
        }

      + logging {
          + target_bucket = (known after apply)
          + target_prefix = "logs/access-logging/"
        }

      ~ versioning {
          ~ enabled    = false -> (known after apply)
          ~ mfa_delete = false -> (known after apply)
        }
    }

  # module.buckets.module.access_logging_bucket.random_id.bucket_suffix must be replaced
-/+ resource "random_id" "bucket_suffix" {
      ~ b64         = "nY6U_w" -> (known after apply)
      ~ b64_std     = "nY6U/w==" -> (known after apply)
      ~ b64_url     = "nY6U_w" -> (known after apply)
        byte_length = 4
      ~ dec         = "2643367167" -> (known after apply)
      ~ hex         = "9d8e94ff" -> (known after apply)
      ~ id          = "nY6U_w" -> (known after apply)
      + keepers     = {
          + "aws_account_id" = "123412341234"
          + "env"            = "xyz-stage"
        } # forces replacement
    }

Plan: 6 to add, 0 to change, 5 to destroy.

我当前远程 TF 状态的差异片段(LEFT) 与旧帐户范围(RIGHT) for cloudtrail_bucket_suffix:


该计划显示了存储桶名称的差异(bucket强制更换)。

这会触发存储桶本身和相关资源的重新创建。

你需要让bucket name达到稳定的状态,那么其他的也就稳定了。由于您使用随机后缀作为存储桶名称,我怀疑您忘记导入它。这random_id资源允许像这样导入:

terraform import module.buckets.random_id.cloudtrail_bucket_suffix cqLFzQ

Edit:

但是,您需要删除keepers因为它们触发了更换random_id资源。keepers当其他资源发生变化时,用于触发依赖资源的重新创建。

我认为这不是您想要的存储桶,因为您定义的守护者似乎是稳定/静态的:account_id and env对于此部署,两者都不太可能改变。如果您确实需要它们,您可以尝试手动操纵状态。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Terraform (0.12.29) 导入未按预期工作;导入成功,但计划显示销毁并重新创建 的相关文章

随机推荐

  • 使用客户端 HTML 表排序对行进行分组

    是否有现有的表格排序库 或者有没有办法配置表格排序器 http tablesorter com docs 每两行排序 或者 是否有更好的方法来语义地表达我的表 以便标准行排序可以工作 我有一个 html 表 看起来像这样 table the
  • SBT 集成测试设置

    我想向我的 SBT Spray 应用程序添加集成测试阶段 理想情况下 它就像 Maven 一样 具有以下阶段 compile 应用程序已构建 test 单元测试已运行 pre integration test 应用程序在单独的进程中启动 i
  • 获取与 Leaflet 类关联的 DOM 元素

    有没有办法获取a对应的DOM元素Marker http leafletjs com reference html marker or Layer http leafletjs com reference html ilayer与传单 就像使
  • mySQL - 使用返回多行的选择更新多列

    我有一个邮政编码表 我想用它的 3 个最近邻居更新每个邮政编码 即填写此表中的空白 postcode nearestPostcode1 nearestPostcode2 nearestPostcode3 KY6 1DA KY6 1DG KY
  • 如何使用 TrueForAll

    我有一个布尔列表 我想检查是否每个列表都设置为 true 我可以运行一个循环并以这种方式检查它 但我想尝试这样做TrueForAll列表的方法 我需要一个谓词 但我找不到这样一个简单任务的明确示例 Use All http msdn mic
  • MDM:服务器 URL 的 ssl 问题

    我想使用Lion Server管理iOS设备 我购买了Lion Server并安装在具有Lion OS 10 7的Mac系统中 我想在我们自己的网络中管理设备 我没有为 MDM 采用特定的域 在 IPCU 中为 MDM 创建 cofig 配
  • 将数组的索引更改为所需的顺序问题

    您好 我有一个索引为 0 13 的数组 其键值为每个索引都有一个自己嵌套的数组 我希望能够将其顺序更改为 0 2 1 3 4 5 7 6 8 10 9 11 13 12 这是我的尝试 但它不起作用 var array 1 array id
  • Qt Windeployqt 导致部署不可用

    我在用着windeployqt可执行文件来准备我的安装树 该工具将所有必需的 甚至一些不必要的 dll 复制到指定文件夹中 并对 Qt5Core dll 进行硬编码路径变量的修补 以下是我执行该工具的方法 C Qt 5 11 2 mingw
  • Aurelia 中的数据绑定父子关系

    代码 我有两节课 export class Shipment shipmentId number widget Widget export class Widget widgetId number name string 然后我有一个Shi
  • SQLite.NET 和 SQL Server Compact 的优缺点

    我已经多次使用 SQLite NET 它总是工作得很好 但我有一个朋友一直纠缠我应该使用 SQL Server Compact 所以我完全留在 Microsoft 环境中 现在 我从未使用过 Compact 他告诉我这对他来说效果很好 但看
  • 使用 root 用户(= 存储桶所有者)在 aws s3 存储桶上设置存储桶策略时访问被拒绝

    我有一个 AWS root 用户 用于在 Amazon 上创建 S3 存储桶 现在我想通过添加以下策略来公开此存储桶 Version 2012 10 17 Statement Effect Allow Principal Action s3
  • ElasticSearch 边缘NGram

    我有以下设置和分析器 put tests settings analysis analyzer standardWithEdgeNGram tokenizer standard filter lowercase edgeNGram toke
  • 如何重新加载使用“from module import *”导入的python模块

    我看到在这个有用的问答 https stackoverflow com q 437589 4518341可以使用的reload whatever module 或者 在 Python 3 中 imp reload whatever modu
  • 使用 ID 获取 AmChart 实例 / AmCharts4 Angular-Typescript 中的所有图表

    之前我们使用 this AmCharts 获取它们 AmCharts为我们提供了AmChartsService 通过它我们可以获取dom中的所有图表 升级后获取页面中所有图表的新方法是什么 None
  • 如何在全日历中设置外部事件的持续时间

    我正在尝试将 fullcalendar 与外部事件一起使用 我按照拖放外部事件的示例进行操作 这正是我所需要的 并且示例很好 我可以拖动外部事件并将其放在日历上 它们被转化为事件 但问题是它们都是 60 分钟长 我想更改这个值 但我找不到如
  • Javascript 获取附加了处理程序的元素

    当在元素上触发 onclick 事件时 如何从事件对象中获取事件附加到的元素 与单击的 target 元素相对 您可以访问currentTarget财产 https developer mozilla org en US docs Web
  • 如何使用纯 Javascript 删除父元素

    如何使用纯 JavaScript 删除父元素和所有相应节点 我没有使用 jQuery 或任何其他库 换句话说 我有一个元素 当用户单击它时 我想删除父元素的父元素 以及相应的子节点 table tr td Mohit td td 23 td
  • 如何在Windows中正确构建opencv以获得“opencv_createsamples.exe”

    我想学习和使用 haarcascade 分类器 使用 OpenCV 来检测我选择的对象 我在网上搜索发现createsamples实用程序有助于创建正像和负像图像的数据集 我知道如何在 python 中安装 OpenCV pip insta
  • 将 firebase 添加到代号一

    我正在使用 Codename One 框架开发我的应用程序 并使用 Firebase 将我的数据存储在云中 为了利用 Firebase 的所有潜力 我想将其添加到我的应用程序中 但由于我没有使用 Android Studio 或 Xcode
  • Terraform (0.12.29) 导入未按预期工作;导入成功,但计划显示销毁并重新创建

    一些背景 我们有 terraform 代码来创建各种 AWS 资源 其中一些资源是根据 AWS 账户创建的 因此被构造为存储在account scope我们项目中的文件夹 当时我们只有一个 AWS 区域 现在我们的应用程序是多区域的 因此将