こんにちは。KIYONOエンジニアの斉藤です。
今回の記事では、AWSからGoogle Cloudに接続してデータを取得するための権限設定について解説します。本記事では、AWS Lambdaを使ってCloud Storageからデータを取得し、S3にファイル格納する方法を例に権限設定については解説しておりますが、もちろん他の方法でも応用がきく方法ですので、ぜひご参考にしていただければと思います。
Workload Identity Poolというサービスを使用します。
はじめに
構成の解説
上記が構成図になります。
主な処理としては、以下になります。
- Lambdaに紐づくIAMロールがサービスアカウントの権限を借用する
- Lambdaが権限をCloud Storageにアクセスしファイル取得する
- 取得したファイルをS3バケットに格納する
今回のポイントとしては、特に①の権限借用の部分になります。
Workload Identity Poolでは信頼する対象の AWS アカウントと IAM Role 名等を指定することで、 Google Cloud サービスアカウントの権限を借用することを許可することができます。そうすることで今回のケースでいうとLambdaがCloud Storageにアクセスすることを可能とします。
具体的な設定については後述します。
設定の流れ
- [AWS] IAM Role を作成・権限付与
- [Google Cloud] サービスアカウントを作成・権限付与
- [Google Cloud] Workload Identity Pool を作成
- [Google Cloud] Workload Identity Pool にサービスアカウントを接続
- [ローカル] デプロイパッケージを作成
- [AWS] Lambda 関数をデプロイ
- [AWS] 動作テスト
前提
S3とCloud Storageのバケットはあらかじめ作成しているものとします。本記事ではS3とCloud Storageどちらもs3-gcs-connectというバケット名にしております。Cloud Storage s3-gcs-connectバケットにsample.txt(中身は任意)を配置した前提とします。
検証のゴール
検証のゴールとしてはLambda関数を実行するとAWS s3-gcs-connectバケットにsample.txtが配置されればOKとします。
設定詳細
1. [AWS] IAM Role を作成・権限付与
まずは、Lambda 関数にアタッチするための IAM Role を作成します。Google Cloud 側の設定で、信頼する対象の IAM Role として名称が必要なため、先に作成します。
IAM > ロール > ロールを作成 より、gcs-to-s3-roleというロールを作成します。追加のポリシーとしては以下を設定します。
- AmazonS3FullAccess
- AWSLambdaBasicExecutionRole
一つ目がS3にファイルをアップロードするための権限で、二つ目がLambdaの実行権限になります。
2. [Google Cloud] サービスアカウントを作成・権限付与
次に、Lambda 関数が権限借用するためのサービスアカウントを作成します。
IAMと管理 > サービスアカウント > サービスアカウントを作成 より、gcs-to-s3-service-accountというサービスアカウントを作成します。以下のロールを設定します。
- Storage オブジェクト閲覧者
Cloud Storageのファイルを読み取るための権限となります。
3. [Google Cloud] Workload Identity Poolを作成
IAMと管理 > Workload Identity 連携より、添付の通りにWorkload Identity Poolを作成します。
上図の通り、任意の名称(今回はaws-connect)を設定し、②のプロバイダー追加を設定します。
上図の通り、プロバイダ選択をAWS、プロバイダ名を任意の名称(今回はaws-connect)、AWSアカウントIDを入力し続行します。③は設定せずにプールを作成してしまって問題ないです。
4. [Google Cloud] Workload Identity Poolにサービスアカウントを接続
IAMと管理 > Workload Identity 連携より、先ほど作成したプール(本記事ではaws-connect)を選択します。プールの詳細よりアクセスを許可をクリックし、サービスアカウントを接続します。
以下の通り、先ほど作成したサービスアカウント(gcs-to-s3-service-account)を選択し、プリンシパルの選択の属性名をaws_roleにし、属性値にarn:aws:sts::(AWS Account ID):assumed-role/(IAM Role 名)の形式で入力します。入力が完了したら保存をクリックします。
プロバイダーの部分をaws-connectにし、構成をダウンロードをクリックします。クリックすると、構成情報をローカル環境にダウンロードできます。「5. [ローカル] デプロイパッケージを作成」にて使用します。
5. [ローカル] デプロイパッケージを作成
サンプルコード
Lambda 関数のソースコードは以下を使います。以下はあくまでサンプルコードであり、実際には例外処理やロギング、セキュアなコーディングに関する考慮をしたうえでご利用ください。
import boto3
from google.cloud import storage
from google.api_core.client_options import ClientOptions
import os
def create_gcs_client(custom_endpoint):
# ClientOptions を使用してカスタムエンドポイントを設定
client_options = ClientOptions(api_endpoint=custom_endpoint)
# クライアントの作成
client = storage.Client(client_options=client_options)
return client
def lambda_handler(event, context):
# GCS 設定
gcs_bucket_name = 's3-gcs-connect'
gcs_file_name = 'sample.txt'
custom_endpoint = 'https://storage.googleapis.com' # カスタムAPIエンドポイント
# S3 設定
s3_bucket_name = 's3-gcs-connect'
s3_file_name = 'sample.txt'
# GCSクライアントの作成
gcs_client = create_gcs_client(custom_endpoint)
# GCS からファイルを読み込み
bucket = gcs_client.bucket(gcs_bucket_name)
blob = bucket.blob(gcs_file_name)
content = blob.download_as_bytes()
# S3 にファイルをアップロード
s3_client = boto3.client('s3')
s3_client.put_object(Body=content, Bucket=s3_bucket_name, Key=s3_file_name)
return {
'statusCode': 200,
'body': 'File transferred successfully'
}
パッケージの作成
ローカル環境(※)の任意ディレクトリにてlambda_function.pyを作成し、上記のサンプルコードを入力します。また先程ダウンロードした Workload Identity Pool の構成ファイルも同じディレクトリに配置します。※OSはLinuxやMac想定となっております。
Lambda では Google Cloud クライアントライブラリのような外部ライブラリはデプロイパッケージに含ませる必要があるため、以下のコマンドでディレクトリ内に展開します。
# PythonパッケージをMac上で直接インストールしてしまうと、Arm64向けになってしまうため、x86_64なDockerコンテナ内でインストールしたものをアップロード
docker run --rm -v $(pwd):/work -w /work python:3.11 pip install google-cloud-storage -t .
次に以下のコマンドで1段階上位のディレクトリに zip ファイルを作成します。
zip -r ../function.zip .
6. [AWS] Lambda 関数をデプロイ
lambda > 関数 > 関数の作成より、lambda関数を作成します。入力値については以下添付を参考にしていただければと思いますが、一点注意点としては赤枠の部分のロールを「既存のロールを使用する」を選択いただき、「1. [AWS] IAM Role を作成・権限付与」で作成したIAMロールを選択してください。入力が完了したら添付右下の「関数の作成」をクリックします。
次に実際にlambda関数を設定します。赤枠のアップロード元より、zipファイルをアップロードします。先ほどローカル環境でzip化した、function.zipをアップロードします。
次に、環境変数を設定します。添付の通りGOOGLE_APPLICATION_CREDENTIALSに「4. [Google Cloud] Workload Identity Pool にサービスアカウントを接続」でダウンロードした構成ファイル名を値に入力し、GOOGLE_CLOUD_PROJECTについてはGoogle CloudのプロジェクトIDを入力します。
またその他の設定として、lambdaではデフォルトのタイムアウト設定が3秒になっているため、適宜処理時間に合わせてタイムアウトの設定値を調整ください。
7. [AWS] 動作テスト
添付の通りlambdaのテスト機能より関数を実行します。イベント名と、イベントJSONは任意の値で問題ございません。
テスト実行すると以下の通り、実行ログを出力します。
また対象のS3バケットにファイルが格納されていれば検証としては完了です。
終わりに
いかがだったでしょうか。
AWSからGoogle Cloudに接続してデータを取得するための権限設定について解説しました。冒頭でもお伝えしたとおり、本記事ではAWS Lambdaを使ってCloud Storageからデータを取得し、S3にファイル格納する例を用いながら権限設定(Workload Identity Pool)の方法をご紹介しましたが、他の方法にも応用がききますのでぜひ試してみてくださいませ。
実際に試して難しい場合は、弊社にご相談いただければと思います。
コメント