Alpine 3.14.0 の Breaking Changes に気をつけろ！ 〜 Terraform Enterprise も突然壊れる

この記事は [Recruit Advent Calendar 2021](https://adventar.org/calendars/6663) の19日目の記事です。

# 私たちのTerraform Enterpriseの運用

Terraform Enterpriseは、[Terraform Cloud](https://www.terraform.io/cloud)のようなHashiCorp謹製Terraform CI/CD環境を、自分たちのインフラで実行できる製品です。

EC2上で実行する場合、[Minimum Requirementsとしてm5.xlargeインスタンスが必要](https://www.terraform.io/enterprise/before-installing/reference-architecture/aws)ですので、私たちはコスト最適化のために[SpotFleet](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/spot-fleet.html)を利用して実行していました。

SpotFleetを利用していると、Spotリクエストの中断により、インスタンスが生え変わることがあります。そのため、私たちの環境ではインスタンスが生え変わった際に最新版のTerraform Enterpriseで起動するよう設定していました。

通常、Spotリクエストの中断によって実行中のインスタンスが停止すると、即座に別のインスタンスのSpotリクエストが作成され、最新版のTerraform Enterpriseが起動してきます。その際のHealtyHostCountメトリクスはこのような形になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151115/513d53db-4d9f-6383-830c-983c0c16842d.png)

この場合、数分のサービス中断はありますが、大きな問題とはなりません。（私たちはこういった中断を許容することでコスト最適化するという選択をしています）

# 11/13に起こったこと

ところが、11/13には、中断して再作成されたSpotインスタンス上のTerraform Enterpriseが正常に起動しませんでした。そのため、HealtyHostCountも0のままとなっていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151115/095d38db-8360-a789-1067-c33e6c249dfc.png)

同じ時間帯のCPUUtilizationメトリクスはこちらです。何らかの処理が、半数以上のvCPUを専有したまま正常に動作しない状態になっているようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151115/9f0b02c8-45aa-5e14-357e-323c7428cdbd.png)

ちょうどこの日、Terraform Enterpriseに [v202111-1](https://github.com/hashicorp/terraform-enterprise-release-notes/blob/master/v202111-1.md) というバージョンがリリースされていました。

そこには、以下のようなBreaking Changesの記述があります。

> Certain application container images were updated to use Alpine 3.14 which has specific Docker, `runc`, and `libseccomp` version requirements. Please refer to [the Alpine 3.14 release notes](https://wiki.alpinelinux.org/wiki/Release_Notes_for_Alpine_3.14.0#faccessat2) to determine if your installation meets these new requirements before upgrading.

また、Alpine 3.14のリリースノートには以下の記述があります。

> Docker 20.10.0 (which contains moby commit a181391) or greater, **AND** libseccomp 2.4.4 (which contains backported libseccomp commit 5696c89) or greater. 

つまり、Terraform Enterpriseが依存しているAlpineが3.14に上げられたことにより、DockerとlibseccompのバージョンがRequirementsを満たさなくなり問題を引き起こした、ということになります。

# 復旧

私たちが利用している環境は、AmazonLinux2ベースです。AmazonLinux2の通常のyumでインストールしたTerraform Enterprise環境のDockerは、以下のバージョンとなっていました。

```shell
$ docker --version
Docker version 18.09.9-ce, build 039a7df
```

これは今回のRequirementsを満たしていません。調べてみると、amazon-linux-extrasにはDocker `20.10.7-3.amzn2` がありましたので、そちらをインストールします。

```shell
$ sudo amazon-linux-extras install docker
$ docker --version
Docker version 20.10.7, build f0df350
```

これでDockerのバージョンは要件を満たしたことになります。

次はlibseccompです。こちらは、通常のyumでインストールすると `2.4.1-1.amzn2` となり、Requirementsを満たしません。また、amazon-linux-extrasにも存在しませんでした。

そのため、ソースコードからビルドします。

```shell
$ sudo yum install gcc

$ wget https://github.com/seccomp/libseccomp/releases/download/v2.4.4/libseccomp-2.4.4.tar.gz
$ tar -xvzf libseccomp-2.4.4.tar.gz
$ cd libseccomp-2.4.4
$ ./configure
$ make
$ sudo make install
```

libseccompのバイナリは `/usr/local/lib/libseccomp.so.2.4.4` にインストールされましたので、シンボリックリンクの向き先を変更しておきます。

```
$ sudo ln -s -f /usr/local/lib/libseccomp.so.2.4.4 /usr/lib64/libseccomp.so.2
```

これで無事 Terraform Enterprise v202111-1 が起動するようになりました。

# 対策

これまでのSpotFleetそのままでは中断したときに同じ問題を踏んでしまうので、ソースコードからビルドしたlibseccompを含むAMIを作成し、そのAMIからTerraform Enterpriseを起動するようにしました。あわせて、SpotFleetではなくAutoScaling Groupを利用してSpotリクエストを維持する方式に変更しました。

また、Terraform Enterpriseのバージョンアップがあればリリースノートを早期にチェックできるよう、Github上で更新があれば以下のRSSフィードを利用してSlackに通知されるようにしました。
https://github.com/hashicorp/terraform-enterprise-release-notes/commits/master.atom

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151115/7a952800-3670-e522-2282-8f49d9863260.png)

Terraform Enterpriseで起動するバージョンを固定する、という方法もとれるのですが、今回の対策としては採用していません。これは、Terraformのランタイムバージョンを上げやすくするために、なるべく最新のTerraform Enterpriseを稼働させておきたい、という背景があります。

# おわりに

Dockerのベースイメージのバージョンアップによって、インフラ側のミドルウェアのRequirementsを満たさなくなり、アプリケーションがCPU負荷を生じたまま正常に動作しない、という事象が引き起こされることがある、ということが今回の教訓になりました。発生当初想像していなかったため、原因に気付くまでに時間がかかってしまいました。

本事象に関してはHashiCorpにフィードバックし、Terraform EnterpriseのRequirementsにも迅速に記載いただきました。
https://www.terraform.io/enterprise/before-installing#docker-engine-requirements
また、サポートのナレッジベースにも記事が掲載されています。(サポートセンターへのログインが必要です)
https://support.hashicorp.com/hc/en-us/articles/4410546606995
HashiCorpのyoheiさん、jacopenさん、kabuさん、ご対応ありがとうございました！

----

私たちのチームから、Terraform AWS Providerに出しているPull Requestがあります。AWS WAFv2で、マネージドルールのバージョン指定を可能にするものです。もしよろしければ :thumbsup: お願いします！
https://github.com/hashicorp/terraform-provider-aws/pull/21732