奈良氏の自己紹介

奈良貴充氏:こういった機会をいただきありがとうございます。「GitHubActionsで構築した自動化の仕組み」と題して、今回話します。よろしくお願いします。

今回ですが、7つのアジェンダでお話しします。「GitHubActions」を使っている方も多いと思うので、「こういったケースで使っているんだな」と聞いてもらえればと思います。

まず自己紹介します。私は凸版印刷というところで仕事をしています。主に新規サービスの立ち上げに関するシステム開発全般を扱っています。好きなものは日本のサブカルじゃないですが、漫画、特にジョジョが好きです。アニメはガンダムとかロボット系が好きです。

CI/CDツールについて

そんな私が今日お話しするGitHubActionsについてですが、GitHubActionsに入る前に、まず「ワークフローと言えば」一般的なCI/CDをスライドに書いています。ここにはコンテナアプリケーションの開発を例に書いていますが、このあたりの環境を整えることによって、品質向上やリリーススピードの向上が見込まれて、より良い開発サイクルを実現できると考えています。

そんなCI/CDツールの1つ、GitHubActionsというものを私は使っています。みなさんも使っていると思うんですが、GitHub社によって運営されている開発のプラットフォームです。リポジトリに対するプルリクとかをトリガーにテストしたり、デプロイをしたり。CI/CDに直接関わらないワークフローにも対応しています。

その他の特徴としては、GitHubのアカウントのユーザーに対する面倒な設定も不要、そして何よりも無償枠の幅がけっこう広いので、そういう意味でもGitHubを利用しているならば使わない理由はないかなと感じています。

GitHubActionsの基本

もう少し踏み込んでGitHubActionsの基本的な構造について触れていきたいと思います。(スライドを示して)右側に概要図を書いているんですが、イベントをトリガー・起点に処理が走ります。これは特定のイベントじゃなくても、スケジュール実行、「毎週何曜日に実行される」とか、手動実行も可能です。

ワークフローでは、リポジトリ内の.github/workflowsの中のyamlファイルで定義ができます。肝心のワークフローの中にジョブというものを定義して、これがGitHubActionsの実体になります。この中に実行するシェルとかアクションを記述します。

ここのジョブの中をもう少し深掘りしてみたいと思います。ジョブを実行するためのコンポーネントとして、大きくランナーとアクションというものがあります。ランナーは何かと言うと、GitHubActionsを実行するためのサーバーです。Linuxだったり、Ubuntuだったり、macOSだったり、セルフホスト、自分で持ち込んだものを実行することもできます。

それで実際に動くものがアクションになります。実行されるコマンドですね。あとは、GitHub Marketplaceというところから、もともと提供されているものを使用することもできます。

(スライドを示して)ここまでのGitHubActionsの基本を踏まえて、「実際のyamlってどんなふうになっているのか?」、yamlファイルの中はこんな感じになっています。これはサンプルですが、"Hello World!"と表示するだけになります。name:のところ、ワークフローの名前ですね。

その下にon:、push:、branches:というものがあります。これは何かと言うと、masterのブランチにプッシュされた時に、このイベント・ワークフローが実行されます。

それでは実際に実行されるものは何か? といったらその下にあります。ジョブにhello-worldという名前を付けてruns-on:、ランナーですね。ubuntu-latestを実行サーバーに指定します。

steps:の中にやりたい処理、実行したり処理を書いたりするんですが、今回は"Hello World!"と表示するだけというところで、こういった記述になっています。ここまでがざっくりとしたGitHubActionsの説明になります。

AWS環境へのデプロイとテストの自動化

(スライドを示して)それらを踏まえて今回構築した仕組みがどんなものかを簡単に概要で書いたものになります。AWS環境へのデプロイとテストを自動化しました。大きく4つですね。

今回のAWSのリソース構築には、「Terraform」を使いました。TerraformでAWSの環境構築を行っています。バックエンドはここにロゴが出ている、Pythonです。フロントはReact、LamdaはPythonです。それぞれGitHub上でコードを管理しデプロイする環境を構築しました。

構築して何が良かったんですか? ですが、一番恩恵に感じているところを言うと、作業工数の削減が一番大きかったですね。これはコンテナアプリケーション、にバックエンドを例に書いているんですが、大きく6つの作業に分けて書いています。

2、3、4の削減できていないところはGitHub上にプッシュして、プルリクして、マージしてなので、なかなか避けられない作業かなというところなんですね。

