Treasure Data - Support Engineering Team blog

トレジャーデータのサポートエンジニアリングチームのブログです。

Assume Roleのすすめ

みなさん、こんにちは

本記事ではS3 v2コネクターにて実装されたAssume Roleでの認証について説明をしていきます。
実は6月頃からS3 v2でサポートされていたのですが、より多くの人に知ってもらい使ってもらうためにも
こちらのブログでも紹介いたします。

Treasure DataとAWSアカウントをよりセキュアに接続する事が可能な方式となっているので、
特に新規でコネクターを使う場合にはAssume Roleを第一選択にすることをおすすめいたします。

注意

yamlを使ってassume roleの設定はできません。
TD toobeltやWorkflowから実行したい場合は一度Sourceを作成し、それを呼ぶようにしてください。

Assume Roleとは

Assume RoleはAWSAWS Security Token Serviceの機能の一つとして提供されており、
恒常的な認証情報の代わりに一時的な認証情報を提供することによってAWSリソースへのアクセスを可能にするものです。

Treasure Dataのような外部サービスからお客様のAWSアカウントのリソースであるS3にアクセスする場合は、
AccessKey/Secret Keyを利用した認証方法ではなくAssume Roleを使う方法が推奨されます。

Assume Roleの詳細についてはAWSのドキュメントをご参照ください。
docs.aws.amazon.com

Authenticationの作成方法と注意事項

トレジャーデータのドキュメントにも設定方法の記載がありますが折角なのでこちらのブログでも紹介します。
なおドキュメントはこちらです。

Amazon S3 Import Integration v2 - Integrations - Treasure Data Product Documentation
Amazon S3 Export Integration v2 - Integrations - Treasure Data Product Documentation

CatalogからS3 v2を選択

Assume RoleはS3 v2でのみ利用可能な機能です。
S3 v2のCatalogからAuthenticationを作成しましょう。

項目の入力

入力項目はそれほど多くはありません。

まずAuthentication Methodでassume_roleを選択してください。
そうするとAsuume Roleに必要な項目を入力するフォームに変化します。

S3 v2 catalog
  • Account IDとYour Role Name

こちらの項目にはお客様のAWS Account IDとAssume Roleを引き受けるRoleの名前を入力してください。
この段階だとRoleは未作成かと思いますので、作成予定のRoleの名前をYour Role Nameに入力してください。
AWSのアカウントIDが分からないという場合は以下のAWSのドキュメントに従い、ご自身のAWSアカウントIDをご確認ください。

docs.aws.amazon.com

  • Duration In Seconds

Assume Roleをした結果得た認証情報の有効期限を設定する箇所です。
ご要件に合わせて適切な時間を設定してください。
単位はです。

TD's Instance ProfileとExternal IDのメモ

ここで注意です。

TD's Instance ProfileとExternal IDを必ずメモしておきましょう。
特にExternal IDは必ずどこかに残しておいてください。
External IDは作成時にしか表示されないため、忘れてしまった場合は再度Authenticationを作成する必要があります。

External IDはTreasure Dataからお客様のAWSリソースにアクセスする時に利用される識別子となります。
External IDを使うことでどのリソースからのアクセスなのかを明確に判断しやくすくなり、AWSのAuditという観点でも有用なものであり、AWSとして推奨されるものとなります。

External IDがなぜ必要かは以下のAWSのドキュメントをご参照ください。

AWS リソースへのアクセス権を第三者に付与するときに外部 ID を使用する方法 - AWS Identity and Access Management

以上でAuthenticationの作成は完了です。
お次はAWS側でのRoleを作成しましょう。

IAM Roleの作成

AWSのコンソールからIAM -> Rolesに移動をし、Create Roleを選択してください。

aws iam console
Treasure DataのAccount IDとExternal IDの入力

画面に従いながら、以下のように設定をしてください。

  • Trusted entity typeにてAWS Accountを選択
  • An AWS accountにてAnother AWS accountにチェックを入れ、TDのAccount IDを入力
  • OptionsのRequire external IDにチェックし、External IDを入力

完了したらNext Buttonをクリックし、roleにアタッチするPolicyを選択してください。
なおTreasure DataからS3にアクセスするのに必要な権限は以下の通りです。

Sourceに必要な権限
  • s3:GetObject
  • s3:ListBucket
Result Outputに必要な権限
  • s3:PutObject
  • s3:AbortMultipartUpload

権限の設定が完了したらNextを押し、Step 3 Name, review, and createに移りましょう。
Role nameにはTreasure DataのAuthenticationに設定した名前を入力してください。

最後に設定項目を確認し、Create Roleを押せばAWSでの作業も完了です。

以上のStepで作成したAuthenticationを利用すれば、Assume Roleでの認証となります。

最後に

それほど多くのないステップでAssume Roleの設定が可能ですので、
みなさんもぜひAssume Roleでの接続をご利用ください。

おまけ

Terraformで設定をしている方向けのサンプルコードとなります。

  • data.tf
data "aws_iam_policy_document" "sample_td_s3_assume_role" {
  statement {
    actions = ["sts:AssumeRole"]
    effect  = "Allow"
    principals {
      type        = "AWS"
      identifiers = ["523683666290"]
    }
    condition {
      test     = "StringEquals"
      variable = "sts:ExternalId"
      values   = ["your_external_id"]
    }
  }
}

data "aws_iam_policy_document" "sample_td_s3_connector" {
  statement {
    sid = "1"

    actions = [
      "s3:GetObject",
      "s3:ListBucket",
      "s3:PutObject",
      "s3:AbortMultipartUpload"
    ]

    resources = [
      "arn:aws:s3:::your_bucket_name",
      "arn:aws:s3:::your_bucket_name/*"
    ]
  }

}
  • iam.tf
resource "aws_iam_role" "sample_td_s3_assume_role" {
  name               = "sample_td_assume_role"
  assume_role_policy = data.aws_iam_policy_document.sample_td_s3_assume_role.json
}

resource "aws_iam_policy" "sample_td_s3_access_policy" {
  name        = "sample_td_s3_access_policy"
  description = "Sample of assume role policy"
  path        = "/"
  policy      = data.aws_iam_policy_document.sample_td_s3_connector.json
}

resource "aws_iam_role_policy_attachment" "sample_td_s3_assume_role" {
  role       = aws_iam_role.sample_td_s3_assume_role.name
  policy_arn = aws_iam_policy.sample_td_s3_access_policy.arn
}