Elastic Beanstalk で古い Application Versions は自動で消すようにする

# 概要

CircleCI などを通して ElasticBeanstalk に対して継続的にデプロイしていると、時々 Application Versions の最大数制限に引っかかって失敗してしまいます
これくらい自動で消してくれよ…と思っていたのだが、  AWS CLI 経由であれば自動削除の設定ができるとういことで、試してみました

```shell-session
$ eb deploy YOUR_APP_NAME

WARNING: You have uncommitted changes.
Creating application version archive "app-********".

Uploading: [##################################################] 100% Done...

ERROR: You cannot have more than 500 Application Versions. Either remove some Application Versions or request a limit increase.
```

# 準備

[AWS コマンドラインインターフェイス](https://aws.amazon.com/jp/cli/) をインストールしましょう。
`awsebcli` ではなく `awscli` です。

# 実践

[UpdateApplicationResourceLifecycle \- AWS Elastic Beanstalk](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/api/API_UpdateApplicationResourceLifecycle.html) を参考に進めていきます。

## 今の設定を取得

```shell-session
$ aws elasticbeanstalk describe-applications --application-names YOUR_APP_NAME

{
    "Applications": [
        {
            "ApplicationName": "YOUR_APP_NAME",
            "Description": "Application created from the EB CLI using \"eb init\"",
            "Versions": [
                "app-********",
                ...
                "app-********"
            ],
            "DateCreated": "2017-03-29T12:06:02.417Z",
            "ConfigurationTemplates": [
                "default",
                "variable_environment_setted"
            ],
            "DateUpdated": "2017-03-29T12:06:02.417Z",
            "ResourceLifecycleConfig": {
                "VersionLifecycleConfig": {
                    "MaxCountRule": {
                        "DeleteSourceFromS3": false,
                        "Enabled": false,
                        "MaxCount": 300
                    },
                    "MaxAgeRule": {
                        "DeleteSourceFromS3": false,
                        "Enabled": false,
                        "MaxAgeInDays": 180
                    }
                },
                "ServiceRole": "YOUR_SERVICE_ROLE"
            }
        }
    ]
}
```

自動削除をApplication Version の **数** もしくは **保持日数** のどちらで設定するか決めます。
それぞれ以下の箇所が現在の設定になります。

**数の場合**

```
"MaxCountRule": {
    "DeleteSourceFromS3": false,
    "Enabled": false,
    "MaxCount": 300
}
```

**保持日数の場合**

```
"MaxAgeRule": {
    "DeleteSourceFromS3": false,
    "Enabled": false,
    "MaxAgeInDays": 180
}
```

デフォルトでは両方とも false になっており、自動削除はオフになっています。

## 更新コマンドの詳細

今回は awscli 経由で行いますので、 [update\-application\-resource\-lifecycle](http://docs.aws.amazon.com/cli/latest/reference/elasticbeanstalk/update-application-resource-lifecycle.html) を利用します。

以下のオプションを指定してコマンドを実行します。

| key | value |
| --- | --- |
| --application-name | アプリケーションの名前 |
| --resource-lifecycle-config | 自動削除の設定 |


`--resource-lifecycle-config` は以下の構造になっています。

```json
{
  "ServiceRole": "string",
  "VersionLifecycleConfig": {
    "MaxCountRule": {
      "Enabled": true|false,
      "MaxCount": integer,
      "DeleteSourceFromS3": true|false
    },
    "MaxAgeRule": {
      "Enabled": true|false,
      "MaxAgeInDays": integer,
      "DeleteSourceFromS3": true|false
    }
  }
}
```

これを `--cli-input-json` オプションを付けて JSON 形式で指定するか、オプションなしで以下のように送ります。

```
ServiceRole=string,VersionLifecycleConfig={MaxCountRule={Enabled=boolean,MaxCount=integer,DeleteSourceFromS3=boolean},MaxAgeRule={Enabled=boolean,MaxAgeInDays=integer,DeleteSourceFromS3=boolean}}
```

## 設定変更

**数の場合**

300個で自動削除するようにしてみましょう

```shell-session
$ aws elasticbeanstalk update-application-resource-lifecycle \
    --application-name YOUR_APP_NAME \
    --resource-lifecycle-config "ServiceRole=YOUR_SERVICE_ROLE,VersionLifecycleConfig={MaxCountRule={Enabled=true,MaxCount=300,DeleteSourceFromS3=true}}"
{
    "ApplicationName": "YOUR_APP_NAME",
    "ResourceLifecycleConfig": {
        "VersionLifecycleConfig": {
            "MaxCountRule": {
                "DeleteSourceFromS3": true,
                "Enabled": true,
                "MaxCount": 300
            },
            "MaxAgeRule": {
                "DeleteSourceFromS3": false,
                "Enabled": false,
                "MaxAgeInDays": 180
            }
        },
        "ServiceRole": "YOUR_SERVICE_ROLE"
    }
}
```

**日数の場合**

60日で自動削除するようにしてみましょう

```shell-session
$ aws elasticbeanstalk update-application-resource-lifecycle \
    --application-name YOUR_APP_NAME \
    --resource-lifecycle-config "ServiceRole=YOUR_SERVICE_ROLE,VersionLifecycleConfig={MaxAgeRule={Enabled=true,MaxAgeInDays=60,DeleteSourceFromS3=true}}"
{
    "ApplicationName": "YOUR_APP_NAME",
    "ResourceLifecycleConfig": {
        "VersionLifecycleConfig": {
            "MaxCountRule": {
                "DeleteSourceFromS3": false,
                "Enabled": false,
                "MaxCount": 300
            },
            "MaxAgeRule": {
                "DeleteSourceFromS3": true,
                "Enabled": true,
                "MaxAgeInDays": 60
            }
        },
        "ServiceRole": "YOUR_SERVICE_ROLE"
    }
}
```

なお、数と日数を同時にしていすると以下のように怒られます。

```shell-session
$ aws elasticbeanstalk update-application-resource-lifecycle \
    --application-name YOUR_APP_NAME \
    --resource-lifecycle-config "ServiceRole=YOUR_SERVICE_ROLE,VersionLifecycleConfig={MaxCountRule={Enabled=true,MaxCount=300,DeleteSourceFromS3=true},MaxAgeRule={Enabled=true,MaxAgeInDays=30,DeleteSourceFromS3=true}}"

An error occurred (InvalidParameterValue) when calling the UpdateApplicationResourceLifecycle operation: 'MaxAgeRule' and 'MaxCountRule' cannot be enabled simultaneously.
```

# 所感

なんでこれがデフォルト設定されていないかつ Web Console から設定できないんでしょうね 🤔

# その後

@yasuhiroki さんからコメントを頂きまして、 WebConsole 上から設定ができるようになったようです :tada: 

ElasticBeanstalk のアプリケーションバージョンから設定できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/36620/e43a4452-6eb7-ff63-1f45-b99cad33e29e.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/36620/bff21d6d-9f7c-418c-136e-de0dbaf893ff.png)

便利になりました〜 :pray: