AWS CLIのためだけにcimg/pythonを使う必要はない

CircleCIでAWS CLIを使うために、cimg/python(circleci/python)イメージを使い、pipでインストールしている人も多いかと思います。

以前はAWS CLIがPythonに依存していたので、Pythonが入ったイメージを使うのが効率的でした。ですが現行バージョンのAWS CLI v2は依存関係がないバイナリで提供されるので、Pythonがない環境でも動作します。したがってCircleCIでAWS CLIを使うだけならcimg/baseで問題ありません。

# pipでインストールできるAWS CLIは非推奨バージョン

そもそも現行のv2はPyPIに公開されていないので、pipでインストールできません。これは意図的だそうです。反発も多くGitHubのIssueは相当荒れた結果、ロックされました。

[publish v2 to PyPI](https://github.com/aws/aws-cli/issues/4947)

AWSとしてはv1はすでに推奨しておらず、v2の機能が必ずしもバックポートされないことが明記されています。今から使うならv2一択でしょう。

```
AWS CLI CLI バージョン 1 はオリジナルの AWS CLI CLI であり、引き続きサポートしています。ただし、‭AWS CLI‬ CLI バージョン 2 で導入された主な新機能は、‭AWS CLI‬ バージョン 1 にバックポートされない場合があります。これらの機能を使用するには、AWS CLI CLI バージョン 2 をインストールする必要があります。
```

[AWS CLI のバージョンについて](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/welcome-versions.html)

ですがPyPIのダウンロードランキングによれば、awscli v1の順位は2021/12/05時点でWeekly9位、Monthly12位と相当な人気です。

[PyPI Stats](https://pypistats.org/top)
![PyPIランキング](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19807/40f8d05b-eb53-6c2d-addf-37bd399959c0.png)


# AWS CLI v2のインストール

Orbが使える環境では公式の[aws-cli Orb](https://circleci.com/developer/ja/orbs/orb/circleci/aws-cli)を使うと楽です。

Orbが使えない環境でもインストールは特に難しいことはなく、アーカイブを解凍してインストールするだけです。x86_64 Linux Executerで最新版CLIを使うならこんな感じです。

```yaml
- run:
          name: install aws-cli(binary)
          command: |
            curl -s "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
            unzip -q awscliv2.zip
            sudo ./aws/install
            aws --version
```

# Pagerに関する注意

AWS CLI v2では出力がless経由になります。手動で実行しているときは便利なこともありますが、CIは失敗します。このためpagerの無効化が必要です。

[破壊的変更 - AWS CLI バージョン 1 からバージョン 2 への移行](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cliv2-migration.html#cliv2-migration-output-pager)

無効化にはいくつかやり方はありますが、一例としてenvironmentで`PAGER=cat`を与えるとpagerがcatになり、止まらなくなります。

他にも`AWS_PAGER=""`などでも無効化できるようです。

```yaml
environment:
      PAGER: cat
```

# インストール速度比較

下記config.ymlで簡単な速度比較を行ってみました。実行環境によって実行時間も変わってくるので、目安と思ってください。

```yaml
version: 2
jobs:
  cli-pip:
    docker: 
      - image: cimg/python:3.10
    steps:
      - checkout
      - run:
          name: install aws-cli(pip)
          command: |
            pip3 -q install awscli
            aws --version
  cli-binary:
    docker: 
      - image: cimg/base:stable
    steps:
      - checkout
      - run:
          name: install aws-cli(binary)
          command: |
            curl -s "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
            unzip -q awscliv2.zip
            sudo ./aws/install
            aws --version
workflows:
  version: 2
  benchmark: 
    jobs:
    - cli-pip
    - cli-binary
```

## pip経由でインストールした場合

13秒かかりました
![pip install](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19807/ff3c331b-4b68-9b15-5710-4a4a03b45548.png)


## バイナリでインストールした場合

4秒かかりました
![binary install](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19807/f11633ca-25ca-31f2-cd46-d77cc78697f3.png)


## AWS CLIが初めから入ったイメージはないの?

AWS公式でaws-cli Dockerイメージを提供していますが、gitやsshなどが入っていないので、CIで使うには向いていません。

[amazon/aws-cli](https://hub.docker.com/r/amazon/aws-cli)

# まとめ

- CircleCIでAWS CLIを使うなら、pip installではなく、パッケージインストールの方が効率的
- デフォルトだと出力が途中で止まってしまうので、Pagerの無効化は必須