[AWS] EKSマネージドノードグループでLaunch Templatesがサポートされたことで便利になったこと

#はじめに

先日[Amazon EKS](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/what-is-eks.html)のマネージドノードグループでLaunch TemplatesとカスタムAMIが利用できるようになりました。
https://aws.amazon.com/jp/blogs/containers/introducing-launch-template-and-custom-ami-support-in-amazon-eks-managed-node-groups/
これによって、今まで制限のあったマネージドノードグループの設定のカスタマイズが可能となります。

# 今までのマネージドノードグループの不満点

マネージドノードグループは比較的新しい機能と言うこともあり、ところどころ細かいところで不便な部分があると感じています。
以下、マネージドノードグループを試用している中で感じた不満点の一部です。

- ノードインスタンスに任意のセキュリティグループを設定できない
  - インスタンスの通信ルールを追加するためには、EKSが自動生成するセキュリティグループを後から編集する必要があります。
- ノードインスタンスに任意のタグをつけることができない
  - NameタグをつけられないのでEC2のコンソール画面が悲しいことになる
  - コスト配分タグが利用できない
- ノードインスタンスでUser Dataが使えない
  - セッションマネージャの利用に必要なssmエージェントのインストールが困難（これに関してはEKS最適化AMIの方でインストール済みにしてほしい話ではありますが...）

# Launch Templatesを利用した設定例

Launch Templatesがサポートされたことにより、なんと上記で挙げた不満点は全て解消されます。
以降ではそれぞれのケースに関して、実際に[eksctl](https://github.com/weaveworks/eksctl)でノードグループを作成するための設定ファイル例を紹介していきたいと思います。
既存のLaunch Templatesを利用することも勿論可能ですが、eksctlを介してLaunch Templatesを新規作成することもできます（厳密に言うとeksctlの裏でCloudFormationがリソースを作成）。今回紹介する例は後者のパターンとなります。

なお、eksctlではバージョン0.26.0から本機能をサポートしています。
https://github.com/weaveworks/eksctl/releases/tag/0.26.0
また、本記事で紹介していない設定項目については公式のドキュメントを参照してください。
https://eksctl.io/usage/schema/

## 環境

- (EKS) Kubernetesバージョン: 1.17
- eksctlバージョン: 0.26.0

## ノードインスタンスに任意のセキュリティグループを設定する

セキュリティグループは事前に作成しておき、セキュリティグループIDを控えておきます。

```yaml:cluster.yaml
# クラスター設定は省略

managedNodeGroups:
  - name: test1
    instanceType: t3.small
    desiredCapacity: 1
    volumeSize: 8
    securityGroups:
      attachIDs:
        - sg-xxxxxxxxxxxxxx # ここにセキュリティグループIDを記述
```

この設定でノードグループを作成します。

```console
eksctl create nodegroup -f cluster.yaml
```

作成されたノードグループのインスタンスに、設定ファイルで指定されたセキュリティグループが付与されます。

## ノードインスタンスに任意のタグをつける

`tags`下に記述したkey/valueがそのままEC2インスタンスのタグとして付与されます。
ちなみに`tags`の項目は以前から存在していましたが、これまではEC2インスタンスにはタグが付与されない仕様となっていました（「EKSのノードグループ」に対してのタグでしかありませんでした）。

また、`instanceName`と`instancePrefix`という項目が追加されています。
これらを設定すると、EC2インスタンスのNameタグとして付与されます。

下記の設定例であれば、`project: test-project`と`Name: test-ng-instance`の二つのタグがEC2インスタンスに付与されます。

```yaml:cluster.yaml
# クラスター設定は省略

managedNodeGroups:
  - name: test2
    instanceType: t3.small
    desiredCapacity: 1
    volumeSize: 8
    tags:
      project: test-project
    instanceName: ng-instance
    instancePrefix: test
```

## ノードインスタンスでUser Dataを利用してセッションマネージャを使えるようにする

User Dataの使用例としてセッションマネージャを利用するためのssm-agentのインストールの設定をしてみます。

UserDataを追加するには、`preBootstrapCommands`に配列型式で実行したいコマンドを記述します。
下記設定例では、ssm-agentをインストールし、ssm-agentのサービスをスタートさせています。

```yaml:cluster.yaml
# クラスター設定は省略

managedNodeGroups:
  - name: test3
    instanceType: t3.small
    desiredCapacity: 1
    volumeSize: 8
    iam:
      attachPolicyARNs:
        - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
        - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
        - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
    preBootstrapCommands:
      - "sudo yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm"
      - "sudo systemctl enable amazon-ssm-agent"
      - "sudo systemctl start amazon-ssm-agent"
```

一つ注意点ですが、ssm-agentを利用するためにはIAMポリシーの`AmazonSSMManagedInstanceCore`をEC2インスタンスに適用する必要があります。
そこで`iam.attachPolicyARNs`の項目でポリシーを設定する際、独自にアタッチしたいポリシーだけでなく、EKSのノードグループに必要なポリシー（`AmazonEKSWorkerNodePolicy`等）を明示的に記述する必要があります。

参考: https://eksctl.io/usage/iam-policies/#attaching-policies-by-arn

# さいごに

今回はEKSのマネージドノードグループのアップデートにより便利になった点と各ユースケースのeksctl設定ファイルの例を紹介しました。運用上地味に困る部分が解消されて嬉しい限りです。まだまだ発展途上のマネージドノードグループですが、今後のアップデートでますます使いやすくなることを期待です。