別AWSアカウントのS3にオブジェクトをコピーしたい
特定のAWSアカウントのS3バケットにあるオブジェクトを
別AWSアカウントにコピーするTerraformコードの紹介になります。
実際のコード
copy_objectを使えばOKです。
- main.tf
ソースのS3バケットが存在するAWSアカウント設定
provider "aws" {
region = "ap-northeast-1"
default_tags {
tags = {
IaC = "Terraform"
}
}
}
# コピー対象のAWSアカウント設定
provider "aws" {
profile = var.targetprofile
alias = "delegator"
region = "ap-northeast-1"
default_tags {
tags = {
IaC = "Terraform"
}
}
}
- data.tf
data "aws_caller_identity" "current" {}
- variables.tf
TARGET_AWS_PROFILE : コピー先のAWSプロファイル名
TARGET_S3_BUCKETNAME : コピー先のS3バケット名
SOURCE_S3_BUCKETNAME : コピー元のS3バケット名
variable "target_profile" {
default = TARGET_AWS_PROFILE
description = "aws target_profile"
}
variable "region" {
default = "ap-northeast-1"
description = "aws region"
}
variable "source_bucketname" {
default = TARGET_S3_BUCKETNAME
description = "source s3 bucket name"
}
variable "target_bucketname" {
default = SOURCE_S3_BUCKETNAME
description = "target s3 bucket name"
}
- s3_object_copy.tf
targetobject : コピー対象のオブジェクト名
# Object S3 Copy
locals {
targetobject = [
"test.txt",
"test/sample.txt"
]
}
# S3 Bucker Create
resource "aws_s3_bucket" "target" {
provider = aws.delegator
bucket = var.target_bucketname
}
data "aws_iam_policy_document" "allow_access_from_another_account" {
provider = aws.delegator
statement {
sid = "Example permissions"
principals {
type = "AWS"
identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"]
}
actions = [
"s3:GetObject",
"s3:ListBucket",
"s3:PutObject",
"s3:PutObjectAcl",
"s3:*"
]
resources = [
aws_s3_bucket.target.arn,
"${aws_s3_bucket.target.arn}/*",
]
}
}
resource "aws_s3_bucket_policy" "target" {
provider = aws.delegator
bucket = aws_s3_bucket.target.bucket
policy = data.aws_iam_policy_document.allow_access_from_another_account.json
}
resource "aws_s3_object_copy" "copy_object" {
for_each = toset(local.targetobject)
bucket = aws_s3_bucket.target.id
key = each.key
source = "${var.source_bucketname}/${each.key}"
depends_on = [
aws_s3_bucket_policy.target,
]
}
実行方法
- DryRun
terraform plan
- Apply
terraform apply
解説
aws_s3_object_copyでバケットポリシーを関連付けしておかないと
バケットポリシーの付与前にオブジェクトをコピーしようとしてしまうため
バケットポリシーの付与が完了してからコピーするようにdepends_onで指定しています。
尚、定義ファイルをシンプルにするためstateファイル管理にS3やDynamoDBを利用していません。
同じ理由でmodule化もしていません。
- 初回実行だとdefault_tagsが付与されない問題
Applyの内容をみるとtags_allで付与されるように見えるのですが、
実際には付与されず、再度実行する必要があります。
# aws_s3_object_copy.copy_object["test.txt"] will be updated in-place
~ resource "aws_s3_object_copy" "copy_object" {
id = "test.txt"
tags = {}
~ tags_all = {
+ "IaC" = "Terraform"
}
# (32 unchanged attributes hidden)
}
# aws_s3_object_copy.copy_object["test/sample.txt"] will be updated in-place
~ resource "aws_s3_object_copy" "copy_object" {
id = "test/sample.txt"
tags = {}
~ tags_all = {
+ "IaC" = "Terraform"
}
# (32 unchanged attributes hidden)
}