LoginSignup
0
0
お題は不問!Qiita Engineer Festa 2024で記事投稿!
Qiita Engineer Festa20242024年7月17日まで開催中!

[Terraform]別AWSアカウントにS3オブジェクトをコピー

Last updated at Posted at 2024-06-30

別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)
    }
0
0
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
0
0