TerraformでS3リソースをインポートしてみた：②Terraform import block編

# やりたいこと
・手動で作成したS3リソースをterraformで管理したい 
　👇👇👇前回できたよ～

https://qiita.com/curlneko/items/ab317f0be0ee4b29a871


・AWSで事前に書いた3バケットポリシーをtfファイルに丸ごと取り込みたい　👈今回はここ

# 前提
・AWSアカウント作成済み
・AWS IAMユーザーを作成し、access_keyとsecret_keyを発行済み
・Terraformインストール済み
・AWS CLIインストール済み
・VSCODEインストール済み
　（お好みのエディターで大丈夫）

・AWSのほうで、手動でS3バケットとそのポリシーを作成済み
　（バケットポリシー以外の設定は、全部デポジットで大丈夫）

　バケット名を「terraform-test-import-20230828」にして、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/0eb9acf4-b5a9-9a8c-8dd2-073f6d49ed29.png)
　「IPアドレスのアクセス許可権限」に関するバケットポリシーを手動で設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/9f2780d8-b9b1-bdee-6bcb-df8a0493303e.png)

```ruby:バケットポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::terraform-test-import-20230828/*"
            ],
            "Condition": {
              "IpAddress": {"aws:SourceIp": "設定したいIP"},
              "NotIpAddress": {"aws:SourceIp": "設定したいIP"}
            }
        }
    ]
}
POLICY
}
```

:::note info
※補足
・バケットポリシーは今回の主役じゃないので、どうでもいい内容で大丈夫だけど、場合によって「ブロックパブリックアクセス (バケット設定)」が引っかかってうまく設定できないのがある

・特に「s3:GetObject」のallow権限は、ブロックパブリックアクセスが関連してるので避けたほうが無難かな。。。

・今回はブロックパブリックアクセス (バケット設定)が関わらない「IPアドレスのアクセス」ポリシーを選定
:::

# 環境
```
$ terraform -v 
Terraform v1.5.5
on windows_amd64
+ provider registry.terraform.io/hashicorp/aws v5.13.1
```

# ディレクトリ構成
```
root  　　   
  ┣━ main.tf
  ┣━ variables.tf
  ┣━ terraform.tfstate（Terraform実行により作成されたやつ）
  ┣━ terraform.tfstate.backup（Terraform実行により作成されたやつ）
  ┣━ import_block.tf（import blockのお試し）
  ┗━ s3.tf（import blockお試しにより作成されたやつ）
```

# ソースの中身
### main.tf
・main.tfには基本、全体共通で重要な設定、例えば「AWS プロバイダの設定」を書く
```ruby:main.tf
# AWS プロバイダの設定
provider "aws" {
  access_key = var.access_key
  secret_key = var.secret_key
  region     = var.region
}
```
### variables.tf
・variables.tfに全ソース共通の変数を書く
・リージョンは東京にしたが、適宜変更して大丈夫
・access_keyとsecret_keyは事前に発行したやつを使用
```ruby:variables.tf
variable "region" {
  default = "ap-northeast-1"
}

variable "access_key" {
  default = "自分のaccess_key"
}

variable "secret_key" {
  default = "自分のsecret_key"
}
```
### import_block.tf
・Terraform import blockのお試しファイル
```ruby:import_block.tf
import {
  id = "terraform-test-import-20230828" # リソースの識別子
  to = aws_s3_bucket.bucket             # ローカルのimport先
}

import {
  id = "terraform-test-import-20230828" # リソースの識別子
  to = aws_s3_bucket_policy.s3          # ローカルのimport先
}
```

# Terraformのimport blockを試してみる
前回は、terraform importでAWS側のS3リソースをローカルへimportし管理できるようになった！

しかし、また一つの課題があります。。。

`importしたS3リソースの内容は、自動でterraform.tfstateにしか書き込まれず、tfファイルにはずっと空っぽな状態。。。`

AWS側で設定したバケットポリシーを変更したい場合、
手動でterraform.tfstateファイルからバケットポリシー内容をtfファイルへコピペして編集するか、一からバケットポリシをtfファイルに書き込むかしないとダメ。。。なんか面倒くさい。。。

importした時点で、terraform.tfstateファイルとtfファイル両方へ書き込む方法はないかな？

**Terraform import block** の出番だ！！！

まず、AWSでS3バケットとそのバケットポリシが存在してることを確認しよう～
（前回は最後terraform destroyでリソースを削除したので、再作成を忘れないでね）

:::note warn
※注意
AWS側にリソースがない状態で進めると、import時は以下のエラーになるので気を付けてください
:::


