#amazon-web-services #import #terraform #terraform-provider-aws #terraform0.12
#amazon-web-services #импорт #terraform #terraform-provider-aws #terraform0.12
Вопрос:
Некоторая информация: у нас есть код terraform для создания различных ресурсов AWS. Некоторые из этих ресурсов создаются для каждой учетной записи AWS и, следовательно, структурированы для хранения в account-scope
папке в нашем проекте. Это было, когда у нас был только один регион AWS. Теперь наше приложение сделано мультирегиональным, и, следовательно, эти ресурсы должны создаваться для каждого региона для каждой учетной записи AWS.
Для этого мы переместили эти сценарии TF в region-scope
папку, которая будет выполняться для каждого региона. Поскольку эти ресурсы больше не являются частью «области действия учетной записи», мы удалили их из состояния Terraform области действия учетной записи. Теперь, когда я пытаюсь импортировать эти ресурсы
Импортировал ресурсы, запустив это из 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:
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
Но вывод плана terraform показывает Plan: 6 to add, 0 to change, 5 to destroy.
, что эти ресурсы будут уничтожены и воссозданы.
Я не понимаю, почему так, я что-то упускаю и не делаю это правильно?
Пожалуйста, обратите внимание, что мы храним удаленное состояние в корзине S3, но в настоящее время у меня нет файла состояния удаленного TF, созданного в корзине S3 для области региона (хотя у меня есть один для области учетной записи). Я ожидал, что Import..Plan..Apply
процесс также создаст его для области области.
РЕДАКТИРОВАТЬ: я вижу файл состояния удаленного TF, созданный в области S3 для региона после запуска импорта. Одно из различий, которое я вижу между этим новым файлом состояния 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
РЕДАКТИРОВАТЬ 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 (СЛЕВА) и старой учетной записи (СПРАВА) для cloudtrail_bucket_suffix
:
Комментарии:
1. план должен указать вам причину воссоздания. например, какие изменения вызывают их. можете ли вы опубликовать результаты плана?
2. @mariux, спасибо, что проверили это. Я добавил фрагмент моего плана терраформирования. Пожалуйста, дайте мне знать, если вам нужны какие-либо другие подробности.
3. Итак, исходя из вашего комментария, означает ли это, что то, что я импортировал (то есть фактические ресурсы в aws), отличается от того, что представляют мои сценарии terraform?
4. @mariux Также хочу упомянуть, что у меня есть некоторые изменения в коде для обновления TF с версии
0.11
до0.12.29
.5. спасибо за добавление, у меня может быть подсказка.. смотрите мой ответ
Ответ №1:
В плане показано различие в имени корзины ( bucket
принудительная замена).
Это запускает воссоздание самого корзины и зависимых ресурсов.
Вам нужно перевести имя корзины в стабильное состояние, тогда все остальное также будет стабильным. Поскольку вы используете случайный суффикс для имени корзины, я подозреваю, что вы забыли импортировать это. random_id
Ресурс разрешает импорт, подобный этому:
terraform import module.buckets.random_id.cloudtrail_bucket_suffix cqLFzQ
Редактировать:
Однако вам нужно будет удалить keepers
, поскольку они запускают замену random_id
ресурса. keepers
используются для запуска восстановления зависимых ресурсов при изменении других ресурсов.
Я предполагаю, что это не то, что вы хотите для своих сегментов, поскольку определенные вами хранители кажутся стабильными / статичными: account_id
и env
оба вряд ли изменятся для этого развертывания. Если они вам действительно нужны, вы можете попытаться манипулировать состоянием вручную.
Комментарии:
1. Спасибо Мариуксу. Да, мы используем random_id, и я уже импортировал его. Это:
terraform import module.buckets.random_id.cloudtrail_bucket_suffix cqLFzQ
2. Я добавил полный
terraform import
иterraform plan
вывод для справки. Пожалуйста, посмотрите мой обновленный вопрос.3. извините.. да, пропустил это… смотрите мою обновленную версию.. хранители должны быть удалены .. если они вам действительно нужны, я мог бы попробовать трюк, который мы когда-то использовали для клиента… никогда не пробовал использовать random_id…
4. Я хочу сохранить
keepers
. Когда вы говорите «трюк», вы имеете в виду обновление текущего файла состояния удаленного TF, чтобы иметьkeeepers
и т. Д.? Я добавил разницу между текущим удаленным состоянием и тем, что было, когда этот ресурс был частью account-scope . Пожалуйста, проверьте5. Из-за случайного характера ресурса наша последовательность импорта для другого ресурса не сработала. Поэтому единственный способ, который я вижу здесь, — это манипулировать состоянием вручную и открыть проблему в репозитории поставщика для поддержки импорта хранителей. извините, что здесь нет лучших вариантов.