AWS EKS構築のためMFA設定IAMユーザーでeksctl実行

# はじめに
AWS EKSが東京リージョンで公開されたタイミングと時を同じくしてEKSを触ってみるチャンスを得た。予めチュートリアルは見ていたが、「[eksctl](https://github.com/weaveworks/eksctl)」なるものがあるよと[Twitter](https://twitter.com/search?src=typd&q=eksctl)で出回っていたので、せっかくならということでeksctlでトライした。

手元の環境がセキュリティベストプラクティスに倣いMFAを有効化してあるため、eksctlの利用には一工夫必要でした。その対応方法について記載する。

# 環境

作業端末：Windows10 Subsystem for Linux(Ubuntu16.04)
AWS CLI：aws-cli/1.16.81
IAMユーザー：Admin権限あり、MFA有効化

# MFAトークンの利用
## 一時トークンの払い出し

AWSのガイドにあるように、MFA有効化したIAMユーザーアカウント権限でAWS CLIを利用するためには、一時的なセッショントークンを作成＆利用する必要がある。

[AWS CLI 経由で AWS リソースへのアクセスを認証するには、どのように MFA トークンを使用したらよいですか?](https://aws.amazon.com/jp/premiumsupport/knowledge-center/authenticate-mfa-cli/)
まず上記リンク先の方法で一時トークンを出力させる。実行例は上記リンク先参考。

>$ aws sts get-session-token --serial-number arn-of-the-mfa-device --token-code code-from-token

arn-of-the-mfa-device：IAMユーザーの認証情報＞MFAデバイスの割り当てを参照
なお、一時セッショントークンの有効期間はデフォルトで12時間。


## 一時トークンをProfileに設定

今後は--profileオプションで一時トークンの設定を呼び出しできるように先程取得した一時トークンをプロファイルに登録しておく。
”mfa”というプロファイル名で追加登録する。

```ruby:.aws/config
$ cat .aws/config
[default]
output = json
region = us-east-1

[profile mfa]
output = json
region = us-east-1
aws_access_key_id = <Access-key-as-in-returned-output>
aws_secret_access_key = <Secret-access-key-as-in-returned-output>
aws_session_token = <Session-Token-as-in-returned-output>
```

ちなみに、当初下記のようにprofileが無いと怒られてAWS CLIが実行できなかったが、profile名の記載方法が間違っていた。単なる[mfa]ではなく[profile mfa]と設定しないと行けなかった。

```ruby:profile名の頭にはprofileとつけること
$ aws ec2 describe-instances --profile mfa

The config profile (mfa) could not be found
```

- profileオプションをつけて実行確認

```
$ aws ec2 describe-instances --profile mfa
{
    "Reservations": [
        {
            "Instances": [
                {
                    "Monitoring": {
                        "State": "disabled"
                    },
                    "PublicDnsName": "",
                    "StateReason": {
                        "Message": "Client.UserInitiatedShutdown: User initiated shutdown",
                        "Code": "Client.UserInitiatedShutdown"
                    },
                    "State": {
                        "Code": 80,
                        "Name": "stopped"
                    },
                    "EbsOptimized": false,
                    "LaunchTime": "2018-12-21T04:33:14.000Z",
以下省略
```
→ OK。

一時トークンの有効期限が過ぎると、再度この設定をし直す必要がある。


#eksctlの準備

ここはeksctlの準備の話はメインではないので、リンク情報のみ記載する。

ekscltインストール
https://github.com/weaveworks/eksctl

kubectlインストール
https://kubernetes.io/docs/tasks/tools/install-kubectl/

kubectl を Amazon EKS 用に設定
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/configure-kubectl.html

# profileオプションを使用したeksctlの実行

ようやく本題のeksctlをMFAの一時トークンを使用する。
使用方法はAWS CLIの実行時と同じで--profileオプションを追加するだけ。

```
$ eksctl xxx --profile mfa
```

クラスター構築の際はこんな感じでオプションに追加する。

```
$ eksctl create cluster \
  --name hoge \
  --region us-east-1 \
  --nodes 3 \
  --nodes-min 1 \
  --nodes-max 3 \
  --node-type t2.medium \
  --version=1.10 \
  --tags name=fuga \
  --profile mfa
```

profileオプションを付けないと以下のように失敗する。

```
$ eksctl get cluster
[✖]  checking AWS CloudFormation access – cannot list stacks: AccessDenied: User: arn:aws:iam::xxx:user/xxxx is not authorized to perform: cloudformation:ListStacks with an explicit deny
        status code: 403, request id: xxxxx
```

#EKSクラスターを作ってみた

クラスター構築はこちらを参考。
https://qiita.com/arakawa_moriyuki/items/b01a3294f141feeaf54e

クラスター情報を参照

```
$ eksctl get cluster --profile mfa
NAME                            REGION
hoge                           us-east-1
```

こちらがeksctlコマンドでクラスター作成する際に自動で作成されるkubectlのconfig情報。

```ruby:.kube/config
$ cat .kube/config
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: xxx
    server: https://xxx.us-east-1.eks.amazonaws.com
  name: hoge.us-east-1.eksctl.io
contexts:
- context:
    cluster: hoge.us-east-1.eksctl.io
    user: xxx@hoge.us-east-1.eksctl.io
  name: xxx@hoge.us-east-1.eksctl.io
current-context: xxx@hoge.us-east-1.eksctl.io
kind: Config
preferences: {}
users:
- name: xxx@hoge.us-east-1.eksctl.io
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1alpha1
      args:
      - token
      - -i
      - hoge
      command: aws-iam-authenticator
      env:
      - name: AWS_PROFILE
        value: mfa
```

なんと、.kube/configの中にも一時トークンのprofile情報が追記されている（最下部）。

ちなみに、kubectlコマンドの実行の際はprofileオプションは不要。

```
$ kubectl get nodes
NAME                             STATUS   ROLES    AGE   VERSION
ip-192-168-27-178.ec2.internal   Ready    <none>   54m   v1.10.11
ip-192-168-49-72.ec2.internal    Ready    <none>   53m   v1.10.11
ip-192-168-8-92.ec2.internal     Ready    <none>   53m   v1.10.11
```

ただし、MFAの一時トークンの有効期限が切れるとkubectlもエラーとなり使用できない。そのため、再度一時トークンの設定が必要になる。

# まとめ
MFAを設定したIAMユーザー権限でも一時トークンをプロファイルに設定＆利用することで、eksctlの使用は可能。


それにしてもeksctlはめちゃくちゃ便利！