AWS CLIのプロファイル切り替えをいい感じにする

# はじめに

## AWSのプロファイルについて

AWSで複数のアカウントを使い分けたい場合など、[プロファイル](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-multiple-profiles.html) を定義して切り替えるのが良いと思います。

プロファイルの切り替えは、

* コマンド実行時に都度指定する方法

```sh
$ aws s3 ls --profile example
```

* 環境変数 `AWS_PROFILE` で切り替える方法

```sh
$ export AWS_PROFILE=example
$ aws s3 ls
```

のいずれかで行います。

また、環境変数 `AWS_PROFILE` で切り替える場合に、現在設定されているプロファイルを確認するには、

```sh
$ aws configure list
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                   example           manual    --profile
access_key     ******************** shared-credentials-file
secret_key     ******************** shared-credentials-file
    region           ap-northeast-1      config-file    ~/.aws/config
```

または

```sh
$ echo $AWS_PROFILE
example
```

で確認できます。

## この記事の内容

プロファイルは便利な仕組みですが、コマンド実行時に都度指定するのは面倒ですし、環境変数で切り替えるのもコマンドが面倒な感じです。

と言うわけで、ここではプロファイル切り替えと確認をいい感じにする手順を紹介します。

この手順でセットアップすると、以下のような感じで **awsp コマンドでプロファイルを切り替え、プロンプトで選択しているプロファイルを確認できる** ようになります。

* プロファイル名を指定して切り替え

```sh
crossroad0201@my-macbookpro|~/develop/work
$ awsp example
Set AWS_PROFILE=example.

crossroad0201@my-macbookpro|~/develop/work / AWS:example
$ 
```

* プロファイルを選択肢から選んで切り替え
  * 2018/09/28 時点での [awsp](https://github.com/johnnyopao/awsp) には、プロファイル選択を解除した場合に環境変数 `AWS_PROFILE` が unset されずに値が空の状態で残ってしまい、正しく選択解除されない問題があるため、プロファイル選択を解除するには `unset AWS_PROFILE` する必要があります。

```sh
crossroad0201@my-macbookpro|~/develop/work
$ awsp
AWS Profile Switcher
? Choose a profile (Use arrow keys)
❯ example
  example2
  example3
  *clear*

crossroad0201@my-macbookpro|~/develop/work / AWS:example
$ 
```

なお、この手順ではシェルとして **zsh** を使っていることと、zshの拡張フレームワークとして [Prezto](https://github.com/sorin-ionescu/prezto) を導入している前提としています。
（参考→ [Macのzshでプロンプトをカスタマイズしたり、コマンド履歴を検索したりできるようにする](https://qiita.com/crossroad0201/items/7b8db9fc8c6f85562a66)）

**zsh** および **Prezto** 以外を使っている場合は、使用している環境に応じて読み替えてください。

# 手順

## プロファイルの選択を便利にする

まずは [awsp](https://github.com/johnnyopao/awsp) と言うツールを導入して、プロファイルの選択を改善します。
これは、`awsp` コマンドを打つと、選択可能なプロファイルの一覧が表示され、そこからプロファイルを選択できる、と言うものです。

ただ、`awsp` コマンドには引数として切り替え先プロファイルを指定することができないため、あらかじめ切り替え先プロファイルが自明な場合でも常にインタラクティブにプロファイルを選択しなければならないのが不便です。

そこで、**awsp** をラップするシェル関数を定義して、

* プロファイル名が引数として与えられていればそのプロファイルに切り替える。
* 引数が与えられていなければ **awsp** を起動してプロファイルを選択させる。

のようにします。

### awspのインストール

**npm** でインストールします。（あらかじめ、**node** と **npm** のインストールが必要です）

```sh
$ npm install -g awsp
```

[公式のインストール手順](https://github.com/johnnyopao/awsp#setup) では `awsp` を言うエイリアスを切っていますが、この手順ではエイリアスは作成せず、後述の関数を定義します。

### awsp関数の定義

`~/.zshrc`（**bash** では `~/.bashprofile`） に、以下のような `awsp` 関数を定義します。

* `AWS_PROFILE` だけでなく、`AWS_DEFAULT_PROFILE` もセットするのがポイントです。
（一部のツールには `AWS_DEFAULT_PROFILE` を参照するものがあります）

```sh:~/.zshrc
function awsp() {
  if [ $# -ge 1 ]; then
    export AWS_PROFILE="$1"
    echo "Set AWS_PROFILE=$AWS_PROFILE."
  else
    source _awsp
  fi
  export AWS_DEFAULT_PROFILE=$AWS_PROFILE
}
```

## プロンプトにAWSプロファイルを表示する

次に、**Prezto**でプロンプトをカスタマイズし、選択しているプロファイルを表示するようにします。

**zsh** + **Prezto** ではない場合は、その環境に応じてカスタマイズしてください。（[awspのガイド](https://github.com/johnnyopao/awsp#show-your-aws-profile-in-your-shell-prompt) にも例があります）
### Preztoテーマのカスタマイズ

**Prezto** でプロンプトをカスタマイズにするには、`/Users/USER/.zprezto/modules/prompt/functions` 下にあるテーマのスクリプト `prompt_THEME_setup` を編集します。

```sh:prompt_THEME_setup
  :

# 1.環境変数 AWS_PROFILE から、プロンプトに表示する文字列を作るフック関数を定義
function prompt_awsprof_precmd {
  profile="${AWS_PROFILE}"
  if [[ -z "${profile}" ]]; then
     _prompt_awsprof=""
  else
     _prompt_awsprof="/ AWS:%F{magenta}${profile}%f"
  fi
}

function prompt_THEME_setup {
  :

  # 2.フック関数を登録
  add-zsh-hook precmd prompt_awsprof_precmd

  # 3.プロンプトに、プロファイル表示を追加
  PROMPT='%(?..%F{red}%B-> [%?]%b%f
)%F{magenta}%n%f@%F{yellow}%m%f|%F{green}${_prompt_giddie_pwd}%f${vcs_info_msg_0_} ${_prompt_awsprof}
%F{blue}${_prompt_giddie_symbol}%f '

  :
}
```

1. フック関数を定義します。 
この関数では、環境変数 `AWS_PROFILE` にセットされたプロファイルを取得し、プロンプトに表示するための文字列を生成して、任意の環境変数（この例では `_prompt_awsprof`）にセットします。 
プロファイルがセットされていない場合は、プロンプトの表示を消すようにします。


2. 作成したフック関数をzshから呼び出されるように登録します。


3. プロンプトの、プロファイルを表示させたい場所に、フック関数で表示文字列をセットした環境変数を挿入します。


* 参考→ [Shell Awesomeness With Prezto](http://joshsymonds.com/blog/2014/06/12/shell-awesomeness-with-prezto/)


以上で完了です。