1.はじめに
1.1.1.背景
AWS CloudShellは便利なツールですが、限られたリソース(1 vCPU、2GB RAM)しか持たないため、大きめのコンテナをビルドする際に制約を感じることがあります。
そこで代替手段として、より高いスペック(2 vCPU、4GB RAM)を持つGoogle Cloud Shellを活用し、AWS ECRへのイメージプッシュとLambda関数のデプロイを試みました。
1.1.2.AWSとGoogle Cloud の Cloud Shellの違い
- DockerイメージのビルドにはCPUやメモリリソースが要求されるため、Google Cloud Shellのスペックは助かります。
項目 | AWS Cloud Shell | Google Cloud Shell |
---|---|---|
CPU | 1 vCPU | 2 vCPU |
メモリ | 2 GB RAM | 4 GB RAM |
ストレージ | 1 GB 永続ストレージ | 5 GB 永続ストレージ |
データ保持期間 | 120日間 | 手動でリセットするまで無期限 |
コードエディタ | シンプルなエディタ | フル機能のWeb IDEを内蔵 |
ウェブプレビュー | 非対応 | Web Previewで5000番ポート等を外部公開可能 |
1.1.3.本構築の構成図
2.ハンズオン
2.1.前提
2.1.1.実行環境
- AWS の Cloud Shell
- リージョン:us-east-1 として実施
- Google Cloud の Cloud Shell
2.1.2.手順の流れ
- AWS側での準備はAWS Cloud Shellで、それ以降のDockerビルドやデプロイはGoogle Cloud Shellで実施する。
2.2.AWS側での準備
- AWSのCloud Shellで以下コマンドを実施
- PoCのためIAMユーザを作成して認証情報を付与する(※本番環境では、IAMロール作成やポリシーアタッチに必要な最小限の権限(例: iam:CreateRole, iam:AttachRolePolicy, iam:GetRole, iam:PassRoleなど)を付与することを推奨)
- 作成されたアクセスキーの取扱いには注意してください(※後続の手順後に削除推奨)
# 変数設定
USER="GoogleCloud_CloudShell"
# IAMユーザ作成
aws iam create-user --user-name $USER
# ユーザーにポリシーをアタッチする(ECR、Lambda、IAMの権限)
aws iam attach-user-policy --user-name $USER --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryFullAccess
aws iam attach-user-policy --user-name $USER --policy-arn arn:aws:iam::aws:policy/AWSLambda_FullAccess
aws iam attach-user-policy --user-name $USER --policy-arn arn:aws:iam::aws:policy/IAMFullAccess
# アクセスキー作成して結果をJSONファイルに保存
aws iam create-access-key --user-name $USER > ${USER}_access_key.json
# ファイル確認
cat ${USER}_access_key.json
2.3.Google Cloud側での準備
2.3.1.AWS CLI インストール
- Google CloudのCloud Shellで以下コマンドを実施
aws configure
での設定した認証情報は~/.aws/credentials
ファイルに保存される。
# AWS CLI ダウンロード
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
# 解凍
unzip awscliv2.zip
# AWS CLI インストール
sudo ./aws/install
2.3.2.AWS認証情報の設定
2.2.AWS側での準備
で作成した${USER}_access_key.json
を登録
# AWS認証情報の設定
aws configure
# 以下を払い出されたユーザのものを登録
AWS Access Key ID [None]: ■■■■■■■■■■■
AWS Secret Access Key [None]: ■■■■■■■■■■■
Default region name [None]: us-east-1
Default output format [None]: json
2.4.Lambda関数作成
2.4.1.アプリケーション部分
# lambda_function.py作成
cat > lambda_function.py << EOF
import json
from datetime import datetime
import pytz
def lambda_handler(event, context):
# 東京時間の取得
tokyo_tz = pytz.timezone('Asia/Tokyo')
current_time = datetime.now(tokyo_tz).strftime('%Y-%m-%d %H:%M:%S %Z')
# メッセージを取得(event パラメータから'message'キーを取得)
message = event.get('message', 'Default message from Lambda!')
return {
'statusCode': 200, # HTTP ステータスコード
'body': json.dumps({
'greeting': f'Hello from {message}!',
'event': event, # 受け取ったイベント全体を返す(デバッグ用)
'requested_at': datetime.now(tokyo_tz).isoformat(), # ISO形式の日時
'display_time': current_time, # 見やすい形式の日時
'request_id': context.aws_request_id # Lambdaリクエストの一意なID
})
}
EOF
2.4.2.requirements.txt作成
# requirements.txt作成
cat > requirements.txt << EOF
pytz
EOF
2.4.3.Dockerfile作成
cat > Dockerfile << EOF
# AWS公式よりPython 3.11 環境を利用
FROM public.ecr.aws/lambda/python:3.11
# アプリケーションコードをコピー
COPY lambda_function.py requirements.txt ./
# 依存関係をインストール
RUN pip install --no-cache-dir -r requirements.txt
# ハンドラを設定
CMD ["lambda_function.lambda_handler"]
EOF
2.5.ECRリポジトリ作成とログイン
# 変数設定
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
REPO_NAME="lambda-container"
REGION=us-east-1
# ECRリポジトリ作成
aws ecr create-repository --repository-name $REPO_NAME
# ECRにログイン
aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com
2.6.Dockerイメージのビルドとプッシュ
# 変数設定
ECR_IMAGE_URI=$ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$REPO_NAME
# Dockerイメージビルド
docker build -t $ECR_IMAGE_URI:latest .
# ECRにプッシュ
docker push $ECR_IMAGE_URI:latest
2.7.Lambda実行ロールと関数デプロイ
# 変数設定
FUNCTIONNAME="my-python-container-function"
LAMBDAROLE="lambda-container-role"
# IAMロール作成
aws iam create-role --role-name $LAMBDAROLE --assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}'
# IAMポリシーをアタッチ
aws iam attach-role-policy \
--role-name $LAMBDAROLE \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
# IAMロールARNを取得
ROLE_ARN=$(aws iam get-role --role-name $LAMBDAROLE --query 'Role.Arn' --output text)
# Lambda関数を作成
aws lambda create-function \
--function-name $FUNCTIONNAME \
--role $ROLE_ARN \
--code ImageUri=$ECR_IMAGE_URI:latest \
--description "Python Lambda Container from GCP CloudShell" \
--timeout 30 \
--memory-size 256 \
--package-type Image \
--region $REGION
2.8.挙動確認
2.8.1.コマンド実行
"StatusCode": 200
が返ってくることを確認
# テストイベントを作成
echo '{"key": "value", "message": "Lambda Container from Google Cloud"}' > test-event.json
# Lambda関数の呼出し
aws lambda invoke \
--function-name my-python-container-function \
--payload fileb://test-event.json \
response.json
# レスポンスの確認
cat response.json
2.8.2.実行結果
2.8.2.1.コンソールの出力
{
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
2.8.2.2.response.jsonの内容
- 適宜改行して記載
{
"statusCode": 200,
"body":
"{
\"greeting\": \"Hello from Lambda Container from Google Cloud!\",
\"event\": {
\"key\": \"value\",
\"message\": \"Lambda Container from Google Cloud\"
},
\"requested_at\": \"2025-05-07T22:41:16.821398+09:00\",
\"display_time\": \"2025-05-07 22:41:16 JST\",
\"request_id\": \"452d46a9-df6a-40be-889c-58c1183003d8\"
}"
}
2.9.クリーンアップ
2.9.1.Google Cloud側での実行
# Lambda関数の削除
aws lambda delete-function --function-name my-python-container-function
# ECRリポジトリの削除(必要に応じて)
aws ecr delete-repository --repository-name $REPO_NAME --force
# IAMロールの削除
aws iam detach-role-policy \
--role-name lambda-container-role \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
aws iam delete-role --role-name lambda-container-role
2.9.2.AWS側での実行
アクセスキーID
は、2.2で作成した${USER}_access_key.json
ファイルから取得可能
# 変数設定
USER="GoogleCloud_CloudShell"
# IAMユーザーのクリーンアップ
aws iam delete-access-key --user-name $USER --access-key-id ${アクセスキーID}
aws iam detach-user-policy --user-name $USER --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryFullAccess
aws iam detach-user-policy --user-name $USER --policy-arn arn:aws:iam::aws:policy/AWSLambda_FullAccess
aws iam detach-user-policy --user-name $USER --policy-arn arn:aws:iam::aws:policy/IAMFullAccess
aws iam delete-user --user-name $USER
3.おわりに
3.1.得られた知見
- Google CloudのCloudshellからAWS ECRとLambdaを操作する方法の理解
3.2.今後の課題
- 本番環境では一時的な認証情報を使用する方法(IAM Roles Anywhere、SAML連携など)への移行
- マルチクラウド環境における認証情報の一元管理の方法