[英]Terraform plan shows differences after importing the aws resources
這是我原始問題的后續問題: Terraform (0.12.29) import not working as expected; 導入成功,但計划顯示銷毀和重新創建
一些背景:我們有 terraform 代碼來創建各種 AWS 資源。 其中一些資源是按 AWS 賬戶創建的,因此結構化為存儲在我們項目的賬戶范圍文件夾中。 當時我們只有一個 AWS 區域。 現在我們的應用程序是多區域的,因此將為每個 AWS 賬戶按區域創建這些資源。
為了做到這一點,我們現在將這些 TF 腳本移動到 region-scope 文件夾,該文件夾將按區域運行。 由於這些資源不再是“帳戶范圍”的一部分,我們已將它們從帳戶范圍 Terraform 狀態中刪除。 現在,當我嘗試將這些資源導入region scope
我的導入(從 xyz-region-scope 目錄運行)和 terraform 計划:
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"
mycompanymachine: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.module.access_logging_bucket.data.template_file.dependencies: Refreshing state...
module.buckets.data.template_file.dependencies: Refreshing state...
data.aws_caller_identity.current: Refreshing state...
module.buckets.module.access_logging_bucket.data.aws_caller_identity.current: Refreshing state...
module.encryption.module.data_key.data.aws_kms_alias.default: Refreshing state...
module.buckets.data.aws_caller_identity.current: Refreshing state...
module.encryption.module.data_key.data.aws_region.current: Refreshing state...
module.encryption.module.data_key.data.aws_caller_identity.current: Refreshing state...
module.buckets.module.access_logging_bucket.data.aws_kms_alias.encryption_key_alias: Refreshing state...
module.buckets.module.access_logging_bucket.random_id.bucket_suffix: Refreshing state... [id=nY6U_w]
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.module.access_logging_bucket.data.template_file.encryption_configuration: Refreshing state...
module.encryption.module.data_key.data.aws_iam_policy_document.encrypt: Refreshing state...
module.encryption.module.data_key.data.aws_iam_policy_document.decrypt: Refreshing state...
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.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
~ update in-place
<= 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 = [
+ "arn:aws:s3:::ab-xyz-stage-cloudtrail-logging-72a2c5cd",
]
+ sid = "AWSCloudTrailAclCheck"
+ principals {
+ identifiers = [
+ "cloudtrail.amazonaws.com",
]
+ type = "Service"
}
}
+ statement {
+ actions = [
+ "s3:PutObject",
]
+ effect = "Allow"
+ resources = [
+ "arn:aws:s3:::ab-xyz-stage-cloudtrail-logging-72a2c5cd/*",
]
+ 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 will be updated in-place
~ resource "aws_s3_bucket" "cloudtrail_logging_bucket" {
+ acl = "private"
arn = "arn:aws:s3:::ab-xyz-stage-cloudtrail-logging-72a2c5cd"
bucket = "ab-xyz-stage-cloudtrail-logging-72a2c5cd"
bucket_domain_name = "ab-xyz-stage-cloudtrail-logging-72a2c5cd.s3.amazonaws.com"
bucket_regional_domain_name = "ab-xyz-stage-cloudtrail-logging-72a2c5cd.s3.us-west-2.amazonaws.com"
+ force_destroy = false
hosted_zone_id = "Z3BJ6K6RIION7M"
id = "ab-xyz-stage-cloudtrail-logging-72a2c5cd"
region = "us-west-2"
request_payer = "BucketOwner"
tags = {
"mycompany:finance:accountenvironment" = "xyz-stage"
"mycompany:finance:application" = "ab-platform"
"mycompany:finance:billablebusinessunit" = "my-dev"
"name" = "Cloudtrail logging bucket"
}
lifecycle_rule {
abort_incomplete_multipart_upload_days = 0
enabled = true
id = "intu-lifecycle-s3-int-tier"
tags = {}
transition {
days = 32
storage_class = "INTELLIGENT_TIERING"
}
}
logging {
target_bucket = "ab-xyz-stage-access-logging-9d8e94ff"
target_prefix = "logs/cloudtrail-logging/"
}
versioning {
enabled = false
mfa_delete = false
}
}
# module.buckets.aws_s3_bucket_policy.cloudtrail_logging_bucket will be updated in-place
~ resource "aws_s3_bucket_policy" "cloudtrail_logging_bucket" {
bucket = "ab-xyz-stage-cloudtrail-logging-72a2c5cd"
id = "ab-xyz-stage-cloudtrail-logging-72a2c5cd"
~ 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.module.access_logging_bucket.aws_s3_bucket.default will be updated in-place
~ resource "aws_s3_bucket" "default" {
+ acl = "log-delivery-write"
arn = "arn:aws:s3:::ab-xyz-stage-access-logging-9d8e94ff"
bucket = "ab-xyz-stage-access-logging-9d8e94ff"
bucket_domain_name = "ab-xyz-stage-access-logging-9d8e94ff.s3.amazonaws.com"
bucket_regional_domain_name = "ab-xyz-stage-access-logging-9d8e94ff.s3.us-west-2.amazonaws.com"
+ force_destroy = false
hosted_zone_id = "Z3BJ6K6RIION7M"
id = "ab-xyz-stage-access-logging-9d8e94ff"
region = "us-west-2"
request_payer = "BucketOwner"
tags = {
"mycompany:finance:accountenvironment" = "xyz-stage"
"mycompany:finance:application" = "ab-platform"
"mycompany:finance:billablebusinessunit" = "my-dev"
"name" = "Access logging bucket"
}
- 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
}
}
versioning {
enabled = false
mfa_delete = false
}
}
Plan: 0 to add, 3 to change, 0 to destroy.
如您所見,terraform 計划輸出顯示計划:0 添加,3 更改,0 銷毀。
我的問題是:
aws_s3_bucket_policy
為cloudtrail_logging_bucket
即使有政策沒有變化。 請參閱下面的屏幕截圖和 TF 代碼cloudtrail_bucket.tf 。 cloudtrail_bucket_suffix 的舊帳戶范圍( LEFT )與我當前的遠程 TF 狀態( RIGHT )的 Diff 片段: module.buckets.data.aws_iam_policy_document.restrict_access_cloudtrail will be read during apply
的資源module.buckets.data.aws_iam_policy_document.restrict_access_cloudtrail will be read during apply
。 它顯示+
符號,這是否意味着它將在這里修改某些內容,或者只是按照它所說的閱讀它。module.buckets.module.access_logging_bucket.aws_s3_bucket.default will be updated in-place ~ resource "aws_s3_bucket" "default"
它消除了grant
和lifecycle_rule
。 見下面s3_bucket.tf
代碼:
cloudtrail_bucket.tf:
data "aws_caller_identity" "current" {}
resource "random_id" "cloudtrail_bucket_suffix" {
keepers = {
# Keep the suffix per account id / environment
aws_account_id = "${data.aws_caller_identity.current.account_id}"
env = "${var.environment}"
}
byte_length = "4"
}
resource "aws_s3_bucket" "cloudtrail_logging_bucket" {
bucket = "ab-${var.environment}-cloudtrail-logging-${random_id.cloudtrail_bucket_suffix.hex}"
acl = "private"
depends_on = [data.template_file.dependencies]
tags = {
name = "Cloudtrail logging bucket"
"mycompany:finance:accountenvironment" = "${var.environment}"
"mycompany:finance:application" = "${module.constants.finance_application}"
"mycompany:finance:billablebusinessunit" = "${module.constants.finance_billablebusinessunit}"
}
lifecycle {
ignore_changes = [ "server_side_encryption_configuration" ]
}
logging {
target_bucket = "${module.access_logging_bucket.name}"
target_prefix = "logs/cloudtrail-logging/"
}
lifecycle_rule {
enabled = "true"
transition {
days = 32
storage_class = "INTELLIGENT_TIERING"
}
}
}
resource "aws_s3_bucket_policy" "cloudtrail_logging_bucket" {
bucket = "${aws_s3_bucket.cloudtrail_logging_bucket.id}"
policy = "${data.aws_iam_policy_document.restrict_access_cloudtrail.json}"
}
data aws_iam_policy_document "restrict_access_cloudtrail" {
statement {
sid = "AWSCloudTrailAclCheck"
effect = "Allow"
actions = ["s3:GetBucketAcl"]
resources = [ "${aws_s3_bucket.cloudtrail_logging_bucket.arn}" ]
principals {
identifiers = ["cloudtrail.amazonaws.com"]
type = "Service"
}
}
statement {
sid = "AWSCloudTrailWrite"
effect = "Allow"
actions = ["s3:PutObject"]
resources = [ "${aws_s3_bucket.cloudtrail_logging_bucket.arn}/*" ]
principals {
identifiers = ["cloudtrail.amazonaws.com"]
type = "Service"
}
condition {
test = "StringEquals"
values = ["bucket-owner-full-control"]
variable = "s3:x-amz-acl"
}
}
}
s3_bucket.tf
resource "random_id" "bucket_suffix" {
keepers = {
# Keep the suffix per account id / environment
aws_account_id = "${data.aws_caller_identity.current.account_id}"
env = "${var.environment}"
}
byte_length = "${var.byte_length}"
}
resource "aws_s3_bucket" "default" {
bucket = "ab-${var.environment}-${var.name}-${random_id.bucket_suffix.hex}"
acl = "${var.acl}"
depends_on = [data.template_file.dependencies]
tags = {
name = "${var.name_tag}"
"mycompany:finance:accountenvironment" = "${var.environment}"
"mycompany:finance:application" = "${module.constants.finance_application}"
"mycompany:finance:billablebusinessunit" = "${module.constants.finance_billablebusinessunit}"
}
lifecycle {
ignore_changes = [ "server_side_encryption_configuration" ]
}
logging {
target_bucket = "${lookup(var.logging, "target_bucket", "ab-${var.environment}-${var.name}-${random_id.bucket_suffix.hex}")}"
target_prefix = "logs/${lookup(var.logging, "target_folder_name", "access-logging")}/"
}
}
我的環境:
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
如果 terraform-code 與導入的現有資源不同,則可能會顯示這種差異。 例如,如果有人在 AWS 管理控制台中通過單擊和指向更改了資源,而無需編輯/應用代碼。 terraform import 僅將資源導入 tfstate,但不會創建 terraform 代碼。
在此示例中,您可以在 AWS 控制台/cli 中驗證 S3 存儲桶“默認”是否確實配置了日志記錄。 根據計划,現有存儲桶未配置用於登錄 AWS,但您的 TF-code 包含此內容,因此將對其進行更改。
您確定您的 TF 代碼與導入資源的所有屬性完全匹配嗎?
為了進一步調查,您還需要發布相應的 tf 代碼。
只是回答我自己的問題,以便我可以提及我為每個問題所做的工作:
對於2nd question
它不會使用terraform apply
修改任何內容,而只是按照消息中的說明閱讀它。
對於我在此處單獨的 SO 線程中提出的3rd question
: Terraform - 更新 S3 訪問控制:關於用授權替換 acl 的問題並繼續我在那里的答案中提到的解決方案。
對於第1st question
,仍然不清楚為什么它會顯示差異。 我嘗試將現有狀態與terraform state pull
和檢查進行比較,為什么更新完成但沒有幫助。 但是運行terraform apply
進行得很好,它沒有對我期望的政策做出任何改變。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.