Lambda関数でSecrets Managerに保存したシークレット情報を取得してみる

Lambda関数でSecrets Managerに保存したシークレット情報を取得してみる

Clock Icon2024.09.17

はじめに

かつまたです。AWSではLambda関数がデータベース等の認証情報を参照する際には、Secrets Managerに保存されている認証情報を取得するといったベストプラクティスがあります。今回はその構成がどのような挙動をしているのか、といった学習のためにLambda関数でSecrets Managerのシークレット情報を取得するまでの手順を試してみました。

ハードコードされたデータベース認証情報をに移動 AWS Secrets Manager - AWS Secrets Manager

シークレットの作成

1.コンソールのSecrets Managerから「新しいシークレットを保存」を選択します。
SecretManeger作成1.png

2.今回検証でのシークレット作成のためシークレットの種類は「その他のシークレットのタイプ」を選択し、任意のキーと値を入力します。シークレット名を入力し作成します。「name」と「pass」のキーを作成しました。
SecretManeger作成2.png

SecretManeger作成3.png

IAMポリシーとIAMロールの作成

ポリシー作成

Lambda関数がSecrets Managerのシークレットにアクセスできるようにするためのポリシーとロールを作成します。

1.「IAM」の「ポリシー」から「ポリシーの作成」を選択します。
ポリシー作成1.png

2.ポリシーエディタに以下のポリシーを記入します。ポリシーに名前を付けて保存します。

json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetSecretValue"
            ],
            "Resource": "Secrets ManagerのARN名"
        }
    ]
}

IAMポリシー作成2.png

IAMポリシー作成3.png

ロール作成

1.「ロール」に移動し「ロールを作成」を選択します。

2.「AWSのサービス」から「Lambda」ロールタイプを選択します。
ロール作成1.png

3.先ほど作成したポリシーを選択し、ロールにアタッチします。ロールに名前を付けて保存します。
IAMロール作成1.png

IAMロール作成2.png

Lambda関数作成

作成したIAMロールを用いて関数を作成します。
1.「Lambda」の「関数の作成」をクリックします。

2.関数名を入力し、ランタイムを選択します(Python 3.x)。「既存のロールを使用する」を選択し、先ほど作成したロールを選択します。「関数の作成」をクリックします。
スクリーンショット 2024-09-13 14.18.48.png

テスト実行

Lambda関数にSecrets Managerのシークレット情報を取得して表示するコードをデプロイし、テストで確認します。
1.作成したLambda関数のコードソースに以下のコードを記入します。「Deploy」ボタンを押下します。

コード例
python
import json
import boto3
import base64
from botocore.exceptions import ClientError

def get_secret():
    secret_name = "katsumata_secretmaneger_lambda"
    region_name = "ap-northeast-1"

    # Create a Secrets Manager client
    session = boto3.session.Session()
    client = session.client(
        service_name='secretsmanager',
        region_name=region_name
    )

    try:
        get_secret_value_response = client.get_secret_value(
            SecretId=secret_name
        )
    except ClientError as e:
        # For a list of exceptions thrown, see
        # https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html
        raise e

    # Decrypts secret using the associated KMS CMK
    if 'SecretString' in get_secret_value_response:
        secret_data = get_secret_value_response['SecretString']
        secret = json.loads(secret_data)  # JSON形式でシークレットを読み込む
    else:
        decoded_binary_secret = base64.b64decode(get_secret_value_response['SecretBinary'])
        secret = json.loads(decoded_binary_secret)  # バイナリ形式の場合もJSON形式に変換

    return secret

def lambda_handler(event, context):
    secret = get_secret()

    # シークレットのキーをログに表示
    name = secret.get('name', 'No name found')
    pw = secret.get('pass', 'No password found')

    print(f'name: {name}, pw: {pw}')

    return {
        "statusCode": 200,
        "body": json.dumps({
            "message": "Successfully retrieved secret",
            "name": name,
            "pw": pw
        })
    }

スクリーンショット 2024-09-13 14.21.31.png

2.テストタブに移動しテストを実行します。ログにシークレット情報が表示され、Lambda関数でのシークレット情報取得を確認することができました。
スクリーンショット 2024-09-13 16.47.28.png

おわりに

今回の検証でSecrets Managerにデータベースの認証情報等のシークレット情報を保存し、Lambda関数でその情報を取得する流れを体感することができました。
ご覧いただきありがとうございました。

参考

https://dev.classmethod.jp/articles/use-secrets-manager-to-set-environment-argument-for-lambda/

アノテーション株式会社について

アノテーション株式会社はクラスメソッドグループのオペレーション専門特化企業です。サポート・運用・開発保守・情シス・バックオフィスの専門チームが、最新 IT テクノロジー、高い技術力、蓄積されたノウハウをフル活用し、お客様の課題解決を行っています。当社は様々な職種でメンバーを募集しています。「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、アノテーション株式会社 採用サイトをぜひご覧ください。

この記事をシェアする

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.