古いOSを導入したAWS EC2インスタンスを稼働させつつ最新のOSにアップデートする

## はじめに

AWSでEC2を使ってると、アカウントの利用者自身でOSやアプリケーションで使うソフトウェアのアップデートを行う必要がたびたび発生します。

AWSのサーバレスのプログラムランタイム環境であるLambdaだと、OSやソフトウェアのサポート期限・EOL (End Of Life)を過ぎたランタイム環境は自動更新されます。ただ、これによりあるバージョンのランタイム環境では動くコードが、新しいランタイム環境では動かなくなってしまう場合もあります。

Lambdaと比べるとEC2の場合、EOLを過ぎた古いOSでも自動更新は行われないので使い続けることはできます。しかしながら、EOLが過ぎたOSはセキュリティパッチ等リリースされなくなるため、ゼロデイ脆弱性の危険も高まりセキュリティリスクとなります。

また、AWS側からEC2の環境に追加された新しい機能を利用したい場合、EOLを過ぎたOSでは新しい機能が動かないこともあります。

セキュリティリスクを軽減させ、便利な機能を享受するためにも、なるべくEC2内部のOSも最新を保つことが望ましいです。

ただ、そうはいっても、本番環境として使われているEC2だと、メンテナンスのためインスタンスを停止するのもなかなか面倒。特に対象のEC2が一台しかない場合、メンテナンス時のダウンタイムを考慮しつつ作業を行う必要があります。予告したダウンタイムを過ぎてもメンテナンス完了できない事も時にあります。

そんな悩めるサーバ管理者の負担を少しでも軽減するため、EC2をなるべく停止せず、比較的安全かつ速やかにEC2環境を更新するための便利機能をご紹介します。

## EC2のルートボリュームを置き換え機能を交えた手順

目的を達成する手段として、EC2のルートボリュームを置き換え機能を利用します。

「EC2 インスタンスのルートボリュームを置き換える」
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/replace-root.html

この機能、とある時点で取得したAMIを指定することにより、そのイメージのスナップショットに使われてるボリューム情報で、更新対象のEC2インスタンスに関連づけされたEBS・ルートボリューム情報を置き換えることができるというものです。

OSのアップデートを行う場合、以下のような手順によりこの機能を使った作業を行うことになるでしょう。

- OSアップデート対象となるEC2インスタンスからAMIを作成
- 作成したAMIを元に新しいEC2インスタンスを作成
- 新しいEC2インスタンスを起動し、OSのアップデートを行う
- OSアップデート済みEC2インスタンスからAMIを作成
- 「EC2インスタンスのルートボリューム置き換え」機能を使用
- あらかじめ取得しておいたデータベース等のバックアップを更新済みのEC2にリストアする

つまりOSアップデート対象となるEC2環境のAMIから、EC2のクローンとなるOSアップデート処理用EC2インスタンスを新たに立ち上げます。これにより、OSアップデート対象の環境そのものは触らず、OSのアップデート作業を行うことができるようになります。

![スクリーンショット 2024-04-30 10.04.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18599/0e2852ad-9464-d34f-dacb-9bc0693810c9.png)

![スクリーンショット 2024-04-30 10.05.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18599/50981400-6194-5484-a35c-d34f423afcb7.png)

アップデート作業が完了したらOSアップデート済みEC2で使ったストレージ装置を、置き換え機能を使って本番環境のルートボリュームと差し替えます。

![スクリーンショット 2024-04-30 10.06.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18599/19017504-6c36-0286-9ae0-38bc4a56071a.png)

![スクリーンショット 2024-04-30 10.08.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18599/66b19ed7-2d15-d708-5121-fba1b9f4740f.png)

置き換えされるのはOSが導入されてるルートボリュームだけで、EC2に追加したその他のボリューム[^1]は更新されません。

[^1]:インスタンスストアボリュームで復元されたデータ、非ルートボリューム以外のAmazon EBS ボリュームに保存されたデータがこれにあたります

また、更新したEC2のネットワーク設定については、置き換えは行われません。したがって、置き換える前のElastic IP等のパブリックIPアドレスや、プライベートIPアドレスはそのまま使うことができます。

この機能を使えるEC2は条件がありますが[^2]、大半のEC2インスタンスでは使うことができます。

[^2]:ルートボリュームを置き換えることができるのは、すべての仮想化インスタンスタイプと EC2 Mac ベアメタルインスタンスに制限されています。

ルートボリューム置き換え機能により、OSアップデート対象のEC2環境を入れかえるギリギリまで稼働させつつ、ダウンタイムを最小限にとどめ、比較的安全にOSアップデート対象の環境を更新することができます。

次項より、作業例にあげた項目それぞれについて、具体的な作業手順を説明します。

### OSアップデート対象となるEC2インスタンスからAMIを作成

