背景
Pythonを含むジョブをAWS EC2インスタンスで実行したくなった。ジョブは頻繁に実行されるわけではないのでEC2インスタンスは常時起動しておく必要はなく、ジョブのたびにEC2インスタンスを立ち上げる仕様とする必要があった。
作業手順
EC2インスタンスの環境構築
UbuntuベースでEC2インスタンスを立ち上げた。そこに必要な環境をインストールした。以下にPython3.8を使うために行ったセットアップを記録しておく。
# Update sudo apt update -y && sudo apt upgrade -y && sudo apt dist-upgrade -y && sudo apt autoremove -y && sudo apt autoclean -y # Install Python and venv sudo apt update && sudo apt-get install python3.8 python3.8-venv python3-pip python3.8 -m venv project_name # Install required libraries # awscli is necessary for Ubuntu, not for Amazon Linux sudo apt update && apt-get install awscli default-jre # Install tools sudo apt update && sudo apt-get emacs # Change timezone to JST sudo timedatectl set-timezone Asia/Tokyo
AMIを作成
EC2コンソール画面からAMIを作成する。この際EC2インスタンスは停止する必要はなく起動したままでよい。
Jenkins設定
(初めにおそらくEC2プラグインを入れる必要がある)「Jenkinsの設定」→「ノードの管理」→「Configure clouds」から新しい「Amazon EC2」設定を追加する。重要な設定項目は以下の通り
- EC2 key Pair's Private Key: EC2にSSHするのに必要な公開鍵を指定する.
- AMI ID: 作成したAMIのID(ami-******)を記載する.
- Instance type: 立ち上げたいEC2のインスタンスタイプを指定する.
- Security group: "ssh-connect"を設定する.
- Remote FS root: Ubuntu の場合は"/home/ubuntu"、Amazon Linuxなら"/home/ec2-user".
- Remote user: Ubuntu の場合は"ubuntu"、Amazon Linuxなら"ec2-user"
- AMI type: "unix".
- Labels: Jenkinsジョブ側から参照するときの識別ID.
Jenkinsジョブの作成
普段のJenkinsジョブ作成と基本的に同じだが、「General」→「実行するノードを制限」→「ラベル式」のところでは、先ほどのクラウド設定で「Labels」に書いたものと同じ文字列を記載する。
メモ
デフォルトのPyhtonバージョン
Ubuntu18.04ベースでEC2インスタンスを作成したが、デフォルトのPythonバージョンが3.6であった。Python3.8をインストールしてデフォルトバージョンにしようとしたが、以下のようなエラーが出て、作成したAMIからEC2を作成したときにステータスチェックで失敗してしまうので、venvを使いそこに環境を作ることにした。
AMI作成前に環境構築をしておく
Jenkinsジョブに依存しない設定(Pythonのインストールやタイムゾーンの設定など)はAMIを作るまえに設定しておけば、そのAMIをベースに作ったEC2インスタンスにもその設定が反映される。
Ubuntuのタイムゾーン設定
デフォルトのEC2インスタンスはUTCタイムゾーンになっていた。現在のタイムゾーンがどこであるかを確認するには
timedatectl
コマンドで確認できる。タイムゾーンを東京に変更するには
sudo timedatectl set-timezone Asia/Tokyo
とすれば良い。
EC2の起動時間
Jenkinsでジョブを実行してから実際にビルドが始まるまでは10-20分ほど時間がかかることがある。これはAMIからEC2インスタンスを起動するのに時間がかかっているため。
JenkinsジョブからEC2インスタンスへのSSH接続が失敗する
EC2インスタンスコネクトというのをセットアップしないとJenkinsからEC2へSSH接続できないらしい。Ubuntuの場合はドキュメントにあるようにawscliをインスタンスにインストールする必要があるらしい。Amazon Linuxの場合は不要らしく、この原因調査に時間がかかった。 参考:
Jenkisジョブに対して常にEC2を起動しておく場合
「Jenkinsの設定」→「ノードの管理」→「新規ノード作成」で「Permanent Agent」を追加すれば良いはず(未トライ)。