3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

TerraformでS3リソースをインポートしてみた:①Terraform import編

Last updated at Posted at 2023-08-28

やりたいこと

・手動で作成したS3リソースをterraformで管理したい 👈今回はここ

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

前提

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

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

 バケット名を「terraform-test-import-20230828」にして、
image.png
 「IPアドレスのアクセス許可権限」に関するバケットポリシーを手動で設定
image.png

バケットポリシー
{
    "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
}

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

・特に「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.tf (importのお試し)

ソースの中身

main.tf

・main.tfには基本、全体共通で重要な設定、例えば「AWS プロバイダの設定」を書く

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は事前に発行したやつを使用

variables.tf
variable "region" {
  default = "ap-northeast-1"
}

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

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

import.tf

・Terraform importのお試しファイル
・Terraform import実行後、中身の編集をやりたいので、最初はリソースaws_s3_bucketaws_s3_bucket_policyの枠だけ用意すればいい
 (いったんリソース名だけ書いて、中身を完全に空にしても大丈夫)

import.tf
resource "aws_s3_bucket" "s3" {
  bucket = "terraform-test-import-20230828"
}

resource "aws_s3_bucket_policy" "s3" {
  bucket = aws_s3_bucket.s3.id
#   policy = <<POLICY
# {
# }
# POLICY
}

※補足
通常、この状態でterraform planを実行するとpolicyがないよ!!って怒られるが、今回はterraform planからではなく、terraform importをやりたいので、policyのコメントアウトは大丈夫(空にするのは必須である)

Terraformのimportを試してみる

AWSのほうですでにリソースがあるだけど、手動で作成したやつらをIaaS風で管理したい場合はどうしたらいいか?

Terraform import の出番だ!!!

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

terraform import aws_s3_bucket.s3 terraform-test-import-20230828

これが出たら成功かな

実行結果
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.

すると、terraform.tfstateのほうに何か自動で書き込まれたはず

terraform.tfstate
{
  "version": 4,
  "terraform_version": "1.5.5",
  "serial": 1482,
  "lineage": "ccde992e-debb-97f0-c5bd-458b5945bd4e",
  "outputs": {},
  "resources": [
    {
      "mode": "managed",
      "type": "aws_s3_bucket",
      "name": "s3",
      "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "acceleration_status": "",
            "acl": null,
            "arn": "arn:aws:s3:::terraform-test-import-20230828",
            "bucket": "terraform-test-import-20230828",
            "bucket_domain_name": "terraform-test-import-20230828.s3.amazonaws.com",
            "bucket_prefix": "",
            "bucket_regional_domain_name": "terraform-test-import-20230828.s3.ap-northeast-1.amazonaws.com",
            "cors_rule": [],
            "force_destroy": null,
            "grant": [
              {
                "id": "2078aa226b78698297fd9aaff292740e1c8f3ce3d6ee33fcc33cd14e0ddea4aa",
                "permissions": [
                  "FULL_CONTROL"
                ],
                "type": "CanonicalUser",
                "uri": ""
              }
            ],
            "hosted_zone_id": "Z2M4EHUR26P7ZW",
            "id": "terraform-test-import-20230828",
            "lifecycle_rule": [],
            "logging": [],
            "object_lock_configuration": [],
            "object_lock_enabled": false,
            "policy": "{\"Statement\":[{\"Action\":\"s3:*\",\"Condition\":{\"IpAddress\":{\"aws:SourceIp\":\"設定したいIP"},\"NotIpAddress\":{\"aws:SourceIp\":\"設定したいIP"}},\"Effect\":\"Allow\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::terraform-test-import-20230828/*\",\"Sid\":\"\"}],\"Version\":\"2012-10-17\"}",
            "region": "ap-northeast-1",
            "replication_configuration": [],
            "request_payer": "BucketOwner",
            "server_side_encryption_configuration": [
              {
                "rule": [
                  {
                    "apply_server_side_encryption_by_default": [
                      {
                        "kms_master_key_id": "",
                        "sse_algorithm": "AES256"
                      }
                    ],
                    "bucket_key_enabled": true
                  }
                ]
              }
            ],
            "tags": {},
            "tags_all": {},
            "timeouts": null,
            "versioning": [
              {
                "enabled": false,
                "mfa_delete": false
              }
            ],
            "website": [],
            "website_domain": null,
            "website_endpoint": null
          },
          "sensitive_attributes": [],
          "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjM2MDAwMDAwMDAwMDAsInJlYWQiOjEyMDAwMDAwMDAwMDAsInVwZGF0ZSI6MTIwMDAwMDAwMDAwMH0sInNjaGVtYV92ZXJzaW9uIjoiMCJ9"
        }
      ]
    }
  ],
  "check_results": null
}

