やりたいこと
・手動で作成したS3リソースをterraformで管理したい 👈今回はここ
・AWSで事前に書いた3バケットポリシーをtfファイルに丸ごと取り込みたい
👇👇👇次回やる
前提
・AWSアカウント作成済み
・AWS IAMユーザーを作成し、access_keyとsecret_keyを発行済み
・Terraformインストール済み
・AWS CLIインストール済み
・VSCODEインストール済み
(お好みのエディターで大丈夫)
・AWSのほうで、手動でS3バケットとそのポリシーを作成済み
(バケットポリシー以外の設定は、全部デポジットで大丈夫)
バケット名を「terraform-test-import-20230828」にして、
「IPアドレスのアクセス許可権限」に関するバケットポリシーを手動で設定
{
"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 プロバイダの設定」を書く
# AWS プロバイダの設定
provider "aws" {
access_key = var.access_key
secret_key = var.secret_key
region = var.region
}
variables.tf
・variables.tfに全ソース共通の変数を書く
・リージョンは東京にしたが、適宜変更して大丈夫
・access_keyとsecret_keyは事前に発行したやつを使用
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_bucketとaws_s3_bucket_policyの枠だけ用意すればいい
(いったんリソース名だけ書いて、中身を完全に空にしても大丈夫)
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のほうに何か自動で書き込まれたはず
{
"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に書き込まれた!
"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の設定をいじってみよう
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を確認すると、変更分はちゃんと管理ファイルに書かれてるね!
"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側を見てみると、バケットポリシは確かに修正されて、
testのタグもできてます!
最後、リソースはterraformにより削除できるか確認しよう
terraform destroy
リソースが削除されたよって言ってます!
Destroy complete! Resources: 2 destroyed.
終わりに
お疲れ様です!今回のやりたいことが無事終わった!
・手動で作成したS3リソースをterraformで管理したい
⇒🎉terraform importすればできるよ!
・AWSで事前に書いたS3バケットポリシーをtfファイルに丸ごと取り込みたい
⇒🐱次回書く
参考サイト
以下のサイトのおかげで、大変勉強になりました!ありがとうございます!