はじめに
terraform importコマンドを使ったことがなかったので、使ってみます。
マネジメントコンソール上で作成したリソースを、import後、destroyしてみようとおもいます。
やってみた
1. 作業ディレクトリとtfファイルを準備する
tfファイルのセットアップを行います。
import-test/
├── main.tf
├── config.tf
└── variables.tf
main.tfを適当に用意します。
############################################################################
## terraformブロック
############################################################################
terraform {
# Terraformのバージョン指定
required_version = "~> 1.7.0"
# Terraformのaws用ライブラリのバージョン指定
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.33.0"
}
}
}
############################################################################
## providerブロック
############################################################################
provider "aws" {
# リージョンを指定
region = "ap-northeast-1"
}
2. importコマンドを実行する
importコマンドを実行するための準備を行います。
Tarraformの公式ドキュメントページへ移動します。
検索窓からAWS config周りのリソースを検索します。
レコーダーリソースのページへ移動します。
importコマンドに関するリファレンスがページ末尾にあることが分かります。
ページ末尾の記載を確認します。
terraform import aws_config_configuration_recorder.${リソースブロック名} ${レコーダーの名前}
でimportできそうです。
レコーダーの名前が分からないので、aws cliをつかって、レコーダーの名前を確認します。
awscliのドキュメントページへ移動します。
検索したりLLMと対話したりしてコマンドを発見します。
実行すると、以下の通り、レコーダーの情報が取得できます。
$ aws configservice describe-configuration-recorders
{
"ConfigurationRecorders": [
{
"name": "default",
"roleARN": "arn:aws:iam::123456789012:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig",
"recordingGroup": {
"allSupported": false,
"includeGlobalResourceTypes": false,
"resourceTypes": [
"AWS::S3::Bucket"
]
}
}
]
}
defaultと名付けられているものがマネジメントコンソールから作成したレコーダーです。
レコーダーの名前が取得できたので、importコマンドを実行してみます。
$ terraform import aws_config_configuration_recorder.default default
aws_config_configuration_recorder.default: Importing from ID "default"...
aws_config_configuration_recorder.default: Import prepared!
Prepared aws_config_configuration_recorder for import
aws_config_configuration_recorder.default: Refreshing state... [id=default]
Import successful!
The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.
importが完了しました!
These resources are now in
your Terraform state and will henceforth be managed by Terraform.
とあるように、importしたリソースがstateの管理下に加わったようです。
3. リソースブの設定をリソースブロックへ転記する
importしたリソース(レコーダー)のブロックを記載していないため、tfファイルに記載します。
tfファイルにimportしたリソースを定義する場合は、terraform state show
コマンドが便利です。
コマンドを実行することで、以下のような結果が得られます。
$ terraform state show aws_config_configuration_recorder.default
# aws_config_configuration_recorder.default:
resource "aws_config_configuration_recorder" "default" {
id = "default"
name = "default"
role_arn = "arn:aws:iam::123456789012:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig"
recording_group {
all_supported = false
include_global_resource_types = false
resource_types = [
"AWS::S3::Bucket",
]
exclusion_by_resource_types {
resource_types = []
}
recording_strategy {
use_only = "INCLUSION_BY_RESOURCE_TYPES"
}
}
}
importしたリソースのattributesが取得できます。
これをそのままconfig.tfへ転記するのですが、以下のように少し変更します。
resource "aws_config_configuration_recorder" "default" {
+ # id = "default" # 不要なので削除
- id = "default"
name = "default"
+ role_arn = var.config_service_role_arn # べた書き回避
- role_arn = "arn:aws:iam::123456789012:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig"
recording_group {
all_supported = false
include_global_resource_types = false
resource_types = [
"AWS::S3::Bucket",
]
exclusion_by_resource_types {
resource_types = []
}
recording_strategy {
use_only = "INCLUSION_BY_RESOURCE_TYPES"
}
}
}
tfファイルに問題がないか、planを実行し確認してみます。
$ terraform plan
aws_config_configuration_recorder.default: Refreshing state... [id=default]
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.
問題なくimport&整合しているtfファイルの作成が完了しました!
4. 周辺リソースを確認し、同様にimportする
terraformやaws cliのドキュメントを見ると分かるように、AWS Configはレコーダー、配信チャンネル、configルールがそれぞれ別リソースとして独立しています。
同時に削除するために、レコーダーと同様にimportしていきます。
手順はレコーダーと同様なのでコマンドのみ記載しておきます。
// 配信チャンネル一覧を表示
aws configservice describe-delivery-channels
// 配信チャンネルをstateへimport
terraform import aws_config_delivery_channel.default default
// 配信チャンネルリソースのattributeを表示
terraform state show aws_config_delivery_channel.default
// configルール一覧を表示
aws configservice describe-config-rules
// configルールをstateへimport
terraform import aws_config_config_rule.s3_public_prohibited s3-bucket-public-read-prohibited
// configルールリソースのattributeを表示
terraform state show aws_config_config_rule.s3_public_prohibited
最終的なconfig.tf
resource "aws_config_configuration_recorder" "default" {
name = "default"
role_arn = var.config_service_role_arn
recording_group {
all_supported = false
include_global_resource_types = false
resource_types = [
"AWS::S3::Bucket",
]
exclusion_by_resource_types {
resource_types = []
}
recording_strategy {
use_only = "INCLUSION_BY_RESOURCE_TYPES"
}
}
}
resource "aws_config_delivery_channel" "default" {
name = "default"
s3_bucket_name = "s3-config-history-test-xzdesnzvz"
sns_topic_arn = var.config_topic_arn
}
resource "aws_config_config_rule" "s3_public_prohibited" {
description = "Checks that your Amazon S3 buckets do not allow public read access. The rule checks the Block Public Access settings, the bucket policy, and the bucket access control list (ACL)."
maximum_execution_frequency = "TwentyFour_Hours"
name = "s3-bucket-public-read-prohibited"
tags = {}
tags_all = {}
evaluation_mode {
mode = "DETECTIVE"
}
scope {
compliance_resource_types = [
"AWS::S3::Bucket",
]
}
source {
owner = "AWS"
source_identifier = "S3_BUCKET_PUBLIC_READ_PROHIBITED"
}
}
レコーダー同様、plan結果を確認し、問題なければ進みます。
$ terraform plan
aws_config_configuration_recorder.default: Refreshing state... [id=default]
aws_config_delivery_channel.default: Refreshing state... [id=default]
aws_config_config_rule.s3_public_prohibited: Refreshing state... [id=s3-bucket-public-read-prohibited]
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.
5. destroyする
terraformでリソースを作成した場合と同様、サクッとdestroyします。
$ terraform destroy
Enter a value: yes
aws_config_configuration_recorder.default: Destroying... [id=default]
aws_config_configuration_recorder.default: Destruction complete after 1s
aws_config_delivery_channel.default: Destroying... [id=default]
aws_config_config_rule.s3_public_prohibited: Destroying... [id=s3-bucket-public-read-prohibited]
aws_config_delivery_channel.default: Destruction complete after 1s
aws_config_config_rule.s3_public_prohibited: Still destroying... [id=s3-bucket-public-read-prohibited, 10s elapsed]
aws_config_config_rule.s3_public_prohibited: Still destroying... [id=s3-bucket-public-read-prohibited, 20s elapsed]
aws_config_config_rule.s3_public_prohibited: Still destroying... [id=s3-bucket-public-read-prohibited, 30s elapsed]
aws_config_config_rule.s3_public_prohibited: Still destroying... [id=s3-bucket-public-read-prohibited, 40s elapsed]
aws_config_config_rule.s3_public_prohibited: Still destroying... [id=s3-bucket-public-read-prohibited, 50s elapsed]
aws_config_config_rule.s3_public_prohibited: Still destroying... [id=s3-bucket-public-read-prohibited, 1m0s elapsed]
aws_config_config_rule.s3_public_prohibited: Destruction complete after 1m5s
Destroy complete! Resources: 3 destroyed.
コマンドが問題なく実行されました。
マネコンからAWS Configの状況を確認してみます。
良い感じですね。
おわりに
以前から気になっていたterraform importコマンドを試してみました。
手軽に削除するなら、aws cliでも削除自体は可能ですが、
terraformを用いることで、
- terraformの公式ドキュメントを経由することで、関連リソースなども同時に確認できる
- terraformで管理する際のattributeが確認できる
などのメリットがあると思います。
初めて触るリソースは、マネコンから作成 > terraform import > terraformのドキュメントを読む、、、
のような学習方法もありかなと思いました!