terraform import実行前、terraform.tfstateの中身はほぼ空だけど

コマンド実行すると、S3がimportされ、Terraformで管理されるようになった!

よく見ると↓↓↓、バケット名とかpolicyとか(今回はこの二つしか設定してないからね)、S3の状態やmetaデータはterraform.tfstateに書き込まれた!

terraform.tfstateから抜粋
"bucket": "terraform-test-import-20230828"

"policy": "{\"Statement\":[{\"Action\":\"s3:*\",\"Condition\":{\"IpAddress\":{\"aws:SourceIp\":\"設定したいIP"},\"NotIpAddress\":{\"aws:SourceIp\":\"設定したいIP"}},\"Effect\":\"Allow\",\"Principal\":\"*\",\"Resource\":\"arn:aws:s3:::terraform-test-import-20230828/*\",\"Sid\":\"\"}],\"Version\":\"2012-10-17\"}"

※補足
terraform.tfstateはTerraformが管理しているリソースの現在の状態(terraformの実行計画)を記載するファイル

初めてterraform planを実行したら、terraform.tfstateはローカルに作られ、リソースのstate(状態)が自動で書き込まれる

その後terraform destroyすると、terraform.tfstateは空になるけど、ファイル自体は消えない

一回もterraform planかterraform importを実行したことないのであれば、terraform.tfstateファイルはローカルに存在しないはず

でも、本当にこれでTerraformの管理下になったのか不安なので、最初に作ったほぼ空のimport.tfに、手動で中身を入れ替えて、S3の設定をいじってみよう

import.tf
resource "aws_s3_bucket" "s3" {
  bucket = "terraform-test-import-20230828"

 #タグをいれてみる
  tags = {
    Name = "test"
  }
}

resource "aws_s3_bucket_policy" "s3" {
  bucket = aws_s3_bucket.s3.id
 #バケットポリシを手動で張り付け、AllowをDenyへ変更
 policy = <<POLICY
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Deny",
            "Principal": "*",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::terraform-test-import-20230828/*"
            ],
            "Condition": {
              "IpAddress": {"aws:SourceIp": "設定したいIP"},
              "NotIpAddress": {"aws:SourceIp": "設定したいIP"}
            }
        }
    ]
}
POLICY
}

こんな感じで、タグを一個追加し、バケットポリシをAllowからDenyにしてみた~

terraformの実行計画を変えるため、今度はterraform planを実行しよう

terraform plan

こんな感じで、結果が出たら成功
1 to add:「新規tfファイルの内容を実行計画にいれたよ」って言ってる
1 to change:「tfファイルに書いたS3リソースは、さっきのimportですでにterraform管理下になったけど、修正分があるよ」って言ってる

実行結果
Plan: 1 to add, 1 to change, 0 to destroy.

次に、変更分をAWS側へデプロイ

terraform apply

ちゃんと成功したっぽい

実行結果
Apply complete! Resources: 1 added, 1 changed, 0 destroyed.

もう一度terraform.tfstateを確認すると、変更分はちゃんと管理ファイルに書かれてるね!

terraform.tfstateから抜粋
"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\"}",
"tags": {
              "Name": "test"
            },

そして、AWS側を見てみると、バケットポリシは確かに修正されて、
image.png
testのタグもできてます!
image.png

最後、リソースはterraformにより削除できるか確認しよう

terraform destroy

リソースが削除されたよって言ってます!

実行結果
Destroy complete! Resources: 2 destroyed.

AWSを確認すると、ちゃんと削除してくれたね!Good!
image.png

終わりに

お疲れ様です!今回のやりたいことが無事終わった!
・手動で作成したS3リソースをterraformで管理したい
 ⇒🎉terraform importすればできるよ!
・AWSで事前に書いたS3バケットポリシーをtfファイルに丸ごと取り込みたい
 ⇒🐱次回書く

参考サイト

以下のサイトのおかげで、大変勉強になりました!ありがとうございます!

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?