概要
Google Cloud の Vertex AI(Gemini)を、AWS Lambda から呼び出します!
Workload Identity Federation でセキュアな認証を実装します。
なぜ AWS Lambda × Vertex AI?
Amazon Bedrock エージェント に Gemini を組み込みたいからです!
Gemini API を直接利用する方法ありますが、セキュリティ的にAPIキーを管理したくないので Workload Identity Federation で認証します。
せっかくなので技術検証も兼ねて Vertex AI をさわってみよう思った次第です!
AWS から Vertex AI アクセス許可フロー
アクセス許可フローは下記の通りです。
- AWS STS を利用し Google Cloud のサービスアカウントにアクセス許可する
- Google Cloud 側で、Workload Identity Pool とその Provider を設定し、AWS IAM ロールが認証を通じ Google Cloud サービスアカウント にアクセス許可する
- Google Cloud サービスアカウントに、Vertex AI アクセス権限付与する
- 結果 AWS から Vertex AI へアクセス可能になる!!!
Workload Identity Federation
Google Cloud で下記設定を実施し、特定のAWSアカウントからのみアクセスを許可します。
- Service Account (人ではなくプログラム等が Google Cloud のリソースにアクセスするためのアカウント)
- Workload Identity
- IAM
data "google_project" "current" {}
data "aws_caller_identity" "self" {}
locals {
project_id = data.google_project.current.project_id
project_number = "************"
services = toset([
"iam.googleapis.com",
"cloudresourcemanager.googleapis.com",
"iamcredentials.googleapis.com",
"sts.googleapis.com",
"aiplatform.googleapis.com"
])
}
#######################################
# Service Account
#######################################
# Google Cloud で利用する API の 有効化
resource "google_project_service" "main" {
for_each = local.services
project = local.project_id
service = each.value
disable_dependent_services = true
}
resource "google_service_account" "main" {
project = local.project_id
account_id = local.project_id
display_name = local.project_id
}
#######################################
# Workload Identity
#######################################
resource "google_iam_workload_identity_pool" "main" {
project = local.project_id
workload_identity_pool_id = "aws"
display_name = "aws"
}
resource "google_iam_workload_identity_pool_provider" "main" {
workload_identity_pool_id = google_iam_workload_identity_pool.main.workload_identity_pool_id
workload_identity_pool_provider_id = "aws"
display_name = "aws"
# AWS Lambda をデプロイするアカウントのみ許可
aws {
account_id = data.aws_caller_identity.self.id
}
}
#######################################
# IAM
#######################################
# サービスアカウントに Vertex AI アクセス権限付与
resource "google_project_iam_member" "main" {
project = local.project_id
role = "roles/aiplatform.user"
member = "serviceAccount:${google_service_account.main.email}"
}
# AWS がサービスアカウントの権限借用許可
resource "google_service_account_iam_binding" "main" {
service_account_id = google_service_account.main.name
role = "roles/iam.workloadIdentityUser"
members = [
"principalSet://iam.googleapis.com/projects/${local.project_number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.main.workload_identity_pool_id}/*",
]
}
Google Cloud 認証情報設定
Google Cloud 認証情報取得
AWS Systems Manager Parameter Store へ Google Cloud 認証情報保存
Google Cloud 認証情報ファイルの内容を、AWS Systems Manager Parameter Storeへ登録します。
パラメータ名は GOOGLE_APPLICATION_CREDENTIALS で登録します。
AWS Lambda
Vertex AI SDK for Pythonを利用する為、コンテナイメージで Lambda をデプロイします。
※ Lambda レイヤーでは容量制限に引っかかる為
メモリーサイズは 最小 128 MB の場合、メモリ不足でエラーになる場合があります。
#######################################
# Lambda Function
#######################################
resource "aws_lambda_function" "main" {
function_name = "gemini"
package_type = "Image"
image_uri = "${aws_ecr_repository.main.repository_url}:latest"
memory_size = 512
timeout = 900
role = aws_iam_role.main.arn
environment {
variables = {
GOOGLE_APPLICATION_CREDENTIALS_PATH = "GOOGLE_APPLICATION_CREDENTIALS" # SSM Parameter Storeのパラメータ名
GCP_PROJECT_ID = data.google_project.current.project_id
}
}
}
#######################################
# ECR
#######################################
resource "aws_ecr_repository" "main" {
name = "gemini"
}
#######################################
# IAM
#######################################
resource "aws_iam_role" "main" {
name = "LambdaRoleForGemini"
assume_role_policy = data.aws_iam_policy_document.lambda_assume_role.json
}
resource "aws_iam_role_policy_attachment" "main" {
role = aws_iam_role.main.name
policy_arn = aws_iam_policy.main.arn
}
resource "aws_iam_policy" "main" {
name = "LambdaRoleForGemini"
policy = data.aws_iam_policy_document.lambda_role.json
}
data "aws_caller_identity" "self" {}
data "aws_region" "current" {}
data "google_project" "current" {}
#######################################
# IAM
#######################################
data "aws_iam_policy_document" "lambda_assume_role" {
version = "2012-10-17"
statement {
effect = "Allow"
principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}
actions = ["sts:AssumeRole"]
}
}
data "aws_iam_policy_document" "lambda_role" {
version = "2012-10-17"
statement {
effect = "Allow"
actions = [
"ssm:GetParameter",
"ssm:GetParameters",
]
resources = [
"arn:aws:ssm:${data.aws_region.current.name}:${data.aws_caller_identity.self.id}:parameter/*",
]
}
statement {
effect = "Allow"
actions = [
"kms:Decrypt",
"kms:Encrypt",
"kms:GenerateDataKey",
]
resources = [
"arn:aws:kms:${data.aws_region.current.name}:${data.aws_caller_identity.self.id}:key/*"
]
}
statement {
effect = "Allow"
actions = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
]
resources = ["arn:aws:logs:${data.aws_region.current.name}:${data.aws_caller_identity.self.id}:log-group:/aws/lambda/${aws_lambda_function.main.function_name}:*"]
}
}
AWS Lambda コンテナ設定
Lambda の処理で利用するライブラリを定義します。
boto3==1.37.17
google-cloud-aiplatform==1.90.0
google-auth==2.39.0
Dockerfile を記述しビルドします。
FROM public.ecr.aws/lambda/python:3.13
WORKDIR /var/task
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Lambdaの処理が存在するディレクトリ
COPY src .
CMD ["lambda_function.lambda_handler"]
ビルドが完了したら、ECRへプッシュします。
AWS Lambda の 処理
コンテナ内部に環境変数 GOOGLE_APPLICATION_CREDENTIALS を設定し、Google Cloud 認証情報ファイルを埋め込む必要があります。
import os
import boto3
import vertexai
from vertexai.generative_models import GenerationConfig, GenerativeModel
def lambda_handler(event, _):
try:
credentials = boto3.client("ssm").get_parameter(
Name=os.environ.get("GOOGLE_APPLICATION_CREDENTIALS_PATH"),
WithDecryption=True
)
# コンテナ内部に google cloud 認証情報を json で保持する
credentials_path = "/tmp/gcloud-credential.json"
with open(credentials_path, "w") as f:
f.write(credentials)
# json のパスを環境変数に設定する
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = credentials_path
# GOOGLE_APPLICATION_CREDENTIALS を読み取り認証を実施
gcp_project_id = os.environ.get("GCP_PROJECT_ID")
vertexai.init(project=gcp_project_id, location="us-central1")
model = GenerativeModel("gemini-2.5-flash-preview-04-17")
# モデルに対しての詳細な設定を調整
generation_config = GenerationConfig(
temperature=0.9,
top_k=40,
top_p=0.9,
candidate_count=1,
max_output_tokens=8192,
)
text = "自己紹介してください"
response = model.generate_content(
text,
generation_config=generation_config,
)
return {"status_code": 200, "message": "処理成功", "text": response.text}
except Exception as e:
return {"status_code": 500, "message": "処理失敗", "error": str(e)}
AWS Lambda のコンソールから実行し、Gemini から回答があれば成功です!!
まとめ
AWS と Google Cloud の認証関連や、本記事には記述していないですがコンテナイメージ Lambda の CD 関連の知見が増えてよかったです。
次は AWS Lambda から Azure OpenAI Service 経由で GPT を呼び出したい!!!