一時クレデンシャルを取得するserverlessコマンドのラッパースクリプト

EC2にアタッチされたIAM Roleからassume roleして、一時クレデンシャルを取得して、Serverless Frameworkを実行するスクリプトを書きました。

serverlessコマンドのラッパーとして機能する簡易的なスクリプトです。

--aws-profile が指定されていた場合に ~/.aws/config を読み込み、 credential_source=EC2InstanceMetadata かつ role_arn が指定されていた場合は、一時クレデンシャルを取得してserverlessコマンドを実行します。それ以外の場合は、なにも加工せずにそのままserverlessを実行します。

スクリプト

シェルスクリプトですが、Pythonコードも埋め込まれています。

#!/bin/bash

# serverlessコマンドのラッパーとして機能する簡易的なスクリプト。
#
# 最初のオプションで --aws-profile が指定されていた場合に
# ~/.aws/config を読み込み、
# credential_source=EC2InstanceMetadata かつ role_arn が指定されていた場合は、
# 一時クレデンシャルを取得してserverlessを実行する。
# それ以外の場合は、なにもせずにserverlessを実行する。

profile=
if [ $# -ge 2 ]; then
    if [ "$1" = --aws-profile ]; then
        profile="$2"
    fi
fi

if [ -z "$profile" ]; then
    # そのままserverlessを実行
    echo serverless "$@"
    exec serverless "$@"
fi

################################
# .aws/config から role_arn を取得
################################

role_arn=$(python <<EOF
import configparser
import os

home_path = "$HOME"

aws_config_filepath = home_path + "/.aws/config"

profile = "$profile"

def fetch_aws_config_role_arn(profile):
    if not os.path.exists(aws_config_filepath):
        return None

    aws_config = configparser.ConfigParser()
    aws_config.read(aws_config_filepath)

    section_name = "profile " + profile
    try:
        credential_source = aws_config.get(section_name, "credential_source")
    except configparser.NoOptionError:
        return None
    except configparser.NoSectionError:
        return None
    if credential_source != "Ec2InstanceMetadata":
        return None
    try:
        role_arn = aws_config.get(section_name, "role_arn")
    except configparser.NoOptionError:
        return None
    return role_arn

role_arn = fetch_aws_config_role_arn(profile)
if role_arn != None:
    print(role_arn)
EOF
)

################################

if [ -n "$role_arn" ]; then # role_arn が取得できた場合
    # 一時クレデンシャルを取得
    echo aws sts assume-role --role-arn $role_arn --role-session-name serverless-deploy
    json=$(aws sts assume-role --role-arn $role_arn --role-session-name serverless-deploy)
    export AWS_ACCESS_KEY_ID=$(echo $json | jq ".Credentials.AccessKeyId" -r)
    export AWS_SECRET_ACCESS_KEY=$(echo $json | jq ".Credentials.SecretAccessKey" -r)
    export AWS_SESSION_TOKEN=$(echo $json | jq ".Credentials.SessionToken" -r)

    # --aws-profile の指定を削除してserverlessを実行
    shift
    shift
    echo serverless "$@"
    exec serverless "$@"
fi

# そのままserverlessを実行
echo serverless "$@"
exec serverless "$@"

################################

適当な名前で実行権限を付けて、PATHの通るところに置けば、普通のserverlessコマンドと同じように動かせます。

リンク

このスクリプトに至る経緯

追記

source_profile にも対応したスクリプトを書きました。

suzuki-navi.hatenablog.com