長期間使用していない AWS Lambda の inactive 状態を active 状態にする方法を備忘録として残しておく
事象
関数が数週間アイドルのままの場合、Inactive 状態になり、その状態で関数を呼び出すとエラーになる
詳細は以下を参照
対象の洗い出し
以下のスクリプトを AWS CLI にて使用することで対象の洗い出しが行える
#!/bin/sh
aws --profile <<プロフィール名>> lambda list-functions --region <<リージョン名>> --query 'Functions[?starts_with(FunctionName, `<<関数名プレフィックス>>`) == `true`].FunctionName' > lambda_list.json
lambda_names=`jq -r .[] lambda_list.json`
for lambda_name in $lambda_names; do
aws --profile <<プロフィール名>> lambda get-function --output text --function-name $lambda_name --query 'Configuration.[FunctionName, State, LastUpdateStatus]' | sort -k 1 | column -t -s "`printf '\t'`"
done
解消方法
inactive の状態で lambda を実行するとエラーになるがしばらくすると active 状態となり実行可能となる
もしくは、以下のスクリプトを AWS Console 上で実行することで inactive => active に状態を更新できる
#!/bin/bash -eu
all_lambda_name_list=()
inactive_lambda_name_list=()
# 最初にアカウント上のすべての関数名を取得
function get_all_lambda_name_list() {
echo "【Start get_all_lambda_name_list】$(date "+%Y/%m/%d %H:%M:%S")"
readonly lambda_list=$(aws lambda list-functions \
| jq -r '.Functions')
len=$(echo $lambda_list | jq length)
for i in $( seq 0 $(($len - 1)) ); do
all_lambda_name_list+=($(echo $lambda_list | jq -r .[$i].FunctionName))
done
echo "【End get_all_lambda_name_list】$(date "+%Y/%m/%d %H:%M:%S")"
}
# 関数が state = Active かどうかの判定
function is_lambda_active() {
local lambda_name=$1
local state=$(aws lambda get-function-configuration \
--function-name $lambda_name \
| jq -r '.State')
if [ $state = "Active" ]; then
echo "true"
else
echo "false"
fi
}
# Active でない関数のみを抽出
function filter_inactive_resources() {
echo "【Start filter_inactive_resources】$(date "+%Y/%m/%d %H:%M:%S")"
for lambda_name in ${all_lambda_name_list[@]}; do
is_active=$(is_lambda_active $lambda_name)
if [ "${is_active}" = "false" ]; then
echo $lambda_name
inactive_lambda_name_list+=($lambda_name)
fi
done
echo "【End filter_inactive_resources】$(date "+%Y/%m/%d %H:%M:%S")"
}
# Active でない関数に対して publish-version を実行する
function publish_lambda() {
echo "【Start publish_lambda】$(date "+%Y/%m/%d %H:%M:%S")"
if [ ${#inactive_lambda_name_list[@]} -eq 0 ]; then
echo "there is no lambda to publish"
return 0
fi
for lambda_name in ${inactive_lambda_name_list[@]}; do
echo "now publishing ${lambda_name}"
aws lambda publish-version --function-name $lambda_name
aws lambda wait function-active --function-name $lambda_name # 関数が Active になるまで待機
done
echo "【End publish_lambda】$(date "+%Y/%m/%d %H:%M:%S")"
}
echo "【Start Processing】$(date "+%Y/%m/%d %H:%M:%S")"
get_all_lambda_name_list
filter_inactive_resources
publish_lambda
echo "【End Processing】$(date "+%Y/%m/%d %H:%M:%S")"
AWS CLI で実行する場合は以下を参考にする
#!/bin/sh
# Shared
AWS_PROFILE_PREFIX={AWS プロファイルのプレフィックス} #自分の設定に書き換える
LOG_FILE=log/make_active_all_lambda.log
all_lambda_name_list=()
inactive_lambda_name_list=()
read -p "Which environment connect to? (dev/stg/prd): " input_environment
# Check the environment
case "${input_environment}" in
"dev" | "stg" | "prd")
echo "Connecting to ${environment} environment..." >> ${LOG_FILE} 2>&1
if [ $input_environment = "prd" ]; then
# AWS MFA Authentication
aws-mfa --profile=${AWS_PROFILE_PREFIX}-${input_environment}
fi;;
*)
echo "Please enter the correct environment." >> ${LOG_FILE} 2>&1
echo "【End Processing】$(date "+%Y/%m/%d %H:%M:%S")" >> ${LOG_FILE} 2>&1
exit;;
esac
# アカウント内全ての関数名を取得
function get_all_lambda_name_list() {
readonly lambda_list=$(aws lambda --profile=${AWS_PROFILE_PREFIX}-${input_environment} list-functions \
| jq -r '.Functions')
len=$(echo $lambda_list | jq length)
for i in $( seq 0 $(($len - 1)) ); do
all_lambda_name_list+=($(echo $lambda_list | jq -r .[$i].FunctionName))
done
}
# 関数の state == Active かどうかを返す
function is_lambda_active() {
local lambda_name=$1
local state=$(aws lambda --profile=${AWS_PROFILE_PREFIX}-${input_environment} get-function-configuration \
--function-name $lambda_name \
| jq -r '.State')
if [ $state = "Active" ]; then
echo "true"
else
echo "false"
fi
}
# 関数の state == Active でないものを抽出
function filter_inactive_resources() {
echo "== following lambda is inactive ==" >> ${LOG_FILE} 2>&1
for lambda_name in ${all_lambda_name_list[@]}; do
is_active=$(is_lambda_active $lambda_name)
if [ "${is_active}" = "false" ]; then
echo $lambda_name
inactive_lambda_name_list+=($lambda_name)
fi
done
echo "== that's all ==" >> ${LOG_FILE} 2>&1
}
# 関数を Active にする
function publish_lambda() {
if [ ${#inactive_lambda_name_list[@]} -eq 0 ]; then
echo "there is no lambda to publish" >> ${LOG_FILE} 2>&1
return 0
fi
for lambda_name in ${inactive_lambda_name_list[@]}; do
echo "now publishing ${lambda_name}" >> ${LOG_FILE} 2>&1
aws lambda --profile=${AWS_PROFILE_PREFIX}-${input_environment} publish-version --function-name $lambda_name
aws lambda --profile=${AWS_PROFILE_PREFIX}-${input_environment} wait function-active --function-name $lambda_name # 関数が Active になるまで待つ
done
}
echo "【Start Processing】$(date "+%Y/%m/%d %H:%M:%S")" >> ${LOG_FILE} 2>&1
get_all_lambda_name_list
filter_inactive_resources
publish_lambda
echo "【End Processing】$(date "+%Y/%m/%d %H:%M:%S")" >> ${LOG_FILE} 2>&1