Terraform importを利用してAWSリソース(AWS Config)を削除してみた

# はじめに
terraform importコマンドを使ったことがなかったので、使ってみます。

マネジメントコンソール上で作成したリソースを、import後、destroyしてみようとおもいます。

## やってみた

### 1. 作業ディレクトリとtfファイルを準備する
tfファイルのセットアップを行います。

```
import-test/
├── main.tf
├── config.tf
└── variables.tf
```

main.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の公式ドキュメントページ](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication)へ移動します。

![cap1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/78dbc76f-e95a-b34f-74ce-222fd0bc3467.png)

検索窓からAWS config周りのリソースを検索します。

レコーダーリソースのページへ移動します。

![cap2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/053800f4-0b73-d32d-fd40-951b6f56e867.png)

importコマンドに関するリファレンスがページ末尾にあることが分かります。

ページ末尾の記載を確認します。

![cap3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/3ce04a31-4c6c-a0c0-9761-480f5da11de3.png)

```terraform import aws_config_configuration_recorder.${リソースブロック名} ${レコーダーの名前}```
でimportできそうです。

レコーダーの名前が分からないので、aws cliをつかって、レコーダーの名前を確認します。
[awscliのドキュメントページ](https://docs.aws.amazon.com/cli/latest/)へ移動します。

![cap4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/50aea4d0-1aba-7dd4-1a5b-61f34696c988.png)

![cap11.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/050d75ec-8258-fb80-0319-1198adc406fe.png)

検索したりLLMと対話したりしてコマンドを発見します。

![cap5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/41d10567-7417-8e98-e555-e163ca96aa30.png)

実行すると、以下の通り、レコーダーの情報が取得できます。

```console
$ 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コマンドを実行してみます。

```console
$ 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```コマンドが便利です。

https://developer.hashicorp.com/terraform/cli/commands/state/show

コマンドを実行することで、以下のような結果が得られます。
```console
$ 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へ転記するのですが、以下のように少し変更します。

```diff_hcl
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を実行し確認してみます。

```console
$ 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していきます。

手順はレコーダーと同様なのでコマンドのみ記載しておきます。
```bash
// 配信チャンネル一覧を表示
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
```

<details> <summary>最終的なconfig.tf</summary>

```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"
    }
}
```
</details>

レコーダー同様、plan結果を確認し、問題なければ進みます。
```console
$ 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します。

```console
$ 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の状況を確認してみます。

![cap10.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/474d2ac7-15bf-5310-c6b2-396b4214df74.png)

良い感じですね。

# おわりに
以前から気になっていたterraform importコマンドを試してみました。
手軽に削除するなら、aws cliでも削除自体は可能ですが、
terraformを用いることで、
- terraformの公式ドキュメントを経由することで、関連リソースなども同時に確認できる
- terraformで管理する際のattributeが確認できる

などのメリットがあると思います。

初めて触るリソースは、マネコンから作成 > terraform import >  terraformのドキュメントを読む、、、
のような学習方法もありかなと思いました！