背景
現在Flutterを用いたモバイルアプリの開発を行なっているが、その中でGitlabによるCI/CDを構築している。
こちらを運用していくにあたって1点問題が発生した。
それは、メンバーの増加によって相対的にCI/CDのビルド端末が不足し、pipelineの滞留が発生したことだ。
pipeline待ちがDeveloperのストレスになったり、作業効率の低下を招いたりすることは既に広く知られてはいるため本件を早急に解決する必要がある。
基本的には、CI/CDのRunnerとなるMacを購入して、処理台数を増やすことで、本件を解決することができる。
しかし、この問題の解決には以下のような課題がある。
- Mac端末の購入にはリードタイムが必要であり、解決まで時間がかかる。
- 新規で購入した端末では新たに環境構築が必要であり、人的リソースがかかる。
- メンバーの増加は一時的なものであり、減少した際はまた今の台数で足りる見込みのため、一時的な対応としては予算的に少し勿体無い。
- (そもそも実機端末を多く保管するためには広いオフィスが必要であり、またマシンをメンテナンスするためには都度出社が必要になる。)
これらの課題を解決するため、
「一時的なリソース増強」という点からクラウドサービスであるAWSのEC2(MacOS)を利用して、EC2のインスタンスをCI/CDのRunnerに設定することで、
上記のリソース問題を解決しようと試みる。
構築手順
モバイルアプリケーション側の準備
こちらは既に準備済みで、以下の動作をするようになっている。
- RemoteにブランチがPushされた時に、Unitテストである
flutter test
を実行する。 - MergeRequestが更新されたときに、簡易なUIテストとしての
smoke test
を実行する。 -
git tag push
をしたときにローカルでiOSとAndriodの資材(ipa/app_bundle)を作成し、その資材をVisualStudioAppCenterにUploadしてテストユーザに配信する。
上記の設定が実装されたgitlab-ci.yamlを以下に示す。
(実際のシェルスクリプトの中身は割愛とさせてください。)
before_script:
- flutter pub get
stages:
- build
- test
- deploy
- schedule
unitTest:
stage: build
tags:
- mac-ci-runner
script:
- flutter test
except:
- tags
- merge_requests
mergeRequestSmokeTest:
stage: build
tags:
- mac-ci-runner
script:
- ./smoke-test.sh
only:
- merge_requests
deployment:
stage: build
tags:
- mac-ci-runner
only:
- tags
script:
- ./deploy-pipeline-for-artifacts.sh
AWS側の準備
MacOSインスタンスの作成・立ち上げ
まずはMacOS向けにはDedicated Hosts
が必要なため、こちらのリソース申請を実施します。(この段階ではまだ課金は発生しません)
参考:WindowsでiOS向けFlutter開発環境を用意する
さて、それでは実際にインスタンス上に環境構築をしていきます。
ここから料金がかかるので注意です!
まず、申請が通ったらDedicated Hosts
の割り当てを実施します。
その後、アクション>インスタンスをホスト で実行します。
インスタンスの作成時にMacOSを指定します。ここでOSを指定するのですが、今使っている環境と差分が出ないように注意してください。
インスタンスを立ち上げたら、SSHクライアントでインスタンスに接続します
$ ssh -i "key.pem" ec2-user@ec2-44-198-162-195.compute-1.amazonaws.com
The authenticity of host 'ec2-44-198-162-195.compute-1.amazonaws.com (44.198.162.195)' can't be established.
ED25519 key fingerprint is SHA256:95QOrDftB2aLiWO4FzNsxAxCV7iAMCz+HzRgVBWBxJY.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'ec2-44-198-162-195.compute-1.amazonaws.com' (ED25519) to the list of known hosts.
┌───┬──┐ __| __|_ )
│ ╷╭╯╷ │ _| ( /
│ └╮ │ ___|\___|___|
│ ╰─┼╯ │ Amazon EC2
└───┴──┘ macOS Monterey 12.6.3
ec2-user@ip-172-31-1-72 ~ %
接続が完了したら以下の手順でVNC接続してリモートデスクトップで操作できるようにします
参考:https://tech.arms-soft.co.jp/entry/2020/12/09/090000
自分はその時、以下のエラーが出てきてうまく接続できませんでしたが、以下の動画を参考にして実施することで事象が解消しました
Screen recording might be disabled. Screen Sharing or Remote Management must be enabled from System Preferences or via MDM.
Screen control might be disabled. Screen Sharing or Remote Management must be enabled from System Preferences or via MDM.
参考:https://www.youtube.com/watch?v=FtU2_bBfSgM
MacOSインスタンス上での環境構築
ここからは通常のFlutterの環境構築をしていきます。
この記事を見ている方は通常の環境構築は問題ないかと思いますが、念の為参考の動画だけ貼っておきます。
参考:https://www.youtube.com/watch?v=d0Gwro3j81g
今回の環境の気をつける点で言えばポイントは以下です。
- 開発端末と同様のOS、IDEのバージョン、Shellの統一(zsh,bash)などを揃える。
- Storageが限られるため、不要なソフトなどは入れない。
- リモートデスクトップなので動作が少しもっさりしているため、何かと並行して作業した方がストレス少なく作業できる
Gitlab CI Runnerとしての登録
上記が完了したらGitLab CIへのRunnerとして登録していきます。
こちらも通常の実機Macと同様の手順のため詳細な手順は、記事にて割愛させていただきます。
参考:https://qiita.com/takamii228/items/64fd6879e6acce845980
※Runner環境を作成するときは、bash
での作成をすること
結果、以下のようにGitLab側にRunnerとして登録されました。
これで完了です。
AMIを用いた開発環境のsnapshotの保存
ここまで実施できたら、私は実際にはやっていませんが、AMIを用いて開発環境のsnapshotを保存すると良いと思います。
Runnerを複数作成したりするのに有効に活用できると思います。
実行速度
環境 | UnitTest | E2E Test |
---|---|---|
実機(M1 Pro 16GB) | 25s | 4m37s |
EC2(M1 16GB) | 22s | 4m3s |
利用料金体系・メリット
この一番下のmac2が今回利用したものの料金になります。
0.65USD/h ですが、Dedicated Hosts
のため、24時間の利用が必要となりますので、最低でも15.6USD。
現在の日本円に直すと2,174円となります。(2023年6月1日時点)
参考:https://aws.amazon.com/jp/ec2/dedicated-hosts/pricing/
これを1ヶ月使用するとなると、2,174円*30日=65,220円/月
M2のMac mini メモリ16GBを購入しようと思うと140,800円なので、2ヶ月より長い期間使用しようと思ったらEC2よりもMac miniの実機を購入した方が費用的には安くなりますね。
結論
参考にした記事
- WindowsでiOS向けFlutter開発環境を用意する
- EC2 Mac インスタンスに入門してみた
- AWS EC2利用料金
- 実際に使用したCI/CDの内容はこちらを参考に構築していますFlutterを使ったAndroid・iOSアプリ開発のCIパイプラインを構築する