Inactive状態のLambdaの関数を一括で起動してやる

アカウント上に存在するアイドル状態のLamnda関数を全部起動したいことがあったのでそのやり方をメモします。

# そもそもなんでそんなことやりたかったの？
Lambdaは非常に便利ですが、数週間アイドル状態が続くと関数がInactive状態になります。そしてInactive状態になった関数を起動しようとすると最初は起動に失敗します。

このせいで若干トラブったので、**いっそのこと定期的にアカウント上に存在するすべてのLambndaを起動してしまえ**ということで、AWSCLIでLambdaを一括で起動するシェルを作成しました。

>Lambdaサービスが設定されたリソースを回収するのに十分な時間アイドルになっている関数は、Inactive状態に移行します。Inactive状態の関数を呼び出すと、失敗し、それらのリソースが再作成されるまで関数はPending状態に設定されます。リソースの再作成に失敗した場合、関数はInactive状態に戻ります。

[AWS Lambda関数の状態の追跡](https://aws.amazon.com/jp/blogs/news/tracking-the-state-of-lambda-functions/)より引用

![関数の状態のライフサイクル](https://d2908q01vomqb2.cloudfront.net/1b6453892473a467d07372d45eb05abc2031647a/2019/11/28/Screen-Shot-2019-11-15-at-5.17.36-PM-1024x557.png)

**実行環境**

```
$ aws --version
aws-cli/1.18.219 Python/3.6.0 Windows/10 botocore/1.19.59

$ bash --version
GNU bash, version 4.3.42(5)-release (x86_64-pc-msys)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
```

# でも、どうやって起動するの？

Lambdaのリファレンスを読みましたが、そもそも「起動する」というコマンドは用意されていないそうです。起動するには [invoke](https://docs.aws.amazon.com/cli/latest/reference/lambda/invoke.html#invoke)（実際にラムダを実行するためのコマンド）しか用意されていなそうでしたが、がんばって漁ってみたところ [publish-version](https://docs.aws.amazon.com/cli/latest/reference/lambda/publish-version.html)というコマンドを発見しました。


>Creates a version from the current code and configuration of a function. Use versions to create a snapshot of your function code and configuration that doesn't change.

>AWS Lambda doesn't publish a version if the function's configuration and code haven't changed since the last version. Use UpdateFunctionCode or UpdateFunctionConfiguration to update the function before publishing a version.


本来は関数のバージョン管理のためのコマンドみたいですが、関数に変更ない場合は何も更新しないとのこと。でもこのコマンドを実行すると、なんと関数が起動されました！！

ということでこれを利用すればすべての関数を起動できそうです。

# 最終的に出来たシェルがこちら

```shell:make_active_all_lambda.sh
#!/bin/bash -eu

all_lambda_name_list=()
inactive_lambda_name_list=()

# 最初にアカウント上に存在するすべての関数名を取得
function get_all_lambda_name_list() {

    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
}

# 関数が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 == following lambda is inacive ==
    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 == thst\'s all ==
}

# Avctiveじゃない関数をpublish-versionする
function publish_lambda() {
    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
}


get_all_lambda_name_list
filter_inactive_resources
publish_lambda

```


# 気になっていること

関数は起動するだけではお金はかからないはずですが、AWS側にとってはあんまりやってほしくないことなんですかね？もしこの辺詳しい人がいたら教えてほしいです！

できればInactive状態でのinvokeでも、失敗にしないで起動させてから実行するまでやってほしいなあ。