プルリク時にソースコードのレビューとかもするので自動化すべきじゃないというか、必要なタスクかなと思っています。そういう意味で、それ以外の1、5、6、主にビルドとデプロイの作業を誰か担当者にお願いするのではなく自動化でいったというのが、作業工数の恩恵を非常に受けられたところかなと感じています。

バックエンドの仕組み

もう少し深掘りして話したいと思います。全部を深掘りすると時間もないので、今回はバックエンドに絞って話したいと思います。Pythonのところですね。

ここのデモ動画を流そうかなと思ったんですが、時間もないため、かいつまんでお話ししたいと思います。

スライドに映しているのがバックエンドのワークフローです。yamlファイルとGitHubActionsの実行画面になります。左側がyamlファイルで、右側が実行画面になります。急に「え?」となりますが、コメントに何をやっているかを記述しています。上から説明していこうと思います。

まずはワークフローの名前です。on:、push:、branches:ということで、プッシュイベントとトリガーに、トリガーとなるブランチを指定して、どのブランチかを書いています。env:は、その名のとおり環境変数ですね。みなさんコーディングをしていたら環境変数を使うと思うので、それを定義しています。

「AWSリージョンだけ?」と思うんですが、クレデンシャル情報は書かずに抜粋しています。

そしてjobs:ですね。ここからが実際に動くものですが、今回はdeploy:という名前を付けています。ubuntu-latestでUbuntuを動かすため。permissions:はGitHubActionsで使うトークンですね。writeとかの書き込み権限を与えるとか、というものを指定します。

そしてこのsteps:の中からが実際に動くものです。リポジトリのチェックアウトは、対象のリポジトリを書いて、AWSの認証。自動テストも行っています。今回はPythonなのでpytestですね。テストの準備で必要なモジュールをインストールして、コンテナの立ち上げ。それでテストを実行します。テストを実行してOKとなったらECRにログインをして、イメージをビルド、プッシュします。URIを更新して、タスク定義を更新して一連の流れが完了するといったものになります。

右側のGitHubActionsの実行画面ではSet up job。(画面)上のところですね。ここではubuntu-latestだったり、必要なサーバーを立ち上げたりします。そしてCheckoutからConfigure AWSですね。

ここからが実際のジョブでステップします。name:ですね。このname:が、実行画面に映されるnameになります。「ちゃんと動いたね」という(ことがわかる)ものがバーッと出ます。

では実際にAWS上で見たらですが、AWS上で見るとけっこう淡泊と言ったらアレですが(笑)。デプロイの前後でバージョンが上がっていることが確認できるような感じです。

導入した効果

実際に導入してみてというところですが、導入してみた導入効果というところでは、やはり作業負荷の軽減だったり作業ミスの防止に直結するので、非常にありがたいです。テストのエビデンスも残すことが可能です。GitHub Artifactという機能で残すことが可能です。自動テストなので、リグレッションのテストも兼ねることが可能です。

Slack連携でSlackに連携して、Slackの承認をトリガーにワークフローを動かすことも可能です。なので、本番環境だけはSlackをトリガーにすることも可能です。注意事項で書いたのですが、今回、自動テストとかも入れてみたんですが、自動テストを含めると、実装時にテストコードの考慮までするのが非常に大変だったので、ここは考えどころかなと思います。

テストをやっていると、「これは本来NGなんだけども問題ないのでOK」とやることもGitHubActionsでは考慮されずにエラーになって止まってしまうので、ここは設計が必要です。

使いどころでTips的なところも書いていますが、ライフサイクルによって使い方を変えるということで、まず1個目のIaCを例にすると、環境複製ですね。Dev環境でコンソールから新規案件とか、新規サービスで新しい環境を立ち上げるということで「こうかな? こうかな?」とコンソールでいろいろ検証しながらやるケースってあると思いますが、それをステージング環境とか本番環境とかで同じ環境を再現するという時に、自動で環境構築をしてくれるので非常に大きな効率化かなと思っています。

フロントエンドに書いてあるのは、自動テストにはあまり入れないほうがいいかなと思いました。初期開発時はフロントってけっこうUIとか、UXとか、頻繁に変わったりするので、自動テストを導入するとけっこうテストで詰まるというか、逆に効率が落ちるようなこともあるので、フロントエンドはデプロイをメインで画面数が増えた時にリグレッションテスト目的で使うことがいいかなと感じました。

とはいえですね、やはりGitHubActionsを使ったほうが良いかなと思います。みなさまにも強くおすすめしたいと思います。

最後に、ちょっと宣伝みたいなかたちになっているんですが(笑)。我々は一緒に働ける人を大募集しているので、気軽にドアノックをくださいということです。以上です。ありがとうございました。