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 にも対応したスクリプトを書きました。