AMIを取得するためにEC2のインスタンス一覧の画面から以下の操作を行います。

- [アクション]-[イメージとテンプレート]-[イメージを作成]

![スクリーンショット 2024-04-29 22.44.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18599/ea48785e-1120-19d9-25a0-36ed8463ebb1.png)

この操作で表示される「イメージを作成」の画面では以下の設定を行います。

- イメージ名に適当な名前をつけます
- 「再起動しない [有効化]」のオプションにチェックをつけます
- [イメージを作成]を押すと、AMIが作成されます

作成したイメージはAMIのリストに掲載されます。

![スクリーンショット 2024-04-29 22.47.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18599/834bb25d-bca5-e519-35f4-ef75326f1e82.png)

### 作成したAMIを元に新しいEC2インスタンスを作成

OSアップデート用のEC2環境を新たに立ち上げるため、取得したイメージを選択し、[AMIからインスタンスを起動]のボタンを押します。

![スクリーンショット 2024-04-30 1.01.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18599/d3c147c5-3f05-9beb-aa55-1588d235cc11.png)

この操作で表示される「Launch an Instance」の画面では以下の値を設定します。

- OSアップデート処理用のEC2は名前を元EC2と別のものに設定
- インスタンスタイプ、キーペア、ネットワーク設定、セキュリティグループ、ストレージ設定は元のEC2と同じように揃えてください[^3]
- 設定できたら [インスタンスを起動]ボタンを押して、新しいEC2インスタンスを操作します

[^3]: その方が置き換え時に起こるトラブルが少なくなります。

### 新しいEC2インスタンスを起動し、OSのアップデートを行う

新しいEC2インスタンスが作られたらインスタンスを起動し、SSH等を経由して環境にログインを行ってOSアップデートを行います。

OSにUbuntuを使ってる場合、以下のコマンドを実行することでアップデートを行うことができます。

```
# ubuntuの場合の手順

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install update-manager
$ sudo do-release-upgrade
```

Ubuntuの場合、例えば16系のバージョンから、現時点の最新である22系には直接アップデートできず、16 > 18 > 20 > 22とひとつずつメジャーバージョンを上げていく必要があります。アップデートの過程で、古い環境で動いていたサービスが削除されることもあります[^4]。

[^4]: 筆者の環境では16 > 18にアップデートした時点で、Apache2 Web Serverが削除されました。

アップデートが完了した時点で、その環境で元々動かしていたサービスが止まってないか確認を行い、動いてない場合は新たに導入を行ってください。

### OSアップデート済みEC2インスタンスからAMIを作成

OSの更新が完了したら、OSアップデート済みEC2環境について、「OSアップデート対象となるEC2インスタンスからAMIを作成」の手順と同じように操作を行い、AMIを作成します。

### 「EC2インスタンスのルートボリューム置き換え」機能を使用

ここまでの作業でそれなりに時間が経過しており、稼働させてる置き換え対象EC2では最初にイメージを作った時点からのデータの増減が発生してるため、必要に応じ、OS更新対象のEC2からリストアするデータをファイルでバックアップしてください。

OSアップデート済みEC2インスタンスのAMIで、OSアップデート対象EC2インスタンスのルートボリュームを置き換えます。

EC2のインスタンス一覧から、置き換え対象EC2を選択し、以下の操作を行います。

- [アクション]-[モニタリングとトラブルシューティング]-[ルートボリュームを置き換える]

この操作で表示される「ルートボリュームを置き換える作業」の画面にて以下の設定を行います。

- 復元で[イメージ]のラジオボタンを選択
- イメージ: ボリュームを置き換えるOSアップデート済みEC2インスタンスのAMIについて、AMI IDを選択
- その後[置き換えタスクを作成]ボタンを押します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18599/496f7aa5-f779-5bfa-9964-db8ffa746286.png)

このとき、選択したAMIと世代が異なるインスタンスタイプを設定してる場合（とくにNitroTPM、ENA設定が有効になってる場合）、AMI IDの一覧に表示されず、無理に設定しても、置き換え処理に失敗するのでご注意ください。

ボタンを押したあと、EC2は稼働したままルートボリュームの更新が行われます[^5]。更新が完了したら、EC2にログインし、OSアップデートしたバージョンに置き換わってるか確認を行ってください。

[^5]: 実際には、一瞬ですがEC2の再起動がかかります。

バックアップしたファイル等からリストアの必要があれば、この時点で行ってください。

## まとめ

OSのアップデート以外にも、アプリケーションのバージョンアップを行いたい場合も同様の手順で置き換えることができます。

また、適切なタイミングでAMIを取得していれば、障害が起きた際、AMIの取得時まで環境を復元することも簡単です。

サーバ管理者の負担を軽減してくれるこの機能、EC2が多い環境では便利なので機会があればお試しください。