0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Google Cloud Shell から AWS ECR/Lambdaデプロイ ハンズオン

Posted at

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.本構築の構成図

image.png

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連携など)への移行
  • マルチクラウド環境における認証情報の一元管理の方法
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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?