```ruby:実行結果
Error: Cannot import non-existent remote object
```

ローカルでは、import_block.tfを用意したうえ、terraform planのコマンドを実行しよう

ここで、気をつけてほしいのはterraform importの実行は必要なくなって、代わりにterraform planだけでいいでした
```
terraform plan -generate-config-out='s3.tf'
```

-generate-config-out='s3.tf'を書くと、terraformはimport_block.tfに書かれてS3リソースのをローカルにインポートしたうえ、

terraform.tfstateにS3の状態を書き込み、s3.tfというtfをファイルを作成し、resourceを作ってくれるらしい！

:::note warn
※注意
terraform planだけでいいよ。terraform importの実行は不要だよ
:::
以下の結果が出たらimportが成功！

```ruby:実行結果
Plan: 2 to import, 0 to add, 0 to change, 0 to destroy.
```
VSCODEを確認すると、terraform.tfstateには書き込まれて、s3.tfも自動で作成された！！
```ruby:s3.tf
# __generated__ by Terraform
# Please review these resources and move them into your main configuration files.

# __generated__ by Terraform from "terraform-test-import-20230828"
resource "aws_s3_bucket_policy" "s3" {
  bucket = "terraform-test-import-20230828"
  policy = "{\"Statement\":[{\"Action\":\"s3:*\",\"Condition\":{\"IpAddress\":{\"aws:SourceIp\":\"54.240.143.0/24\"},\"NotIpAddress\":{\"aws:SourceIp\":\"54.240.143.188/32\"}},\"Effect\":\"Allow\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::terraform-test-import-20230828/*\",\"Sid\":\"\"}],\"Version\":\"2012-10-17\"}"
}

# __generated__ by Terraform from "terraform-test-import-20230828"
resource "aws_s3_bucket" "bucket" {
  bucket              = "terraform-test-import-20230828"
  bucket_prefix       = null
  force_destroy       = null
  object_lock_enabled = false
  tags                = {}
  tags_all            = {}
}

```
こんな感じで、バケットとバケットポリシをリソースが自動で書き込まれて便利！！

そして、前半と同様に、バケットにタグを入れて、バケットポリシにAllowからDenyへ、AWS側のS3リソースをいじってみよう～


```ruby:s3.tf
# __generated__ by Terraform
# Please review these resources and move them into your main configuration files.

# __generated__ by Terraform from "terraform-test-import-20230828"
resource "aws_s3_bucket_policy" "s3" {
  bucket = "terraform-test-import-20230828"
　#見づらいけど、Allow→Deny
  policy = "{\"Statement\":[{\"Action\":\"s3:*\",\"Condition\":{\"IpAddress\":{\"aws:SourceIp\":\"54.240.143.0/24\"},\"NotIpAddress\":{\"aws:SourceIp\":\"54.240.143.188/32\"}},\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::terraform-test-import-20230828/*\",\"Sid\":\"\"}],\"Version\":\"2012-10-17\"}"
}

# __generated__ by Terraform from "terraform-test-import-20230828"
resource "aws_s3_bucket" "bucket" {
  bucket              = "terraform-test-import-20230828"
  bucket_prefix       = null
  force_destroy       = null
  object_lock_enabled = false
  tags                = { Name = "test" } #ここでタグを追加
  tags_all            = {}
}

```
今度はplanだけでいい、-generate-config-outは要らないよ～
```
terraform plan 
```
以下が出たら成功
```ruby:実行結果
Plan: 2 to import, 0 to add, 2 to change, 0 to destroy.
```
そして、AWSへデプロイする
```
terraform apply 
```
```ruby:実行結果
Apply complete! Resources: 2 imported, 0 added, 2 changed, 0 destroyed.
```

最後、AWSを確認しよう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/3eed12cf-ae91-05c3-b570-5b24bb3f377f.png)
バケットポリシの修正はちゃんと反映されて、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/52d50389-fee1-4037-462c-c1a3e2117490.png)
タグもちゃんと追加されたね！

# 終わりに

お疲れ様です！今回のやりたいことが無事終わった！
・手動で作成したS3リソースをterraformで管理したい
 　⇒🐱前回terraform importでできたよ！

https://qiita.com/curlneko/items/ab317f0be0ee4b29a871


・AWSで事前に書いたS3バケットポリシーをtfファイルに丸ごと取り込みたい
 　⇒🎉import blockを使えば、tfファイルを自動生成し、S3バケットポリシーの中身を取り込めてくれるよ！

# 参考サイト
https://techblog.ap-com.co.jp/entry/2023/06/12/184506

https://developer.hashicorp.com/terraform/language/import