電通総研のブログ - TECH PLAY

TECH PLAY

電通総研

電通総研 の技術ブログ

856

電通国際情報サービス 、クロス イノベーション 本部、オープン イノベーション ラボの 比嘉康雄 です。 ブロックチェーン 週報2/21いってみようか。 Web3 Web3関連ニュース その他の話題 Web3 前回 、ク リエータ ー/ファンエコノミーがトレンドになっているという話をしましたが、その流れは今週も続いています。 ただ、その呼び方がWeb3と言われることが多くなったので、今後Web3で統一したいと思います。 Web3は、非中央集権的な Webサービス のことですが、それだとなんのことかわからないと思います。非中央集権的サービスとは、サービスの運営者がサービスを支配せず、サービスのユーザーも運営に関われるようなサービスのことです。これは、個人的な見解ですけど。 ユーザーが運営に関わる手段として、DAO(自律分散型組織)が使われることが一般的です。 DAOの参加資格は、NFTを持っていることとするケースがほとんどです。そこから短絡的に、Web3=NFTを使ったサービスと思っている人もいるようなので、そこは注意が必要です。 Web3関連ニュース The Song That Owns Itself (stoi.org) arrives at ETHDenver on Algorand protocol Jesse Boykins III というミュージシャンが自ら立ち上げたWeb3サービスがSTOIです。 なぜSTOIはEthereumからAlgorandに乗り換えたたか 理由は3つ上がってますが、3つ目の理由がうまく説明できないので、2つ目まで紹介しておきます。 Algorandは、 トランザクション コストが安く、安定している。ニーズがあれば、100億の トーク ンを発行することも可能。 全体的に脱炭素が考慮されている(carbon-neutral footprint)。 前回話したEthereumから他のブロックチェーンへ の動きとも合致しますね。 所有の新しいかたち、P2Pファイル共有から音楽NFTまで その他の話題 ケニア中央銀行がデジタル通貨の導入について国民から意見を募集 デジタル通貨は、 カリブ海 諸国以外では、アフリカの国が積極的なんですね。 たぶん、クロスボーダーな仕送りを改善したいということだと思います。 アダルト系SNS「OnlyFans」が認証済みNFTをプロフィール画像にできる機能を提供 アダルト系 SNS では、本人かどうかめっちゃ重要ですよね。写真でなりすましされたら困りますから。出会い系 SNS でも一緒だと思います。 英歳入関税庁が2.2億円相当の脱税案件の捜査にともないNFTを押収、英法執行機関として初 NFTの押収ってどうやるんでしょうか。プライベートキー(Wallet)を押収したということでしょうか。 BlockFiの米SECとの約115億円の和解は、今後のDeFiレンディングにとって何を意味するのか? 利益の分配をしようとすると、日本でも アメリ カでも証券とみなされます。証券なら、それなりのルールを守る必要があります。でも、守っていなかったという話です。 Web3のパワープレイヤー「アニモカブランズ」が日本進出、戦略的子会社「Animoca Brands株式会社」が11億円のシード調達 IPを利用して、Web3で儲けようという話です。僕の定義だとこれはWeb3ではないんですが... 執筆: @higa 、レビュー: @sato.taichi ( Shodo で執筆されました )
こんにちは、 電通国際情報サービス (ISID)の上羽です。 私は クラウド イノベーション センターという組織に所属し、社内における パブリッククラウド の活用推進や クラウド テク ノロ ジー の研究開発を行っています。この記事は最近Azureでパブリックプレビューとして公開された Azure Kubernetes Service(以下、AKS)の機能であるGitOps について解説します。本記事では、CI/CD、および Kubernetes の基本的な概念をある程度理解していることを前提としています。 GitOpsとは CI/CDによるデプロイを実現する方法として、多くの人が思い浮かべるのはCIツール( GitHub ActionsやJenkinsなど)を使った方法ではないでしょうか。この方法では、 ソースコード リポジトリ への変更をトリガーとしてCIツールが起動し、ビルドなどのCI( 継続的インテグレーション )からCD(継続的デリバリー・デプロイ)までを手続き的に実行します。このようなデプロイ方法はCIOpsと呼ばれ、CIツールが中心となったシンプルで開発者にとってわかりやすい方法です。ただし、CIOpsによるデプロイはいくつか課題があります。 意図したデプロイ状況になっているか把握しにくい CIツールは変更をデプロイするだけです。デプロイ先の状態を管理したい場合は、状態を取得するために複雑なワークフローを組む必要があります。 CIツールの持つ権限が大きくなる デプロイのために、デプロイ先環境の認証情報をCIツールが持つ必要があります。 このような課題へのアプローチとして、WeaveWorks社の提唱する GitOps という方法が考えられました。GitOpsはCDの方法の1つで、誤解を恐れずに要約すると「Kuberenetes クラスタ を構成する マニフェスト のすべてをGit リポジトリ で管理し、その情報を正としてデプロイする方法」です 1 。 CIOpsが持つ課題に対して、それぞれ以下のようなアプローチをとっています。 Git リポジトリ を唯一の情報源(Single Source of Truth)とする 「Git リポジトリ に存在する マニフェスト = Kubernetes クラスタ の状態」とすることで、 クラスタ の状態を把握できるようにします。 CIとCDを分離する CIツールがデプロイ先の認証情報を持つ必要もなくなり、ビルドやテストといったワークフローに注力できるようにします。CDツールを Kubernetes クラスタ 内に配置して、デプロイに注力します。CDツールがGitで管理されている マニフェスト と自身の構成情報の差分を検知すると、 マニフェスト を自身にデプロイします。 ここまでの説明を簡単に図示したものが以下です。CIOpsでは ソースコード リポジトリ から一方向に矢印が伸びている対して、GitOpsでは マニフェスト リポジトリ を境として矢印が反対を向いています。先ほどGitOpsの特徴として述べた「唯一の情報源」が マニフェスト リポジトリ であり、この リポジトリ を境に「CIとCDの分離」を実現していることがわかります。 GitOpsを実現するツールとして Flux や ArgoCD があります。 AKS のGitOps機能にはFluxが利用されています。 AKS でGitOpsを使ってみる ここからが本題です。冒頭で紹介した AKS のGitOps機能を使ってみます。 Azure CLI を利用して環境を構築します。 リソースプロバイダーの登録とAzure CLI 拡張機能 の有効化 今回利用する AKS のGitOps機能はそのままの状態で利用できず、 リソースプロバイダー の登録が必要になります。また、 CLI からGitOpsの構成を作成するために CLI の 拡張機能 も必要です。それらを以下コマンドにより登録します。 # リソースプロバイダの登録 az provider register --namespace Microsoft.Kubernetes az provider register --namespace Microsoft.ContainerService az provider register --namespace Microsoft.KubernetesConfiguration # AKS拡張機能の有効化 az feature register --namespace Microsoft.ContainerService --name AKS-ExtensionManager # Azure CLI拡張機能のインストール az extension add -n k8s-configuration az extension add -n k8s-extension なお、これらの登録には数十分要することがあります。リソースプロバイダーの登録は非同期処理なので、コマンド az provider show -n <名前空間> -o table により登録状況を確認してください。StateがRegisteredになれば登録完了です。 AKS クラスタ の作成 以下コマンドにより AKS クラスタ を作成します。今回作成する クラスタ はGitOpsの検証利用想定のため、必要最小限の構成としています。 az aks create --resource-group < リソースグループ名 > --name < クラスタ名 > --node-vm-size Standard_B2s --node-count 1 --generate-ssh-keys GitOpsの構成 以下コマンドを実行してGitOpsの構成を AKS に追加します。 az k8s-configuration flux create \ --resource-group < リソースグループ名 > \ --cluster-name < クラスタ名 > \ --cluster-type managedClusters \ --name gitops-test \ --namespace gitops-test \ --scope cluster \ --url https://github.com/fluxcd/flux2-kustomize-helm-example \ --branch main \ --kustomization name =infra path =./infrastructure prune =true \ --kustomization name =apps path =./apps/staging prune =true dependsOn = [" infra "] コマンドについて補足します。 --resource-group <リソースグループ名> --cluster-name < クラスタ 名> 作成した AKS の クラスタ 名、および AKS が存在するリソースグループ名を指定してください。 --cluster-type managedClusters インストール対象の クラスタ として、 managedClusters を指定してください。これは AKS のマネージド クラスタ であることを意味します。ほかには connectedClusters というAzure Arc(Azureに接続したオンプレ環境)の クラスタ も指定できます。 --name gitops-test --namespace gitops-test --scope cluster name はこのGitOpsの構成を識別するための名称です。 namespace はこの構成を配置する 名前空間 を指定します。 クラスタ 内になければ新規作成されます。 scope はこの構成のアクセススコープです。検証用なので、clusterに設定します。 --url https://github.com/fluxcd/flux2-kustomize-helm-example --branch main \ url には マニフェスト が存在する リポジトリ を指定します。 本記事においては、Fluxが公開している サンプルリポジトリ を利用します。 branch は リポジトリ に存在するブランチを指定します。ここで指定したブランチに変更があった場合、 AKS にデプロイされます。ほかにコミット単位や、タグを指定できるオプションもあります。 また今回はパブリックな リポジトリ を指定しましたが、プライベートな リポジトリ を指定することも可能です。その場合は リポジトリ に対する認証情報を入力する必要があります。 --kustomization name=infra path=./infrastructure prune=true --kustomization name=apps path=./apps/staging prune=true dependsOn=["infra"] 次にKustomizationの設定です。 Kustomization とはFluxで利用するCRDの1つで、Gitで管理されている マニフェスト のうち クラスタ に適用するものを定義したファイルです。 Kubernetes のエコシステムである Kustomize とも深く関係しますが、この記事では割愛します。 今回作成するKustomizationの設定は2つ(infraとapps)です。このうちの、infra インスタンス で設定したパスにある ディレクト リ構成を見てみます。 infra/  ├ nginx/  │ └ kustomization.yaml  │ └ namespace.yaml  │ └ release.yaml  ├ sources/  │ └ kustomization.yaml  │ └ 複数マニフェスト  ├ redis/  │ └ kustomization.yaml  │ └ 複数マニフェスト  └ kustomization.yaml infra/kustomization.yaml ファイルを見てみます。 apiVersion : kustomize.config.k8s.io/v1beta1 kind : Kustomization resources : - sources - nginx - redis Kustomizationの マニフェスト で、リソースとして3つ定義されています。この3つのリソースは ディレクト リ名を表していて、それぞれの ディレクト リの中にさらに kustomization.yaml が存在します。一例として nginx ディレクト リにある kustomization.yaml の中を見てみます。 apiVersion : kustomize.config.k8s.io/v1beta1 kind : Kustomization namespace : nginx resources : - namespace.yaml - release.yaml リソースとして マニフェスト の yaml ファイルが定義されています。このように定義された マニフェスト をFluxが検知しデプロイする、という仕組みになっています。 本記事ではinfraの構成を確認してみましたが、appsについても同様です。ただし、appsの依存関係にinfraが設定されています。infraのリソースがデプロイされた後にappsをデプロイするための設定です。 デプロイの確認 まずはFluxが クラスタ にインストールされているかを確認します。ここからは視覚的にわかりやすくするためにAzure Portal を利用します。 AKS のリソースメニューから作成した クラスタ を選択し、ブレードからワークロードを選択します。 名前空間 を flux-system でフィルタすると、Fluxを構成するオブジェクトを確認できます。 Fluxに関する アーキテクチャ は説明しません。興味のある方は こちら をご参照ください。 次にGitOpsの構成を確認します。 ブレードからGitOps(プレビュー)を選択します。 先ほど CLI から作成した構成を確認できます。構成名をクリックして詳細画面に移ります。 現在のデプロイ状況を表す「状態」、同期する リポジトリ を表す「 リポジトリ 」、設定したKustomizationなどを表す「プロパティ」がそれぞれ確認できます。いくつか気になる項目をピックアップします。 コンプライアンス の状態 AzureにはAzure Policyという コンプライアンス を管理するサービスが存在します。そのAzure Policyによる検出結果がこれです。 AKS が対象としている ポリシー はこちらから確認できます。 種類 GitOpsを実現するためのツールが示されています。Flux v2であることがわかりますね。あえて表示しているということは今後ほかのツールにも対応予定なのかもしれません。(筆者個人の感想です) 構成オブジェクト インストールの状態 今回のデプロイ対象のオブジェクト、およびその状態を示しています。 リポジトリ にある kustomization.yaml を展開した結果のオブジェクトです。インストールの状態がSucceedになっているので、もうデプロイは完了しているようです。リンクをクリックして中を見てみます。 設定したKustomization自体や、同期先の リポジトリ を管理するGitRepositoryオブジェクト、 リポジトリ に管理されている マニフェスト で指定したHelmReleaseなどが確認できます。今回指定したサンプル リポジトリ からデプロイされるアプリケーションは podinfo という軽量のWebアプリケーションです。 CLI を利用して動作確認してみます。 次のコマンドで AKS に対する認証情報を取得します。 az aks get-credentials --resource-group < リソースグループ名 > --name < クラスタ名 > podinfoアプリケーションが公開されているポートを手元にポート フォワ ードして、アプリケーションに接続してみます。 # ポートフォワード kubectl -n nginx port-forward svc/nginx-ingress-controller 8081:80 & # アプリケーションへのリクエスト curl -H " Host: podinfo.staging " http://localhost:8081 { " hostname " : " podinfo-6dddd646b6-7d8fb " , " version " : " 6.0.3 " , " revision " : "" , " color " : " #34577c " , " logo " : " https://raw.githubusercontent.com/stefanprodan/podinfo/gh-pages/cuddle_clap.gif " , " message " : " greetings from podinfo v6.0.3 " , " goos " : " linux " , " goarch " : " amd64 " , " runtime " : " go1.16.9 " , " num_goroutine " : " 9 " , " num_cpu " : " 2 " } podinfoからのレスポンスが返ってきました。この hostname はPodの名前と一致しているはずです。podを取得して確認してみます。 kubectl get pods -n podinfo NAME READY STATUS RESTARTS AGE podinfo-6dddd646b6-7d8fb 1 / 1 Running 0 129m デプロイコマンドなど一切なしにアプリケーションをデプロイできました。 おわりに 本記事では AKS のGitOps機能を利用してアプリケーションをデプロイする手順を解説しました。 Flux自体はどのKubernetesプラットフォームにおいても利用可能です 。Azureにおいてはそれを 拡張機能 として利用でき、管理用の GUI が提供されていたり、Azureのサービス(Azure Policy)と組み合わせて利用できるのが利点であると筆者は考えています。 最後までお読みいただきありがとうございました。 執筆: @ueba.yuki 、レビュー: @shibata.takao ( Shodo で執筆されました ) Kuberenetes以外でもGitOpsを実現するツール( PipeCD )はありますが、解説を簡潔にするために今回は説明を省きました ↩
こんにちは、 電通国際情報サービス (ISID)の上羽です。 私は クラウド イノベーション センターという組織に所属し、社内における パブリッククラウド の活用推進や クラウド テク ノロ ジー の研究開発を行っています。この記事は最近Azureでパブリックプレビューとして公開された Azure Kubernetes Service(以下、AKS)の機能であるGitOps について解説します。本記事では、CI/CD、および Kubernetes の基本的な概念をある程度理解していることを前提としています。 GitOpsとは CI/CDによるデプロイを実現する方法として、多くの人が思い浮かべるのはCIツール( GitHub ActionsやJenkinsなど)を使った方法ではないでしょうか。この方法では、 ソースコード リポジトリ への変更をトリガーとしてCIツールが起動し、ビルドなどのCI( 継続的インテグレーション )からCD(継続的デリバリー・デプロイ)までを手続き的に実行します。このようなデプロイ方法はCIOpsと呼ばれ、CIツールが中心となったシンプルで開発者にとってわかりやすい方法です。ただし、CIOpsによるデプロイはいくつか課題があります。 意図したデプロイ状況になっているか把握しにくい CIツールは変更をデプロイするだけです。デプロイ先の状態を管理したい場合は、状態を取得するために複雑なワークフローを組む必要があります。 CIツールの持つ権限が大きくなる デプロイのために、デプロイ先環境の認証情報をCIツールが持つ必要があります。 このような課題へのアプローチとして、WeaveWorks社の提唱する GitOps という方法が考えられました。GitOpsはCDの方法の1つで、誤解を恐れずに要約すると「Kuberenetes クラスタ を構成する マニフェスト のすべてをGit リポジトリ で管理し、その情報を正としてデプロイする方法」です 1 。 CIOpsが持つ課題に対して、それぞれ以下のようなアプローチをとっています。 Git リポジトリ を唯一の情報源(Single Source of Truth)とする 「Git リポジトリ に存在する マニフェスト = Kubernetes クラスタ の状態」とすることで、 クラスタ の状態を把握できるようにします。 CIとCDを分離する CIツールがデプロイ先の認証情報を持つ必要もなくなり、ビルドやテストといったワークフローに注力できるようにします。CDツールを Kubernetes クラスタ 内に配置して、デプロイに注力します。CDツールがGitで管理されている マニフェスト と自身の構成情報の差分を検知すると、 マニフェスト を自身にデプロイします。 ここまでの説明を簡単に図示したものが以下です。CIOpsでは ソースコード リポジトリ から一方向に矢印が伸びている対して、GitOpsでは マニフェスト リポジトリ を境として矢印が反対を向いています。先ほどGitOpsの特徴として述べた「唯一の情報源」が マニフェスト リポジトリ であり、この リポジトリ を境に「CIとCDの分離」を実現していることがわかります。 GitOpsを実現するツールとして Flux や ArgoCD があります。 AKS のGitOps機能にはFluxが利用されています。 AKS でGitOpsを使ってみる ここからが本題です。冒頭で紹介した AKS のGitOps機能を使ってみます。 Azure CLI を利用して環境を構築します。 リソースプロバイダーの登録とAzure CLI 拡張機能 の有効化 今回利用する AKS のGitOps機能はそのままの状態で利用できず、 リソースプロバイダー の登録が必要になります。また、 CLI からGitOpsの構成を作成するために CLI の 拡張機能 も必要です。それらを以下コマンドにより登録します。 # リソースプロバイダの登録 az provider register --namespace Microsoft.Kubernetes az provider register --namespace Microsoft.ContainerService az provider register --namespace Microsoft.KubernetesConfiguration # AKS拡張機能の有効化 az feature register --namespace Microsoft.ContainerService --name AKS-ExtensionManager # Azure CLI拡張機能のインストール az extension add -n k8s-configuration az extension add -n k8s-extension なお、これらの登録には数十分要することがあります。リソースプロバイダーの登録は非同期処理なので、コマンド az provider show -n <名前空間> -o table により登録状況を確認してください。StateがRegisteredになれば登録完了です。 AKS クラスタ の作成 以下コマンドにより AKS クラスタ を作成します。今回作成する クラスタ はGitOpsの検証利用想定のため、必要最小限の構成としています。 az aks create --resource-group < リソースグループ名 > --name < クラスタ名 > --node-vm-size Standard_B2s --node-count 1 --generate-ssh-keys GitOpsの構成 以下コマンドを実行してGitOpsの構成を AKS に追加します。 az k8s-configuration flux create \ --resource-group < リソースグループ名 > \ --cluster-name < クラスタ名 > \ --cluster-type managedClusters \ --name gitops-test \ --namespace gitops-test \ --scope cluster \ --url https://github.com/fluxcd/flux2-kustomize-helm-example \ --branch main \ --kustomization name =infra path =./infrastructure prune =true \ --kustomization name =apps path =./apps/staging prune =true dependsOn = [" infra "] コマンドについて補足します。 --resource-group <リソースグループ名> --cluster-name < クラスタ 名> 作成した AKS の クラスタ 名、および AKS が存在するリソースグループ名を指定してください。 --cluster-type managedClusters インストール対象の クラスタ として、 managedClusters を指定してください。これは AKS のマネージド クラスタ であることを意味します。ほかには connectedClusters というAzure Arc(Azureに接続したオンプレ環境)の クラスタ も指定できます。 --name gitops-test --namespace gitops-test --scope cluster name はこのGitOpsの構成を識別するための名称です。 namespace はこの構成を配置する 名前空間 を指定します。 クラスタ 内になければ新規作成されます。 scope はこの構成のアクセススコープです。検証用なので、clusterに設定します。 --url https://github.com/fluxcd/flux2-kustomize-helm-example --branch main \ url には マニフェスト が存在する リポジトリ を指定します。 本記事においては、Fluxが公開している サンプルリポジトリ を利用します。 branch は リポジトリ に存在するブランチを指定します。ここで指定したブランチに変更があった場合、 AKS にデプロイされます。ほかにコミット単位や、タグを指定できるオプションもあります。 また今回はパブリックな リポジトリ を指定しましたが、プライベートな リポジトリ を指定することも可能です。その場合は リポジトリ に対する認証情報を入力する必要があります。 --kustomization name=infra path=./infrastructure prune=true --kustomization name=apps path=./apps/staging prune=true dependsOn=["infra"] 次にKustomizationの設定です。 Kustomization とはFluxで利用するCRDの1つで、Gitで管理されている マニフェスト のうち クラスタ に適用するものを定義したファイルです。 Kubernetes のエコシステムである Kustomize とも深く関係しますが、この記事では割愛します。 今回作成するKustomizationの設定は2つ(infraとapps)です。このうちの、infra インスタンス で設定したパスにある ディレクト リ構成を見てみます。 infra/  ├ nginx/  │ └ kustomization.yaml  │ └ namespace.yaml  │ └ release.yaml  ├ sources/  │ └ kustomization.yaml  │ └ 複数マニフェスト  ├ redis/  │ └ kustomization.yaml  │ └ 複数マニフェスト  └ kustomization.yaml infra/kustomization.yaml ファイルを見てみます。 apiVersion : kustomize.config.k8s.io/v1beta1 kind : Kustomization resources : - sources - nginx - redis Kustomizationの マニフェスト で、リソースとして3つ定義されています。この3つのリソースは ディレクト リ名を表していて、それぞれの ディレクト リの中にさらに kustomization.yaml が存在します。一例として nginx ディレクト リにある kustomization.yaml の中を見てみます。 apiVersion : kustomize.config.k8s.io/v1beta1 kind : Kustomization namespace : nginx resources : - namespace.yaml - release.yaml リソースとして マニフェスト の yaml ファイルが定義されています。このように定義された マニフェスト をFluxが検知しデプロイする、という仕組みになっています。 本記事ではinfraの構成を確認してみましたが、appsについても同様です。ただし、appsの依存関係にinfraが設定されています。infraのリソースがデプロイされた後にappsをデプロイするための設定です。 デプロイの確認 まずはFluxが クラスタ にインストールされているかを確認します。ここからは視覚的にわかりやすくするためにAzure Portal を利用します。 AKS のリソースメニューから作成した クラスタ を選択し、ブレードからワークロードを選択します。 名前空間 を flux-system でフィルタすると、Fluxを構成するオブジェクトを確認できます。 Fluxに関する アーキテクチャ は説明しません。興味のある方は こちら をご参照ください。 次にGitOpsの構成を確認します。 ブレードからGitOps(プレビュー)を選択します。 先ほど CLI から作成した構成を確認できます。構成名をクリックして詳細画面に移ります。 現在のデプロイ状況を表す「状態」、同期する リポジトリ を表す「 リポジトリ 」、設定したKustomizationなどを表す「プロパティ」がそれぞれ確認できます。いくつか気になる項目をピックアップします。 コンプライアンス の状態 AzureにはAzure Policyという コンプライアンス を管理するサービスが存在します。そのAzure Policyによる検出結果がこれです。 AKS が対象としている ポリシー はこちらから確認できます。 種類 GitOpsを実現するためのツールが示されています。Flux v2であることがわかりますね。あえて表示しているということは今後ほかのツールにも対応予定なのかもしれません。(筆者個人の感想です) 構成オブジェクト インストールの状態 今回のデプロイ対象のオブジェクト、およびその状態を示しています。 リポジトリ にある kustomization.yaml を展開した結果のオブジェクトです。インストールの状態がSucceedになっているので、もうデプロイは完了しているようです。リンクをクリックして中を見てみます。 設定したKustomization自体や、同期先の リポジトリ を管理するGitRepositoryオブジェクト、 リポジトリ に管理されている マニフェスト で指定したHelmReleaseなどが確認できます。今回指定したサンプル リポジトリ からデプロイされるアプリケーションは podinfo という軽量のWebアプリケーションです。 CLI を利用して動作確認してみます。 次のコマンドで AKS に対する認証情報を取得します。 az aks get-credentials --resource-group < リソースグループ名 > --name < クラスタ名 > podinfoアプリケーションが公開されているポートを手元にポート フォワ ードして、アプリケーションに接続してみます。 # ポートフォワード kubectl -n nginx port-forward svc/nginx-ingress-controller 8081:80 & # アプリケーションへのリクエスト curl -H " Host: podinfo.staging " http://localhost:8081 { " hostname " : " podinfo-6dddd646b6-7d8fb " , " version " : " 6.0.3 " , " revision " : "" , " color " : " #34577c " , " logo " : " https://raw.githubusercontent.com/stefanprodan/podinfo/gh-pages/cuddle_clap.gif " , " message " : " greetings from podinfo v6.0.3 " , " goos " : " linux " , " goarch " : " amd64 " , " runtime " : " go1.16.9 " , " num_goroutine " : " 9 " , " num_cpu " : " 2 " } podinfoからのレスポンスが返ってきました。この hostname はPodの名前と一致しているはずです。podを取得して確認してみます。 kubectl get pods -n podinfo NAME READY STATUS RESTARTS AGE podinfo-6dddd646b6-7d8fb 1 / 1 Running 0 129m デプロイコマンドなど一切なしにアプリケーションをデプロイできました。 おわりに 本記事では AKS のGitOps機能を利用してアプリケーションをデプロイする手順を解説しました。 Flux自体はどのKubernetesプラットフォームにおいても利用可能です 。Azureにおいてはそれを 拡張機能 として利用でき、管理用の GUI が提供されていたり、Azureのサービス(Azure Policy)と組み合わせて利用できるのが利点であると筆者は考えています。 最後までお読みいただきありがとうございました。 執筆: @ueba.yuki 、レビュー: @shibata.takao ( Shodo で執筆されました ) Kuberenetes以外でもGitOpsを実現するツール( PipeCD )はありますが、解説を簡潔にするために今回は説明を省きました ↩
電通国際情報サービス 、クロス イノベーション 本部、オープン イノベーション ラボの 比嘉康雄 です。 今回は、 ブロックチェーン に関する先週のニュースをまとめます。 Ethereum以外のブロックチェーンを使う動きが活発化 クリエーター/ファンエコノミーとDAO その他のニュース Ethereum以外の ブロックチェーン を使う動きが活発化 これまでNFTといえばEthereumでした。しかし、 スループット の低さ、手数料(ガス代)の高さがネックとなりEthereum以外の ブロックチェーン を使う動きが活発化しています。 Dapper LabsのFlowブロックチェーン活用、ミクシィとDAZNがスポーツ特化型NFTマーケットプレイスを今春提供開始 Flowは、 NBA Top Shot でも使われている ブロックチェーン です。 ゲーム特化ブロックチェーン「Oasys」発表、設立メンバーにバンダイナムコやセガも Oasys で面白いのは、レイヤー2をプライベートチェーンにして、手数料(ガス代)を無料にしているところですね。 Polygonがプライベートトークンセールを実施、ソフトバンクなどから約520億円を調達 PolygonはEthereum上のレイヤー2なので、Ethereum以外の ブロックチェーン といって良いのか微妙なところですが、Ethereumのネックを解決する動きとしては一緒ですね。 ク リエータ ー/ファンエコノミーとDAO ク リエータ ーの資金調達の手段として、これまでもNFTが利用されてきましたが、投機的な側面が強いものでした。 しかし、これからはNFTの購入者であるファンを大切にしていく流れが生まれています。 こうしたク リエータ ーとファンを結びつける組織として、DAO(Decentralized Autonomous Organization )を活用する動きが広まっています。 DAOとは分散型で自律的に機能する組織のことです。従来の組織では、中央に意思決定をする組織/人がいて、その決定に従い組織が運営されていました。これに対してDAOでは、ルールに基づいて活動を行い、中央の組織がなくても自動化された運営ができます。 ク リエータ ー/ファンエコノミーがどのようにDAOを利用しているかというと、ファンは、ファンクラブの会員証に当たるNFTを購入します。このNFTがあれば、DAOに所属できます。 DAOに所属していると、ク リエータ ーの Vlog /写真/未公開の曲など、そのDAOに所属していなければ見られないコンテンツを見ることができます。ク リエータ ーとファンが直接チャットできるようにしているDAOもあります。 セレブとビデオチャットできるCameo、限定アートワークなどが手に入るNFTプロジェクト「Cameo Pass」発表 分散型「マーベル」のようなNFTメディア帝国を目指すPixel Vault、約115億円の資金を調達 YouTubeがNFTやライブショッピングなどクリエイターツールを拡充へ、TikTokやInstagramに対抗 YouTube は、まだDAOは活用していませんがそうなっていくんじゃないかと予想します。 その他のニュース グラフィティ&ストリートアートに特化した、東京発のNFTアート専門オークション「TOTEMO」 トークンブリッジのWormhole、ハッカーが約370億円相当の暗号資産を盗んだことを確認 イーサリアム開発者ツールプラットフォーム「Hardhat」開発元、a16zなどの寄付により非営利団体「Nomic Foundation」に 執筆: @higa 、レビュー: @sato.taichi ( Shodo で執筆されました )
電通国際情報サービス 、クロス イノベーション 本部、オープン イノベーション ラボの 比嘉康雄 です。 今回は、 ブロックチェーン に関する先週のニュースをまとめます。 Ethereum以外のブロックチェーンを使う動きが活発化 クリエーター/ファンエコノミーとDAO その他のニュース Ethereum以外の ブロックチェーン を使う動きが活発化 これまでNFTといえばEthereumでした。しかし、 スループット の低さ、手数料(ガス代)の高さがネックとなりEthereum以外の ブロックチェーン を使う動きが活発化しています。 Dapper LabsのFlowブロックチェーン活用、ミクシィとDAZNがスポーツ特化型NFTマーケットプレイスを今春提供開始 Flowは、 NBA Top Shot でも使われている ブロックチェーン です。 ゲーム特化ブロックチェーン「Oasys」発表、設立メンバーにバンダイナムコやセガも Oasys で面白いのは、レイヤー2をプライベートチェーンにして、手数料(ガス代)を無料にしているところですね。 Polygonがプライベートトークンセールを実施、ソフトバンクなどから約520億円を調達 PolygonはEthereum上のレイヤー2なので、Ethereum以外の ブロックチェーン といって良いのか微妙なところですが、Ethereumのネックを解決する動きとしては一緒ですね。 ク リエータ ー/ファンエコノミーとDAO ク リエータ ーの資金調達の手段として、これまでもNFTが利用されてきましたが、投機的な側面が強いものでした。 しかし、これからはNFTの購入者であるファンを大切にしていく流れが生まれています。 こうしたク リエータ ーとファンを結びつける組織として、DAO(Decentralized Autonomous Organization )を活用する動きが広まっています。 DAOとは分散型で自律的に機能する組織のことです。従来の組織では、中央に意思決定をする組織/人がいて、その決定に従い組織が運営されていました。これに対してDAOでは、ルールに基づいて活動を行い、中央の組織がなくても自動化された運営ができます。 ク リエータ ー/ファンエコノミーがどのようにDAOを利用しているかというと、ファンは、ファンクラブの会員証に当たるNFTを購入します。このNFTがあれば、DAOに所属できます。 DAOに所属していると、ク リエータ ーの Vlog /写真/未公開の曲など、そのDAOに所属していなければ見られないコンテンツを見ることができます。ク リエータ ーとファンが直接チャットできるようにしているDAOもあります。 セレブとビデオチャットできるCameo、限定アートワークなどが手に入るNFTプロジェクト「Cameo Pass」発表 分散型「マーベル」のようなNFTメディア帝国を目指すPixel Vault、約115億円の資金を調達 YouTubeがNFTやライブショッピングなどクリエイターツールを拡充へ、TikTokやInstagramに対抗 YouTube は、まだDAOは活用していませんがそうなっていくんじゃないかと予想します。 その他のニュース グラフィティ&ストリートアートに特化した、東京発のNFTアート専門オークション「TOTEMO」 トークンブリッジのWormhole、ハッカーが約370億円相当の暗号資産を盗んだことを確認 イーサリアム開発者ツールプラットフォーム「Hardhat」開発元、a16zなどの寄付により非営利団体「Nomic Foundation」に 執筆: @higa 、レビュー: @sato.taichi ( Shodo で執筆されました )
こんにちは、X(クロス) イノベーション 本部 ソフトウェアデザインセンター セキュリティグループ、2021年新卒入社の大西です。私は昨年10月にセキュリティグループへ配属され、3ヶ月間、技術調査として GitHub 上の機密情報を見つけ出すチェックツールを調査していました。今日は、 GitHub リポジトリ に機密情報をプッシュしてしまった場合に、それを検知するツールについてお話しします。 皆さんは、 ソースコード を書く際に機密情報をハードコードしてしまっていないでしょうか。機密情報をハードコーディングしたまま GitHub 上に公開すると、その情報を不正利用されてしまいます。例えば、 AWS のアクセスキーID、シークレットアクセスキーが漏洩すると、勝手にEC2 インスタンス を立ち上げられて仮想通貨のマイニングに使用され、莫大な請求が届くという事例が相次いでいます。これを防止するためには機密情報のハードコード防止が必要ですが、人間が注意するにしても限界があります。自動化はできないか、と考えたのが今回技術調査を行った背景です。ISIDでも業務で GitHub を利用しており、パブリック リポジトリ もいくつか所有しています。ISIDが持つパブリック リポジトリ は こちら から見られます。 技術調査記録 Gitleaks 使ってみた感想 Secret Scanning 使ってみた感想 今後の対応 技術調査記録 それでは、不正利用などから会社の資産、情報を守るためのチェックツールを調査した記録を書いていきます。 この調査のためにまず行ったことは、候補に挙がっていたチェックツールの特徴や使い方を知ることです。今回いくつかのチェックツールを対象に調査したのですが、 オープンソース ツールも含まれており、 GitHub 上で ソースコード 自体も見ることができました。 それぞれのツールの特徴を掴んだ後は、実際に様々な機密情報(もし流出しても使用できないように失効済み)を リポジトリ に仕込んでから、各ツールでスキャンし検知率や誤検知率、解析速度などを比較しました。ここで時間がかかったのが、 リポジトリ に仕込むための機密情報を様々なプロバイダーから収集してくることです。今回は、 AWS やAzure、 GCP などの クラウド 系を中心に16種類の機密情報を埋め込んだのですが、 クラウド に触るのがほぼ初めてだったのでどこにどんな情報があるのかを探すのが大変でした。社内の クラウド グループの方からもお力をお借りし、無事にターゲットとしていた機密情報をゲットしました。そして、それらを埋め込んだ リポジトリ をスキャンし、この調査で私たちがツールに求める要件が明確になってきました。その要件とは、 - 過去のコミット履歴もスキャンできること - メンテナンス、サポート等が充実していること - 費用面が安く抑えられること でした。 過去のコミット履歴のスキャンに関しては、HEADコミットやmainブランチだけでなく、全てのブランチ、そしてブランチごとの履歴も含め全てスキャンしてくれるツールであることが重要になってきます。なぜなら、履歴に機密情報が含まれていれば簡単にそれを盗めるからです。また、メンテナンス・サポートに関しては、機密情報の種類は年々変わっていくので、検出できる機密情報の種類を増やしたり、検知のルールを変えたりしなければなりません(例えば、 AWS のアクセスキーIDはAKIA, ANPAなどの プレフィックス が付いているが、将来この プレフィックス が変更されると、それに伴って検知のルールも変更しなければならない)。将来のことも考え、細かなところまできっちりメンテナンスしてくれているようなツールを選ぶことが重要であると考えました。費用面に関しては、もちろん安く抑えられた方がいいですね。 というわけで、今回は5つツールを調査しましたが、その中でも良いと判断した オープンソース ツール1つと有償ツール1つをご紹介したいと思います。 Gitleaks Gitleaks は、機密情報をハードコードすることを防ぐ静的解析ツール。 オープンソース なので無償で利用でき、HomebrewやDockerなどから簡単にインストールできる。リモート、ローカルどちらのスキャンも可能。 言語: Go 検出する機密情報の種類: AWS , GCP , SSH , GitHub , Slackなどの機密情報、約100種類(version 8.2.7) https://github.com/zricethezav/gitleaks/blob/master/config/gitleaks.toml GitHub でのStar数: 8.8k 機密情報の検出方法: 正規表現 下図のように"gitleaks detect -v"とコマンドを打つと、検出された機密情報が表示される↓ 1 使ってみた感想 メリット 過去のコミット履歴まで遡って検知してくれる メインブランチだけでなく、他のブランチ、そしてそれぞれのブランチの履歴までスキャンできる ルールのカスタマイズが可能( 正規表現 でルールを書く必要がある) ルールをカスタマイズすればより多くの機密情報をスキャンできる 8系がリリースされ、7系に比べスキャンスピードが速くなった 8系がリリースされてから検知できるシークレット数が増加した(+60種類くらい) pre-commit hookを使用すればコミットする前にスキャンされるため、 GitHub に誤って機密情報をプッシュしてしまうことがなくなる GitHub Actions が GitHub Marketplaceに登録されている ymlファイルに記述するだけで、CI/CDパイプラインの中で検出できる デメリット 8系で検知できるシークレット数が増えた分、誤検知が多くなった 具体的には、調査した リポジトリ の中にIonic API tokenという名前で45件の検出があった ソースコード の中'section ...'という文字列を含むKeyがありその中の'ion 'という文字列が 正規表現 で引っかかった Configファイルのallow listの中に上記の文字列を入れれば、スキャンはスキップされる 正規表現 をカスタマイズすれば誤検知を減らすことができる Secret Scanning Secret Scanningは GitHub が提供するスキャン機能。Secret Scanningは、すべてのパブリック リポジトリ 、および GitHub Advanced Securityが有効になっている組織が所有するプライベー トリポジ トリで利用できる。パブリック リポジトリ では自動的にSecret Scanningが有効になり、 リポジトリ をプッシュすると、コンテンツをスキャンして機密情報を探す。 検出する機密情報の種類: - パブリック リポジトリ :約100種類 - プライベー トリポジ トリ:約100種類 詳しくは、 こちら のページで! GitHub リポジトリ のメインページ -> Securityタブ -> 左サイドバーのSecret scanning alertsをクリックすると、機密情報が見つかった場合その一覧が見られる↓ 2 使ってみた感想 メリット Secret Scanningで機密情報が検出された場合、 GitHub が機密情報を発行したサービスプロバイダーと連携をとって対応に当たってくれる パブリック リポジトリ トーク ンなどの機密情報(シークレット)を発行したサービスプロバイダー( AWS , Azureなど)に通知する サービスプロバイダーは、資格情報を検証してから、シークレットを取り消すか、新しいシークレットを発行するか、直接連絡するかを決定する(ユーザーまたはサービスプロバイダーに関連するリスクによって異なる) プライベー トリポジ トリ リポジトリ 管理者と組織の所有者にメールアラートを送信する リポジトリ にシークレットをコミットしたユーザーに対し、関連するシークレットスキャンアラートへのリンクを含む電子メールアラートを送信する。コミット作成者は、 リポジトリ 内のアラートを表示し、アラートを解決できる。 GitHub は リポジトリ にアラートを表示する Secret Scanningを使用していて困った時に GitHub 社のサポートを受けられる(英語対応) ルールのカスタマイズが可能( 正規表現 でルールを書く必要がある) デメリット プライベー トリポジ トリをスキャンするためには、所属する組織が、有償の GitHub Advanced Securityをオプション購入してからSecret Scanningを有効にしなければならない リポジトリ をプッシュした後にスキャンするため、スキャンする時点ですでに機密情報が漏れている可能性がある 今後の対応 今後は、試験運用として、Gitleaksを使って機密情報のスキャンをしていくことになりました。理由としては、上記でも述べたように、過去のコミット履歴もスキャンできること、メンテナンスが充実していること、無償で利用できることがあげられます。また、 GitHub 上のコミュニケーションも活発で、例えば、投稿されたissueはアクティブに対応されています。Gitleaksで社内の リポジトリ を定期的にスキャンし、機密情報が検出された時は リポジトリ 所有者に通達するなどし、開発者のセキュリティ意識向上につなげていきます。 (もしも、機密情報を見つけたら......) もし、機密情報を GitHub にプッシュしていることに気が付いたら、その情報を完全に削除するのには手間がかかります。なぜなら、gitの仕組み上変更履歴は全てツリー中に含まれており、履歴をたどれば機密情報の含まれたコミットまでたどり着けることがあるため、履歴を全て改変する必要があるからです。機密情報の含まれたコミットをいかなるブランチやタグからも遡れないようにする必要があります。そのためにはBFGツールなどを使ってgit リポジトリ の履歴から特定の文字列やファイルを削除します。また、 GitHub 上ではgit リポジトリ そのものの他に、Pull RequestやIssueに貼られたEmbed commentなど、git リポジトリ 内のコンテンツが表示されうる機会が存在します。 これらの情報を完全に削除するには GitHub のサポートに連絡して削除してもらうしかありません。 機密情報の削除については こちら の記事が参考になりました。 今後はツールを活用し機密情報を外部に漏らさない対策を強化していきたいと思います。 執筆: @onishi.mayu 、レビュー: @higa ( Shodo で執筆されました ) 図は https://asciinema.org/a/455683 のものを引用しています ↩ 図は https://docs.github.com/en/enterprise-cloud@latest/code-security/secret-scanning/managing-alerts-from-secret-scanning?learn=secret_scanning&learnProduct=code-security のものを引用しています ↩
こんにちは、X(クロス) イノベーション 本部 ソフトウェアデザインセンター セキュリティグループ、2021年新卒入社の大西です。私は昨年10月にセキュリティグループへ配属され、3ヶ月間、技術調査として GitHub 上の機密情報を見つけ出すチェックツールを調査していました。今日は、 GitHub リポジトリ に機密情報をプッシュしてしまった場合に、それを検知するツールについてお話しします。 皆さんは、 ソースコード を書く際に機密情報をハードコードしてしまっていないでしょうか。機密情報をハードコーディングしたまま GitHub 上に公開すると、その情報を不正利用されてしまいます。例えば、 AWS のアクセスキーID、シークレットアクセスキーが漏洩すると、勝手にEC2 インスタンス を立ち上げられて仮想通貨のマイニングに使用され、莫大な請求が届くという事例が相次いでいます。これを防止するためには機密情報のハードコード防止が必要ですが、人間が注意するにしても限界があります。自動化はできないか、と考えたのが今回技術調査を行った背景です。ISIDでも業務で GitHub を利用しており、パブリック リポジトリ もいくつか所有しています。ISIDが持つパブリック リポジトリ は こちら から見られます。 技術調査記録 Gitleaks 使ってみた感想 Secret Scanning 使ってみた感想 今後の対応 技術調査記録 それでは、不正利用などから会社の資産、情報を守るためのチェックツールを調査した記録を書いていきます。 この調査のためにまず行ったことは、候補に挙がっていたチェックツールの特徴や使い方を知ることです。今回いくつかのチェックツールを対象に調査したのですが、 オープンソース ツールも含まれており、 GitHub 上で ソースコード 自体も見ることができました。 それぞれのツールの特徴を掴んだ後は、実際に様々な機密情報(もし流出しても使用できないように失効済み)を リポジトリ に仕込んでから、各ツールでスキャンし検知率や誤検知率、解析速度などを比較しました。ここで時間がかかったのが、 リポジトリ に仕込むための機密情報を様々なプロバイダーから収集してくることです。今回は、 AWS やAzure、 GCP などの クラウド 系を中心に16種類の機密情報を埋め込んだのですが、 クラウド に触るのがほぼ初めてだったのでどこにどんな情報があるのかを探すのが大変でした。社内の クラウド グループの方からもお力をお借りし、無事にターゲットとしていた機密情報をゲットしました。そして、それらを埋め込んだ リポジトリ をスキャンし、この調査で私たちがツールに求める要件が明確になってきました。その要件とは、 - 過去のコミット履歴もスキャンできること - メンテナンス、サポート等が充実していること - 費用面が安く抑えられること でした。 過去のコミット履歴のスキャンに関しては、HEADコミットやmainブランチだけでなく、全てのブランチ、そしてブランチごとの履歴も含め全てスキャンしてくれるツールであることが重要になってきます。なぜなら、履歴に機密情報が含まれていれば簡単にそれを盗めるからです。また、メンテナンス・サポートに関しては、機密情報の種類は年々変わっていくので、検出できる機密情報の種類を増やしたり、検知のルールを変えたりしなければなりません(例えば、 AWS のアクセスキーIDはAKIA, ANPAなどの プレフィックス が付いているが、将来この プレフィックス が変更されると、それに伴って検知のルールも変更しなければならない)。将来のことも考え、細かなところまできっちりメンテナンスしてくれているようなツールを選ぶことが重要であると考えました。費用面に関しては、もちろん安く抑えられた方がいいですね。 というわけで、今回は5つツールを調査しましたが、その中でも良いと判断した オープンソース ツール1つと有償ツール1つをご紹介したいと思います。 Gitleaks Gitleaks は、機密情報をハードコードすることを防ぐ静的解析ツール。 オープンソース なので無償で利用でき、HomebrewやDockerなどから簡単にインストールできる。リモート、ローカルどちらのスキャンも可能。 言語: Go 検出する機密情報の種類: AWS , GCP , SSH , GitHub , Slackなどの機密情報、約100種類(version 8.2.7) https://github.com/zricethezav/gitleaks/blob/master/config/gitleaks.toml GitHub でのStar数: 8.8k 機密情報の検出方法: 正規表現 下図のように"gitleaks detect -v"とコマンドを打つと、検出された機密情報が表示される↓ 1 使ってみた感想 メリット 過去のコミット履歴まで遡って検知してくれる メインブランチだけでなく、他のブランチ、そしてそれぞれのブランチの履歴までスキャンできる ルールのカスタマイズが可能( 正規表現 でルールを書く必要がある) ルールをカスタマイズすればより多くの機密情報をスキャンできる 8系がリリースされ、7系に比べスキャンスピードが速くなった 8系がリリースされてから検知できるシークレット数が増加した(+60種類くらい) pre-commit hookを使用すればコミットする前にスキャンされるため、 GitHub に誤って機密情報をプッシュしてしまうことがなくなる GitHub Actions が GitHub Marketplaceに登録されている ymlファイルに記述するだけで、CI/CDパイプラインの中で検出できる デメリット 8系で検知できるシークレット数が増えた分、誤検知が多くなった 具体的には、調査した リポジトリ の中にIonic API tokenという名前で45件の検出があった ソースコード の中'section ...'という文字列を含むKeyがありその中の'ion 'という文字列が 正規表現 で引っかかった Configファイルのallow listの中に上記の文字列を入れれば、スキャンはスキップされる 正規表現 をカスタマイズすれば誤検知を減らすことができる Secret Scanning Secret Scanningは GitHub が提供するスキャン機能。Secret Scanningは、すべてのパブリック リポジトリ 、および GitHub Advanced Securityが有効になっている組織が所有するプライベー トリポジ トリで利用できる。パブリック リポジトリ では自動的にSecret Scanningが有効になり、 リポジトリ をプッシュすると、コンテンツをスキャンして機密情報を探す。 検出する機密情報の種類: - パブリック リポジトリ :約100種類 - プライベー トリポジ トリ:約100種類 詳しくは、 こちら のページで! GitHub リポジトリ のメインページ -> Securityタブ -> 左サイドバーのSecret scanning alertsをクリックすると、機密情報が見つかった場合その一覧が見られる↓ 2 使ってみた感想 メリット Secret Scanningで機密情報が検出された場合、 GitHub が機密情報を発行したサービスプロバイダーと連携をとって対応に当たってくれる パブリック リポジトリ トーク ンなどの機密情報(シークレット)を発行したサービスプロバイダー( AWS , Azureなど)に通知する サービスプロバイダーは、資格情報を検証してから、シークレットを取り消すか、新しいシークレットを発行するか、直接連絡するかを決定する(ユーザーまたはサービスプロバイダーに関連するリスクによって異なる) プライベー トリポジ トリ リポジトリ 管理者と組織の所有者にメールアラートを送信する リポジトリ にシークレットをコミットしたユーザーに対し、関連するシークレットスキャンアラートへのリンクを含む電子メールアラートを送信する。コミット作成者は、 リポジトリ 内のアラートを表示し、アラートを解決できる。 GitHub は リポジトリ にアラートを表示する Secret Scanningを使用していて困った時に GitHub 社のサポートを受けられる(英語対応) ルールのカスタマイズが可能( 正規表現 でルールを書く必要がある) デメリット プライベー トリポジ トリをスキャンするためには、所属する組織が、有償の GitHub Advanced Securityをオプション購入してからSecret Scanningを有効にしなければならない リポジトリ をプッシュした後にスキャンするため、スキャンする時点ですでに機密情報が漏れている可能性がある 今後の対応 今後は、試験運用として、Gitleaksを使って機密情報のスキャンをしていくことになりました。理由としては、上記でも述べたように、過去のコミット履歴もスキャンできること、メンテナンスが充実していること、無償で利用できることがあげられます。また、 GitHub 上のコミュニケーションも活発で、例えば、投稿されたissueはアクティブに対応されています。Gitleaksで社内の リポジトリ を定期的にスキャンし、機密情報が検出された時は リポジトリ 所有者に通達するなどし、開発者のセキュリティ意識向上につなげていきます。 (もしも、機密情報を見つけたら......) もし、機密情報を GitHub にプッシュしていることに気が付いたら、その情報を完全に削除するのには手間がかかります。なぜなら、gitの仕組み上変更履歴は全てツリー中に含まれており、履歴をたどれば機密情報の含まれたコミットまでたどり着けることがあるため、履歴を全て改変する必要があるからです。機密情報の含まれたコミットをいかなるブランチやタグからも遡れないようにする必要があります。そのためにはBFGツールなどを使ってgit リポジトリ の履歴から特定の文字列やファイルを削除します。また、 GitHub 上ではgit リポジトリ そのものの他に、Pull RequestやIssueに貼られたEmbed commentなど、git リポジトリ 内のコンテンツが表示されうる機会が存在します。 これらの情報を完全に削除するには GitHub のサポートに連絡して削除してもらうしかありません。 機密情報の削除については こちら の記事が参考になりました。 今後はツールを活用し機密情報を外部に漏らさない対策を強化していきたいと思います。 執筆: @onishi.mayu 、レビュー: @higa ( Shodo で執筆されました ) 図は https://asciinema.org/a/455683 のものを引用しています ↩ 図は https://docs.github.com/en/enterprise-cloud@latest/code-security/secret-scanning/managing-alerts-from-secret-scanning?learn=secret_scanning&learnProduct=code-security のものを引用しています ↩
こんにちは。XI本部 クラウド イノベーション センターの柴田です。 最近ではアプリケーションを実行する手段としてコンテナ技術が広く用いられています。 しかし、本番環境で稼働できる品質のコンテナイメージを作る際、初学者がコンテナ設計の段階で見落としがちなポイントがいくつかあります。 そこで今回はコンテナイメージを設計する際の推奨事項をいくつかご紹介したいと思います。 コンテナとは コンテナイメージを設計する際の推奨事項 The Twelve-Factor Appに従ってアプリケーションを実装する プロセス:アプリケーションを1つもしくは複数のステートレスなプロセスとして実行する 廃棄容易性:高速な起動とグレースフルシャットダウンで堅ろう性を最大化する ログ:ログをイベントストリームとして扱う 1コンテナにつき1アプリケーション コンテナイメージに余分なパッケージを含めない 適切なベースイメージを選択する マルチステージビルドを活用する コンテナイメージに機密情報を含めない コンテナ内におけるアプリケーションの実行ユーザーを root 以外に変更する ベストプラクティスに従ってDockerfileを書く コンテナイメージの脆弱性スキャンを実施する おわりに 参考 コンテナとは コンテナは仮想化技術の一種です。あらかじめ作成したコンテナイメージをもとに、異なる環境上で環境の影響を受けずにコンテナ化したアプリケーションを実行できます。 コンテナにはいくつかのメリットがあります。 可搬性が高い :コンテナを使うことで、あらかじめ作成したコンテナイメージをもとに、異なる環境上で環境の影響を受けずにコンテナ化したアプリケーションを実行できます。例えば、開発環境と本番環境の間に差異があって開発環境で動いたアプリケーションを本番環境にデプロイしたところ動かなかった、といった事態をある程度防ぐことができます。 仮想マシン と比べて軽量 :従来のハイパーバイザー型の 仮想マシン と異なり、コンテナはホストマシンの カーネル を利用してプロセスとして起動します。そのためコンテナは 仮想マシン と比べて高速に起動・停止できます。 コンテナイメージを設計する際の推奨事項 The Twelve-Factor Appに従ってアプリケーションを実装する コンテナ化するアプリケーションは The Twelve-Factor App に従っていることが望ましいです。The Twelve-Factor Appはモダンなアプリケーション開発における12個のベストプ ラク ティスです。 コードベース :バージョン管理されている1つのコードベースと複数のデプロイ 依存関係 :依存関係を明示的に宣言し分離する 設定 :設定を 環境変数 に格納する バックエンドサービス :バックエンドサービスをアタッチされたリソースとして扱う ビルド、リリース、実行 :ビルド、リリース、実行の3つのステージを厳密に分離する プロセス :アプリケーションを1つもしくは複数のステートレスなプロセスとして実行する ポート バインディング :ポート バインディング を通してサービスを公開する 並行性 : プロセスモデル によってスケールアウトする 廃棄容易性 :高速な起動とグレースフルシャットダウンで堅ろう性を最大化する 開発/本番一致 :開発、ステージング、本番環境をできるだけ一致させた状態を保つ ログ :ログをイベントストリームとして扱う 管理プロセス :管理タスクを1回限りのプロセスとして実行する 詳細は The Twelve-Factor App を参照ください。 コンテナのライフサイクルは 仮想マシン と比べて短く 基盤障害とそれに伴う自動復旧 オートスケーリング 新しいバージョンのコンテナイメージのデプロイ などをトリガーにコンテナの終了・再作成が頻繁に発生します。アプリケーションのコンテナをいつでも安全に終了できることができるよう、特に「6.プロセス」「9.廃棄容易性」「11.ログ」は適切に実装することが望ましいです。 プロセス:アプリケーションを1つもしくは複数のステートレスなプロセスとして実行する コンテナが永続データやセッション情報を持っている場合、コンテナを安全に終了するのが難しくなります。永続データやセッション情報はできるだけ外部のデータストアで管理し、コンテナはなるべくステートレスにするのが望ましいです。 廃棄容易性:高速な起動とグレースフルシャットダウンで堅ろう性を最大化する アプリケーションのコンテナはいつでもユーザーへの影響なく安全に終了できるよう実装されていることが望ましいです。 アプリケーションを安全に終了する方法の1つにSIGTERMシグナルの適切な処理が挙げられます。多くのコンテナ オーケストレーション ツールはコンテナの終了時にSIGTERMシグナルを送信します。例えばWebアプリケーションならSIGTERMシグナルを受け取ったら現在のリク エス トを全て処理した後で安全に終了するようアプリケーションを実装するとよいでしょう。 ログ:ログをイベントストリームとして扱う アプリケーションのログをファイルとして出力している場合、コンテナの終了に伴うログ消失の恐れがあります。アプリケーションのログは標準出力・ 標準エラー出力 に出力し、コンテナ オーケストレーション ツール側で収集・保存することが望ましいです。 1コンテナにつき1アプリケーション 1つのコンテナにつき1つのアプリケーションのみを起動することが望ましいです。 仮想マシン では1つの 仮想マシン 上でWeb・AP・DBなど複数のアプリケーションを起動することがありましたが、コンテナでは1つのコンテナ上に複数のアプリケーションを起動することは推奨されません。かわりに、アプリケーションごとにコンテナを起動してください。 コンテナイメージに余分なパッケージを含めない 攻撃者による攻撃を防ぐため、本番環境で実行するコンテナイメージは、余分なパッケージがインストールされておらず、攻撃の余地は少ないことが望ましいです。 適切なベースイメージを選択する アプリケーションをコンテナ化する際、まずベースとなるコンテナイメージを選択します。ベースイメージは軽量かつセキュアなものを選択することが望ましいです。具体的にはまず distroless の使用を検討するとよいでしょう。 マルチステージビルドを活用する ソースコード や コンパイラ など、アプリケーションのビルド時には必要だけれども実行時には不要なパッケージがあります。 マルチステージビルド を活用することで、アプリケーションのビルド用コンテナイメージと実行用コンテナイメージを分離し、最終的なビルド成果物のコンテナイメージに含まれるパッケージを最小化できます。 コンテナイメージに機密情報を含めない コンテナイメージにはクレデンシャルなどの機密情報を含めないでください。かわりに、クレデンシャルなどの機密情報はコンテナの実行時に 環境変数 経由でアプリケーションへ渡すようにしてください。 また以下のようなDockerfileを書かないようにしてください。 rm コマンドで機密情報を削除してもコンテナイメージのレイヤーとして機密情報が残ります。 # 機密情報をコンテナイメージへ追加 COPY credentials ./ # 何らかの処理を実行 RUN ... # コンテナイメージから不要になった機密情報を削除(実際にはcredentialsはレイヤとしてコンテナイメージに残っている) RUN rm ./credentials コンテナ内におけるアプリケーションの実行ユーザーを root 以外に変更する コンテナ内におけるアプリケーションの実行ユーザーは root 以外に変更することが望ましいです。 万が一攻撃者にアプリケーションの 脆弱性 を悪用された場合、実行ユーザーが root だと、コンテナだけでなく、コンテナの稼働するホストマシンも攻撃される恐れがあります。 ベストプ ラク ティスに従ってDockerfileを書く Dockerfileはベストプ ラク ティスに従って記述することが望ましいです。 Best practices for writing Dockerfiles | Docker Documentation Dockerfileがベストプ ラク ティスに従っているかを 機械的 にチェックしてくれるツールも存在します。 hadolint dockle コンテナイメージの 脆弱性 スキャンを実施する コンテナイメージに 脆弱性 のあるパッケージが含まれていないか定期的にスキャンすることが望ましいです。 コンテナイメージの 脆弱性 スキャンを実行するツールには例えば以下があります。 Trivy Clair また主要なイメージ レジストリ ではコンテナイメージの登録時に自動的に 脆弱性 スキャンを実行する機能を提供しています。 Amazon ECR Azure Container Registry Google Container Registry Docker Hub (有償プランのみ) おわりに 本記事では、まだコンテナをあまり使い馴れていない初学者の方向けに、コンテナイメージを設計する際の推奨事項をいくつかご紹介しました。本記事が読んでいただいた方のお役に立てば幸いです。 参考 The Twelve-Factor App (日本語訳) Best practices for writing Dockerfiles | Docker Documentation コンテナ構築のおすすめの方法  |  Cloud アーキテクチャ センター  |  Google Cloud Dockerfileのベストプラクティス Top 20 | Sysdig ECS のアプリケーションを正常にシャットダウンする方法 | Amazon Web Services ブログ What a Windows Container looks like ? - Speaker Deck 軽量Dockerイメージに安易にAlpineを使うのはやめたほうがいいという話 - inductor's blog Kubernetes完全ガイド 第2版 - インプレスブックス Docker/Kubernetes開発・運用のためのセキュリティ実践ガイド(Compass Booksシリーズ) | マイナビブックス 執筆: @shibata.takao 、レビュー: @fhiroaki ( Shodo で執筆されました )
こんにちは。XI本部 クラウド イノベーション センターの柴田です。 最近ではアプリケーションを実行する手段としてコンテナ技術が広く用いられています。 しかし、本番環境で稼働できる品質のコンテナイメージを作る際、初学者がコンテナ設計の段階で見落としがちなポイントがいくつかあります。 そこで今回はコンテナイメージを設計する際の推奨事項をいくつかご紹介したいと思います。 コンテナとは コンテナイメージを設計する際の推奨事項 The Twelve-Factor Appに従ってアプリケーションを実装する プロセス:アプリケーションを1つもしくは複数のステートレスなプロセスとして実行する 廃棄容易性:高速な起動とグレースフルシャットダウンで堅ろう性を最大化する ログ:ログをイベントストリームとして扱う 1コンテナにつき1アプリケーション コンテナイメージに余分なパッケージを含めない 適切なベースイメージを選択する マルチステージビルドを活用する コンテナイメージに機密情報を含めない コンテナ内におけるアプリケーションの実行ユーザーを root 以外に変更する ベストプラクティスに従ってDockerfileを書く コンテナイメージの脆弱性スキャンを実施する おわりに 参考 コンテナとは コンテナは仮想化技術の一種です。あらかじめ作成したコンテナイメージをもとに、異なる環境上で環境の影響を受けずにコンテナ化したアプリケーションを実行できます。 コンテナにはいくつかのメリットがあります。 可搬性が高い :コンテナを使うことで、あらかじめ作成したコンテナイメージをもとに、異なる環境上で環境の影響を受けずにコンテナ化したアプリケーションを実行できます。例えば、開発環境と本番環境の間に差異があって開発環境で動いたアプリケーションを本番環境にデプロイしたところ動かなかった、といった事態をある程度防ぐことができます。 仮想マシン と比べて軽量 :従来のハイパーバイザー型の 仮想マシン と異なり、コンテナはホストマシンの カーネル を利用してプロセスとして起動します。そのためコンテナは 仮想マシン と比べて高速に起動・停止できます。 コンテナイメージを設計する際の推奨事項 The Twelve-Factor Appに従ってアプリケーションを実装する コンテナ化するアプリケーションは The Twelve-Factor App に従っていることが望ましいです。The Twelve-Factor Appはモダンなアプリケーション開発における12個のベストプ ラク ティスです。 コードベース :バージョン管理されている1つのコードベースと複数のデプロイ 依存関係 :依存関係を明示的に宣言し分離する 設定 :設定を 環境変数 に格納する バックエンドサービス :バックエンドサービスをアタッチされたリソースとして扱う ビルド、リリース、実行 :ビルド、リリース、実行の3つのステージを厳密に分離する プロセス :アプリケーションを1つもしくは複数のステートレスなプロセスとして実行する ポート バインディング :ポート バインディング を通してサービスを公開する 並行性 : プロセスモデル によってスケールアウトする 廃棄容易性 :高速な起動とグレースフルシャットダウンで堅ろう性を最大化する 開発/本番一致 :開発、ステージング、本番環境をできるだけ一致させた状態を保つ ログ :ログをイベントストリームとして扱う 管理プロセス :管理タスクを1回限りのプロセスとして実行する 詳細は The Twelve-Factor App を参照ください。 コンテナのライフサイクルは 仮想マシン と比べて短く 基盤障害とそれに伴う自動復旧 オートスケーリング 新しいバージョンのコンテナイメージのデプロイ などをトリガーにコンテナの終了・再作成が頻繁に発生します。アプリケーションのコンテナをいつでも安全に終了できることができるよう、特に「6.プロセス」「9.廃棄容易性」「11.ログ」は適切に実装することが望ましいです。 プロセス:アプリケーションを1つもしくは複数のステートレスなプロセスとして実行する コンテナが永続データやセッション情報を持っている場合、コンテナを安全に終了するのが難しくなります。永続データやセッション情報はできるだけ外部のデータストアで管理し、コンテナはなるべくステートレスにするのが望ましいです。 廃棄容易性:高速な起動とグレースフルシャットダウンで堅ろう性を最大化する アプリケーションのコンテナはいつでもユーザーへの影響なく安全に終了できるよう実装されていることが望ましいです。 アプリケーションを安全に終了する方法の1つにSIGTERMシグナルの適切な処理が挙げられます。多くのコンテナ オーケストレーション ツールはコンテナの終了時にSIGTERMシグナルを送信します。例えばWebアプリケーションならSIGTERMシグナルを受け取ったら現在のリク エス トを全て処理した後で安全に終了するようアプリケーションを実装するとよいでしょう。 ログ:ログをイベントストリームとして扱う アプリケーションのログをファイルとして出力している場合、コンテナの終了に伴うログ消失の恐れがあります。アプリケーションのログは標準出力・ 標準エラー出力 に出力し、コンテナ オーケストレーション ツール側で収集・保存することが望ましいです。 1コンテナにつき1アプリケーション 1つのコンテナにつき1つのアプリケーションのみを起動することが望ましいです。 仮想マシン では1つの 仮想マシン 上でWeb・AP・DBなど複数のアプリケーションを起動することがありましたが、コンテナでは1つのコンテナ上に複数のアプリケーションを起動することは推奨されません。かわりに、アプリケーションごとにコンテナを起動してください。 コンテナイメージに余分なパッケージを含めない 攻撃者による攻撃を防ぐため、本番環境で実行するコンテナイメージは、余分なパッケージがインストールされておらず、攻撃の余地は少ないことが望ましいです。 適切なベースイメージを選択する アプリケーションをコンテナ化する際、まずベースとなるコンテナイメージを選択します。ベースイメージは軽量かつセキュアなものを選択することが望ましいです。具体的にはまず distroless の使用を検討するとよいでしょう。 マルチステージビルドを活用する ソースコード や コンパイラ など、アプリケーションのビルド時には必要だけれども実行時には不要なパッケージがあります。 マルチステージビルド を活用することで、アプリケーションのビルド用コンテナイメージと実行用コンテナイメージを分離し、最終的なビルド成果物のコンテナイメージに含まれるパッケージを最小化できます。 コンテナイメージに機密情報を含めない コンテナイメージにはクレデンシャルなどの機密情報を含めないでください。かわりに、クレデンシャルなどの機密情報はコンテナの実行時に 環境変数 経由でアプリケーションへ渡すようにしてください。 また以下のようなDockerfileを書かないようにしてください。 rm コマンドで機密情報を削除してもコンテナイメージのレイヤーとして機密情報が残ります。 # 機密情報をコンテナイメージへ追加 COPY credentials ./ # 何らかの処理を実行 RUN ... # コンテナイメージから不要になった機密情報を削除(実際にはcredentialsはレイヤとしてコンテナイメージに残っている) RUN rm ./credentials コンテナ内におけるアプリケーションの実行ユーザーを root 以外に変更する コンテナ内におけるアプリケーションの実行ユーザーは root 以外に変更することが望ましいです。 万が一攻撃者にアプリケーションの 脆弱性 を悪用された場合、実行ユーザーが root だと、コンテナだけでなく、コンテナの稼働するホストマシンも攻撃される恐れがあります。 ベストプ ラク ティスに従ってDockerfileを書く Dockerfileはベストプ ラク ティスに従って記述することが望ましいです。 Best practices for writing Dockerfiles | Docker Documentation Dockerfileがベストプ ラク ティスに従っているかを 機械的 にチェックしてくれるツールも存在します。 hadolint dockle コンテナイメージの 脆弱性 スキャンを実施する コンテナイメージに 脆弱性 のあるパッケージが含まれていないか定期的にスキャンすることが望ましいです。 コンテナイメージの 脆弱性 スキャンを実行するツールには例えば以下があります。 Trivy Clair また主要なイメージ レジストリ ではコンテナイメージの登録時に自動的に 脆弱性 スキャンを実行する機能を提供しています。 Amazon ECR Azure Container Registry Google Container Registry Docker Hub (有償プランのみ) おわりに 本記事では、まだコンテナをあまり使い馴れていない初学者の方向けに、コンテナイメージを設計する際の推奨事項をいくつかご紹介しました。本記事が読んでいただいた方のお役に立てば幸いです。 参考 The Twelve-Factor App (日本語訳) Best practices for writing Dockerfiles | Docker Documentation コンテナ構築のおすすめの方法  |  Cloud アーキテクチャ センター  |  Google Cloud Dockerfileのベストプラクティス Top 20 | Sysdig ECS のアプリケーションを正常にシャットダウンする方法 | Amazon Web Services ブログ What a Windows Container looks like ? - Speaker Deck 軽量Dockerイメージに安易にAlpineを使うのはやめたほうがいいという話 - inductor's blog Kubernetes完全ガイド 第2版 - インプレスブックス Docker/Kubernetes開発・運用のためのセキュリティ実践ガイド(Compass Booksシリーズ) | マイナビブックス 執筆: @shibata.takao 、レビュー: @fhiroaki ( Shodo で執筆されました )
みなさん、こんにちは。 電通国際情報サービス (ISID)コーポレート本部システム推進部の宮井です。この記事ではISIDの基幹系システムのDB変更( Oracle → Amazon Aurora )にまつわる意思決定のお話をします。 自己紹介 なぜOracleから移行するのか おわりに 自己紹介 その前に少しだけ自己紹介を。わたくし「システム推進部」という部署の部長を務めているのですが、「システム推進部」という部署名って、これだけ聞いてもよく分からないですよね? えぇ、私もそう思います。一言で申し上げれば、「情シス+α」といったところです。社内インフラ・ネットワークに加え基幹系システムの開発/運用/保守、はたまたIT全般統制、さらには情報セキュリティといった業務領域をカバーする部署となります。 なぜ Oracle から移行するのか いま「基幹系システムの開発」と書きましたが、一般的に基幹系システムってパッケージを買ってきて必要なカスタマイズを施したうえで使うというケースが多い・・・ですよね? ですが、ISIDではなにを思ったか(!?)、十数年前になんと フルスクラッチ で自社開発してしまいました。そうして生まれた基幹系システムは、社内から寄せられる手厳しい声に耐えながらも(涙)、その後さまざまなエンハンスを積み重ね現在に至るまでいちおうISIDグループの屋台骨を裏から支えています。 で、今般、その基幹系システムのDBを Oracle から PostgreSQL 、正確に言えば PostgreSQL と互換性のある Amazon Aurora に乗り換えることとなりました。 ご承知のとおり、 Oracle は確かに抜群の実績と信頼性を誇ります。ですが、いかんせんお値段がちと高い。加えてライセンス体系も非常に複雑、さらには保守費用が毎年数%ずつ 複利 方式で上がっていくというオマケも。(涙) 基幹系システムということもあり、これまではずっと Oracle を使い続けてきました。しかし、こうしたコストやリスクの点、他の DBMS も機能面や信頼性の面で Oracle に比肩するほど充実してきている点を考慮し、今回Auroraへ乗り換える方針としました。 決定打となったのは、コストシミュレーション。 当然ながらDBを変えることにより大規模なシステム改修/テストが必要となり、それには相応のコストが掛かるわけです。それでもなお、乗り換えることで大きなコストメリットが得られるという結果になりました。(あくまで弊社での使い方を想定した場合ですので、この点は十分にご注意ください) また、わたくし個人的には 社内システムも従来の重厚長大で安全確実なガチガチ路線から、リスクを取ってより良い方向を目指して挑戦したい という思いもあります。 おわりに かくして始まった Oracle 卒業プロジェクトですが、実はまだ開発の真っ最中です。実際にやってみて技術面でどういった課題があり、それをどのようなアプローチで乗り越えていったのか等、後日に改めてこのISID Tech Blogでお伝えする予定です。 有益な情報をみなさまにご提供できるようにするためにも、なにはともあれプロジェクト関係者一同、 Oracle 卒業プロジェクトを成功させるべく、ガンバリマス。 最後までお読みいただき、ありがとうございました。 執筆: @miyai 、レビュー: @handa.kenta ( Shodo で執筆されました )
みなさん、こんにちは。 電通国際情報サービス (ISID)コーポレート本部システム推進部の宮井です。この記事ではISIDの基幹系システムのDB変更( Oracle → Amazon Aurora )にまつわる意思決定のお話をします。 自己紹介 なぜOracleから移行するのか おわりに 自己紹介 その前に少しだけ自己紹介を。わたくし「システム推進部」という部署の部長を務めているのですが、「システム推進部」という部署名って、これだけ聞いてもよく分からないですよね? えぇ、私もそう思います。一言で申し上げれば、「情シス+α」といったところです。社内インフラ・ネットワークに加え基幹系システムの開発/運用/保守、はたまたIT全般統制、さらには情報セキュリティといった業務領域をカバーする部署となります。 なぜ Oracle から移行するのか いま「基幹系システムの開発」と書きましたが、一般的に基幹系システムってパッケージを買ってきて必要なカスタマイズを施したうえで使うというケースが多い・・・ですよね? ですが、ISIDではなにを思ったか(!?)、十数年前になんと フルスクラッチ で自社開発してしまいました。そうして生まれた基幹系システムは、社内から寄せられる手厳しい声に耐えながらも(涙)、その後さまざまなエンハンスを積み重ね現在に至るまでいちおうISIDグループの屋台骨を裏から支えています。 で、今般、その基幹系システムのDBを Oracle から PostgreSQL 、正確に言えば PostgreSQL と互換性のある Amazon Aurora に乗り換えることとなりました。 ご承知のとおり、 Oracle は確かに抜群の実績と信頼性を誇ります。ですが、いかんせんお値段がちと高い。加えてライセンス体系も非常に複雑、さらには保守費用が毎年数%ずつ 複利 方式で上がっていくというオマケも。(涙) 基幹系システムということもあり、これまではずっと Oracle を使い続けてきました。しかし、こうしたコストやリスクの点、他の DBMS も機能面や信頼性の面で Oracle に比肩するほど充実してきている点を考慮し、今回Auroraへ乗り換える方針としました。 決定打となったのは、コストシミュレーション。 当然ながらDBを変えることにより大規模なシステム改修/テストが必要となり、それには相応のコストが掛かるわけです。それでもなお、乗り換えることで大きなコストメリットが得られるという結果になりました。(あくまで弊社での使い方を想定した場合ですので、この点は十分にご注意ください) また、わたくし個人的には 社内システムも従来の重厚長大で安全確実なガチガチ路線から、リスクを取ってより良い方向を目指して挑戦したい という思いもあります。 おわりに かくして始まった Oracle 卒業プロジェクトですが、実はまだ開発の真っ最中です。実際にやってみて技術面でどういった課題があり、それをどのようなアプローチで乗り越えていったのか等、後日に改めてこのISID Tech Blogでお伝えする予定です。 有益な情報をみなさまにご提供できるようにするためにも、なにはともあれプロジェクト関係者一同、 Oracle 卒業プロジェクトを成功させるべく、ガンバリマス。 最後までお読みいただき、ありがとうございました。 執筆: @miyai 、レビュー: @handa.kenta ( Shodo で執筆されました )
みなさんこんにちは、 電通国際情報サービス (ISID)X イノベーション 本部ソフトウェアデザインセンターの佐藤太一です。 この記事では、Git を使った仕事のやり方(以降は Git ワークフローと記載)を設計する上での検討事項を説明します。 これによって、読者の皆さんがGitワークフローを適切に定義できるようになることを主たる目的としています。 また、筆者の能力不足によって記載しきれなかった考慮事項について、より深く Git を使いこなしている識者からの指摘を受ける機会を得ることを副次的な目的とします。 この記事には書かれていないものの、検討すべき事項について知見のある方はブログ記事を書いたり、 Twitter 等の SNS で指摘してくださるとありがたいです。 はじめに 基本的な考え方 Git ワークフロー設計における考慮事項 チームの人数 monorepoの検討 参考文献 プロジェクト管理ツールとの連携 Pull Request ブランチ名 頻出する定型業務の自動化(CI/CD サービスとの統合) ビルド 静的解析 ソースコードの自動生成 単体テスト 結合テスト ドキュメントの自動生成 パッケージング 依存ライブラリのアップデート システムテスト アプリケーション運用との統合 Git ワークフローの実際 シングルブランチモデル 参考文献 GitHub Flow 参考文献 GitLab Flow 参考文献 Gitflow (A successful Git branching model) 参考文献 まとめ はじめに この記事は、Git や GitHub の基本的な使い方を読者が理解していることを前提に書いています。 つまり、Git サーバとしての GitHub だけでなく、その機能を十分に使うことを想定しています。 もし基本的な使い方に不安があるなら、まずは以下のサイトや書籍で学習してください。 Git でのバージョン コントロールの概要 半日程度でgitについて把握できる Microsoft の教育コンテンツです。 サル先生の Git 入門 Git の初歩の初歩を図解しながら学習できるサイトです 改訂 2 版 わかばちゃんと学ぶ Git 使い方入門 漫画で Git を学習するならこの本がおすすめです 新しい領域として Git を学ぶならとっつき易さで選ぶのがいいと個人的には考えています いちばんやさしい Git&GitHub の教本 人気講師が教えるバージョン管理&共有入門 Git と GitHub をまとめて学習するならこの本がおすすめです 基本的な考え方 Gitのワークフローを決めるのは仕事の質を上げるためです。失敗の可能性を低減し、また失敗したとしても労せずやり直せることで効率よく働けるようにしましょう。 Gitのワークフローを検討する際、常に意識してほしいのは 作りこみ過ぎない ということです。 まず、起きてもいない問題のすべてを事前に対応しようとしないでください。また、プロジェクトメンバーがワークフローの習熟に使う時間をできるかぎり減らしましょう。 プロジェクトメンバーが複雑すぎるワークフローに振り回されると仕事の生産性は確実に低減し、その結果として仕事の質が落ちていきます。 Gitのワークフローは自分のプロジェクトにおいて問題が起きてもやり直せるギリギリまで軽量化しましょう。 Git ワークフロー設計における考慮事項 この記事の主題となるGitワークフロー設計における考慮事項を説明します。 ここでは、Gitを中心にした仕事のやり方全体を指してGit ワークフローと呼んでいます。 少し抽象的な話が続きますので、Gitワークフローについて考えたことがないなら、記事の後半にある Git ワークフローの実際を読んでから戻ってくると少しわかり易くなるかもしれません。 チームの人数 仕事のやり方を考えるのですから、まずチームがどのようなメンバーで構成されているのか検討しましょう。 例えば、2,3人のチームでは労せずお互いのやっていることを正確に把握できるので、複雑なワークフローは必要ありません。ミスはするものとしてお互い補いあう想定で働くと効率がいいです。 こういった少人数であれば、最低限の ケアレスミス を防ぐためだけにワークフローを定義しましょう。 メンバーが10人を超えたあたりで、お互いの仕事内容を正確に把握しあうのは難しくなります。 これくらいの人数から、Gitワークフローを検討する上でメンバーの入れ替わり頻度について考慮しましょう。 数年間固定されていて気心の知れたメンバー10人と、この3か月で集まった10人では採用すべきワークフローに多少の違いはでるでしょう。 メンバーが固定されているチームでは少人数のチームと同じようなGitワークフローで十分です。変に手順を難しくするのはやめましょう。 メンバーが流動的なチームでは作業記録を残しやすい形でワークフローを定義すると、問題が発生した際に対処し易くなります。 メンバーが30人を超えると大抵のプロジェクトでお互いの仕事内容を正確に把握しあうのは不可能です。 チームを2つか3つに分割した上で役割と責任範囲を明確にした作業分担が必要になるでしょう。 メンバーは流動的で少なくとも四半期に一回程度は誰かが抜けて、誰かが増えます。 つまり、ワークフローに習熟していないメンバーがいつでも一定数存在することを前提にワークフロー操作が失敗しても他のチームにその影響が派生しないことを重視しましょう。 こういう状況ではチーム同士の成果を結合するワークフローはどうしても複雑なものになりがちです。 monorepoの検討 Gitでは小さい単位の開発成果物ごとに リポジトリ を作る方が大抵の場合うまくいきます。 例えば、サーバアプリケーションとクライアントアプリケーション、デプロイ スクリプト 、マニュアル類、設計ドキュメントなどをそれぞれを別な リポジトリ として管理するとよいでしょう。 成果物の種類毎に リポジトリ が分かれていれば、それらを更新するメンバーの役割と責任範囲が自然と明確で分かり易くなります。 例えば、クライアントアプリケーションの開発メンバーには、サーバアプリケーションの リポジトリ に対して読み取り専用の権限を付与することを考えてみましょう。まず、コードの読むことはできるので問題発生時に分析はできます。 一方で、クライアントアプリケーションの修正のつもりでサーバアプリケーションに修正を加えてしまうといったミスは発生しなくなります。 一方で、 リポジトリ が分かれていると問題になるケースもあります。 考えてみてください。.protoや JSON Schemaのように、サーバアプリケーションとクライアントアプリケーションが通信するための プロトコル を定義するIDLは、どちらの リポジトリ に置くのがいいでしょうか?それとも、 通信プロトコル の定義は設計ドキュメントとセットで新しい リポジトリ を作るべきでしょうか?また、クライアントアプリケーションとしてモバイルアプリケーションを実装することにしました、 Android と iOS では リポジトリ を分けるべきでしょうか? このように何かあるたびに リポジトリ を増やしていくと、 リポジトリ の増加は止まりません。 リポジトリ が増えると手元の開発環境を適切な状態に維持するための手順は煩雑になります。また、CIやCDなどのビルドプロセスも複雑になります。 これに対して、開発成果物を全て単一の リポジトリ 内に収めてしまうのがmonorepoです。 単一の リポジトリ 内にあらゆる成果物を入れて管理すれば、メンバーの新規追加時における難しさは大きく低減します。 monorepoを採用することによって、まず新しいメンバーが既存の成果物を探し回るために必要なコストが低減します。 そして、ドキュメントや ソースコード の間で 相対パス を使ったリンクを張れます。種類の成果物同士で情報の連携が取り易いことは、仕様に対する理解の速度を早めます。 Google のように依存ライブラリも含めて全てmonorepoに入れてしまうような組織もあります。 対応を検討すべきデメリットはいくつかあります。 ファイル数やコミット数が多くなるので、単純に リポジトリ が大きくなる GitHub の リポジトリ は5GB程度に収めるよう推奨されている Repository size limits cloneやfetchに時間がかかり易くなる 対応策は、 パーシャルクローンとシャロークローンを活用しよう タグの対象範囲が分かりづらくなり易い タグの 命名規則 をしっかり考える必要がある メンバーが編集できる成果物の範囲を限定するのが難しい GitHub にはCODEOWNERSという仕組みで ディレクト リ単位やファイル単位の必須レビュアーを設定できる コードオーナーについて 参考文献 Git で monorepo を扱う際の課題とヒント Why Google Stores Billions of Lines of Code in a Single Repository monorepo.tools プロジェクト管理ツールとの連携 ソフトウェア開発をするためにGitを使うのですから、プロジェクト管理ツールとGitワークフローは密接に関連します。 GitHub にはタスク管理機能が備わっていますが、ある一定以上の規模で利用しようとするには機能不足です。 ボトムアップ な管理をするにも、例えばタスクの分割と集約の機能がなかったり、チケットの検索クエリが貧弱だったりします。 トップダウン な管理という意味では、例えばタスクの進捗状況を俯瞰するのは非常に難しいですし、承認フローを構築したり WBS を引いたりといったことも出来ません。 ステークホルダー となる組織が複数あり、プロジェクトとの関係性において一定の複雑さがあるならプロジェクト管理ツールを導入すべきです。 理想的には、ソフトウェア開発系のタスクとそれ以外のタスクにおける情報連携を自動的に実施するのが望ましいでしょう。つまり、プロジェクト管理ツールに定義したワークフローとGitを使ったワークフローを上手く連携させるのが望ましいというわけです。 基本的にはプロジェクト管理ツール側に GitHub 上のPull Requestやブランチの情報を取込んでいく形になります。 例えば、広く使われているプロジェクト管理ツールであるJiraには スマートコミット という仕組みがあり、コミットメッセージを所定の書式で記述するとJiraのIssueが持つ状態を操作できます。 プロジェクト管理ツール側がWebhookに対応しているならPull Requestから情報を送信できます。 また、 GitHub Actions を使うならPull Requestでなくても情報をプロジェクト管理ツールに送信できます。 Pull Request Gitはそれぞれの開発者が持っている リポジトリ は完全に独立しており対等なものです。 SVN や CVS といった構成管理ツールを使う場合、開発者のローカルにチェックアウトされた成果物は作業用のコピーであることとは対照的です。 一方で、内部統制がしっかりと効いた開発を行うなら、プロジェクトの進捗と厳密に同期していると言える リポジトリ を一つ決めます。 その中心となる リポジトリ を GitHub 上に置くと使える仕組みがPull Request(PR)です。他のツールではMerge Requestと呼ばれることもあります。 PRを使うと、コードレビューとそれにひもづく定型作業の自動化(CI)をサーバ上で実行できます。 GitHub を使うプロジェクトでは、Gitワークフローを設計するならPRをどうやって使うかが議論の中心になるでしょう。 もしPRを使うのであれば、Issue Templateを用意するとPR自体の質を底上げできます。 About issue and pull request templates ブランチ名 Gitを利用する際にブランチ名を工夫すると、CIで作業を自動化し易くなります。 ワークフローの設計次第ではもう少しルールを追加しますが、基本的にはこれだけです。 作業内容を想像し易い単語をブランチ名に含める ブランチ名は基本的に半角英数だけを使う 意味の区切りは / を使う 区切り文字として / を使うのは、GitKrakenを始めとした GUI クライアントが / 区切りでブランチを階層表示してくれるからです。 この画像では dev/my-task 、 dev/your-task に加えて折りたたまれた test/awesome ブランチがあります。 頻出する定型業務の自動化(CI/CD サービスとの統合) Gitのワークフローを作りこむ理由は、定型業務を自動化してより効率よく働くためです。 どんな作業をCIの中に組込みたいのかをしっかりと検討することはワークフロー設計をする上で大切です。 ここでは、参考のためにCIへ組み込むと便利な定型業務を列挙しますが、最初から全てに取り組もうとしないでください。 ご自分のプロジェクトにおいて明らかに恩恵があると思われるものを少量取り入れるのがおすすめです。 PRに伴って動作するCIワークフローのパフォーマンスが悪いと開発効率は確実に低減しますので、あれもこれもと盛り込み過ぎないようにしましょう。 また、筆者が知らなかったり、列挙できなかった定型業務は非常に多岐にわたることが予想されます。 読者の皆さんがご自分のプロジェクトで定型化している業務を SNS やブログで共有して下さることを期待しています。 ビルド CIに組み込む作業として一番最初に思い浮かぶのがビルドです。 ここでいうビルドは、 ソースコード から実行可能な状態に変換する過程で発生する定型的な業務全般を指しています。 静的解析 コンパイル 型の プログラミング言語 なら コンパイラ がある程度の静的解析に基づくエラーを出力してくれます。 大抵の プログラミング言語 には、Lintと呼ばれるタイプの ソースコード の妥当性を検証するツールがあります。 特に筆者が好きなのは、ベストプ ラク ティスに基づいたコードへ矯正するタイプの静的解析ツールです。 使うことが明確に非推奨というわけではないけども、新しいコードではそのような書き方をしない方がよいという知識を複数の プログラミング言語 にわたって学習し続けるのは非常に難しいです。 例えば、ReactのuseEffectに [] を指定すべきケースは限定的で基本的に何か値を設定したほうがいいとか。 goは1.13でerrorの望ましい書き方が変わったとか。 アプリケーションとしては動作する以上、望ましくないスタイルのコードを書いていても気が付きませんよね。しかし、望ましくないスタイルのコードはソフトウェアの品質を確実に低減させます。 こういったことを学習するきっかけをえるためにLintツールはPRからトリガーされるタスクに組み込むのが望ましいでしょう。 ソースコード の自動生成 ソースコード の自動生成は、それを実施すべきかどうかを判断するのが難しいタスクです。 ジェネリック スやテンプレートなど言語の機能を利用することで、継続的な ソースコード の自動生成は不要にできる場合もあります。 また、自動生成した ソースコード をGitのような構成管理ツールにチェックインするかどうかも注意深く検討してください。 自動生成した ソースコード をチェックインする場合には、 リポジトリ のサイズが大きくなり易い代わりに、CIの実行時間を抑えられます。 一方で、自動生成した ソースコード をチェックインしない場合には、 リポジトリ のサイズを小さく保てる代わりにCIの実行時間が長くなります。 筆者としては、 ソースコード の自動生成は開発者のローカルマシンで実行しPRを出して リポジトリ にチェックインする方式を好んで使っています。それは、基本的には望ましくないことだと分かっていても、生成物に対して手を入れたいという要求を完全に消すことはできないからです。 単体テスト データベースや アプリケーションサーバ を使わない 単体テスト は、PRからトリガーされるタスクとして実行したいタスクです。開発者が実施するテストのあり方を学びたい人には 和田さんのスライド をおすすめしておきます。 QuickCheckのようなパラメタライズドテストや、コード カバレッジ の計測は実行コストが高いのでそれほど頻繁に行わなくてもいいかもしれません。そういう高コストなテストは、Gitワークフローからは切り離して夜中や早朝に定期実行するようなアプローチをおすすめします。 結合テスト ここではデータベースや アプリケーションサーバ 、リバースプロキシなどを構成した上で実施するテストを 結合テスト とします。 テストに時間がかかりすぎるとか、テストが終わらなくて タイムアウト するとか言った問題はスローテスト問題と呼ばれています。 長期間にわたって価値を生み出すソフトウェアを実装していくにあたって、スローテスト問題は避けられません。 スローテスト問題に対する基本的なアプローチは、品質を担保できるギリギリの頻度で実行し、テストの実行コストと品質の トレードオフ における妥当な割合を見つけることです。 機械学習 によってテストの実行対象を賢く選択してくれる Launchable は、この問題に対する画期的な解決策を提供してくれるかもしれないと期待しています。 筆者の個人的な好みは、 ナイトリー ビルドのような形で一日に数回は 結合テスト を実行するものの、日常的なPRトリガーのワークフローからは外すことです。 ドキュメントの自動生成 Javadoc のようなドキュメントコメントから開発者向けドキュメントを自動生成するタスクもまたビルドタスクの一部としてよく組込みます。 フレームワーク やライブラリのように繰り返し再利用されるものを実装する際にはドキュメントコメントをしっかり書くのが望ましいでしょう。一方で、アプリケーションコードのドキュメントコメントは必要最小限に留めておくのがおすすめです。 筆者の経験上、コメント部分は動作しないためかコードと整合性をもってメンテナンスされづらく、その結果コメントとコードの内容にズレがおきることでコードを理解する妨げになる事の方が多いからです。 ドキュメントの自動生成は多くても一日に一回程度、大抵の場合は一週間に一回くらいの頻度で実施すれば事足りるので、PRから実行されるCIタスクには組み込まないことが多いです。 代わりに、クーロンジョブのような形で定期的に実行してPRを自動生成する方が低コストです。 今の GitHub Pagesにはアクセス制御機能があり、許可された開発者だけが閲覧できるサイトを簡単に構築できることは知っておいてください。 Changing the visibility of your GitHub Pages site パッケージング パッケージングは、Dockerコンテナイメージや、jarのような形式で アーカイブ されたファイルを作ることです。 単に アーカイブ すればいいものから署名が必要なものまで、言語やデプロイ先によって実行すべきタスクは様々です。 ただ、大きな傾向としてパッケージングはリリース作業の一部として実行するタスクです。 パッケージングとして実施すべきタスクの内容は極めて複雑で多岐にわたるため、今回はそういうものがあるとだけ言っておきます。 依存ライブラリのアップデート 現代的なソフトウェア開発において オープンソース ソフトウェア( OSS )の利用は避けられません。 そして、 OSS のライブラリは高頻度にアップデートされます。特に緊急性の高いセキュリティパッチと呼ばれるようなアップデートは実施しなければなりません。 とはいえ、定期的な依存ライブラリのアップデートを手動でやっていると時間がどれだけあっても不足します。つまり、自動化するしかありません。そのためには、比較的高品質な 回帰テスト が必要になります。 依存ライブラリのアップデートを自動的にやってくれるサービスとしては、 Renovate や、 GitHub に標準で組み込まれている Dependabot を使うのが良いでしょう。これらのサービスを利用するとライブラリをアップデートするPRを自動的に作ってくれます。 自動的に作られるPRをGitワークフローの中でどういう位置づけにするのかは、丁寧に検討してください。深く考えずに導入すると、無限に生成されるPRに押しつぶされてしまいますよ。 これは、筆者がメンテナンスしている社内ツールの 回帰テスト が不安定なせいで自動マージが上手く動作せず蓄積してしまったPRの山です。 システムテスト Gitのワークフローを検討する上で、 システムテスト の位置づけは整理するのが望ましいでしょう。 まずは、ワークフローの一部に システムテスト を組み込むのかどうかを検討してください。 システムテスト の自動化は極めて深遠な話題ですので、大抵のプロジェクトでは組み込まないという結論になるでしょう。 ソフトウェアが価値を生み長生きするならば、規模は大きくなり複雑になっていきます。 その中で システムテスト の自動化は取り組むべき課題の一つです。 Gitワークフローの一部として システムテスト を実行すべき状況になっていないかを、ときどき気にかけてください。 アプリケーション運用との統合 Gitワークフローとアプリケーション運用の統合については、パッケージングの話題でありデプロイの話題です。 少なくとも、ワークフローの終了ステータスをどのような形で、いつ誰に通知するのかは検討してください。 伝統的にはショートメッセージサービス(SMS)や電子メールを使っていますよね。 現代的にはSlackやTeams、LINEなどチャットツールへのメッセージ送信となるでしょう。 また、アプリケーション運用側からGitに対する情報提供をどのように実施するのかを検討するのも忘れないでください。 基本的にはプロジェクト管理ツールに対するタスクの起票( GitHub Issuesなど)を介して行うことになるはずです。 Git ワークフローの実際 ここからは、ワークフロー設計の参考になるようなGitワークフローをいくつか紹介します。 ただし、具体的な作業手順については説明していません。参考文献に詳細な説明のあるページをリンクしておきましたので参考にしてください。 ここで紹介しているものは、あくまでも基本的な型であって、これをそのまま導入すべきものではありません。 とはいえ、一定の複雑さがあるワークフローを導入する際、最初のうちは基本的な型のまま何も変えずに導入することがGitワークフローのあり方をチームとして理解する助けになるでしょう。 この説明では、デフォルトのブランチをmainブランチと記載しています。 以前は、 GitHub におけるデフォルトのブランチ名はmasterでしたが、世相を反映して現在はmainをデフォルトのブランチ名とすることが推奨されています。 GitHub、これから作成するリポジトリのデフォルトブランチ名が「main」に。「master」から「main」へ変更 シングルブランチモデル シングルブランチモデルは、開発者はサーバの リポジトリ をcloneしたらmainブランチに変更作業をコミットしていき、作業が終わり次第mainブランチをサーバにpushする方式です。 これは、 SVN からGitへ ソースコード 管理ツールを移行するチームが一時的に使う方式として検討する余地があります。 単に SVN をGitで代替し、基本的なコマンドの使い方や動作を理解する期間を設けることでツールの移行に伴う生産性の低下を緩やかにできます。 一方でシングルブランチモデルはソフトウェアの設計や、作業分担次第ではあるものの非常にコンフリクトが発生し易い使い方です。 push前に必ずrebaseしてローカル ディレクト リ内でコンフリクトを解決する。もしくは、同じファイルを同時に複数の人が修正しないよう作業範囲を調整しなければなりません。 つまり、この方式を採用してプロジェクト運営を行うならプロジェクトマネージャーが、仕様の変更や追加に伴うファイルの変更範囲を厳密に理解している必要があります。 チームが2,3人で担当範囲が明確なら、この方式でGitを使い始めるのがいいでしょう。 コンフリクトさえ発生しなければ、覚えなければならないGit固有の知識が最小限で済みます。 参考文献 Centralized Workflow トランクベース開発 GitHub Flow GitHub Flowでは、サーバの リポジトリ をcloneしたらmainブランチから作業用のフィーチャブランチへswitchします。 フィーチャブランチでの作業が終わったら、それをサーバにpushしPRを使ってmainブランチにマージします。 この方式では、gitの3-way mergeが上手く働くのでシングルブランチモデルよりも断然コンフリクトが発生し辛くなります。 原義的な GitHub Flowではmainブランチにマージされた変更は本番環境を含む何らかの実行環境にデプロイすることが重要なのですが、そこまでやらなくても十分に利便性を享受できます。 参考文献 GitHub Flow 翻訳 GitHub公式 GitLab Flow ブランチの管理とデプロイをより丁寧に対応付ける形のワークフローがGitLab Flowです。 開発者がPRを使ってmainブランチに変更をマージしていくことは GitHub Flowと同じです。 GitLab Flowでは、デプロイ作業を実施するブランチを専用に設けることで、開発におけるPRのマージとデプロイの周期やタイミングを分離します。 mainブランチにマージされたアプリケーションがテスト環境にデプロイされ、そこで問題が見つからなければ本番環境にデプロイされるというようなワークフローを想定すると、このような形になるでしょう。 大規模な開発では、テスト環境が複数用意されているものです。 テストの目的や、担当者の責任範囲によって環境が分離されているようなら環境に対応したブランチを用意した上で、それらのブランチへのマージをトリガーにデプロイを実行するでしょう。 パッケージソフト ウェアのビジネスでは、リリース済みで新機能の追加がないとしても、セキュリティの問題や深刻なバグへの対応を実施するためパッチを適用して保守していくことが望まれます。 このような状況にGitLab Flowの考え方を適用すると、それぞれのリリースに応じてブランチを作り、mainブランチから必要な変更だけを取り出してマージしていく(チェリーピック)ことになります。 このバージョンブランチを伸ばしていく保守方針は変更コストが高くなり易いので、なるべく選ばない方がいいでしょう。 しかし、これはソフトウェアの収益モデルと直接関連するので、ビジネスオーナーと開発者が丁寧な議論を実施すべき話題です。 参考文献 GitLab Flow GitLab flowから学ぶワークフローの実践 Gitflow (A successful Git branching model) Gitflowはここまで説明してきたワークフローの集大成となるものです。 開発者は、サーバの リポジトリ をcloneしたらdevlopブランチから作業用のフィーチャブランチへswitchします。 フィーチャブランチでの作業が終わったら、それをサーバにpushしPRを使ってdevelopブランチにマージします。 必要な変更作業が終わったら、リリースの担当者がdevelopブランチから新しいreleaseブランチをswitchし、アプリケーションのリリースに伴う作業を実施した成果をコミットします。ここでコミットされるものは、例えば、軽微な作業ミスの修正やバグの対応、ドキュメントの修正などです。 そういった作業が全て終了したら、releaseブランチをサーバにpushしPRを使ってmainブランチにマージしてタグを打ちます。 そうです、Gitflowにおけるmainブランチはアプリケーションの静止点を記録するためだけのブランチなのです。 ただし、緊急対応を行うホットフィックスブランチだけは例外です。 緊急対応を行う開発者は、mainブランチから作業用のホットフィックスブランチへswitchします。 作業が終わったらホットフィックスブランチをサーバにpushしPRを使ってdevelopブランチとmainブランチの両方へマージします。 その上で、mainブランチにタグを打ちアプリケーションをリリースします。 Gitflowでは非常に複雑な状況が想定されています。またそれぞれの開発者がGitに対してかなり習熟していることが前提のワークフローです。 中身を詳細に理解した上で、全ての要素が必要であると判断できるなら、リリースまでの作業を何度か実施してみてください。それでもなおプロジェクトの運営方針と合致していると確信できる場合のみGitflowを採用してください。 参考文献 A successful Git branching model 翻訳 まとめ 筆者は、Gitワークフローの設計で最も重要なのは 作りこみ過ぎない ことだと考えています。 そのために、Gitワークフローにおける検討事項を適切に把握しましょう。 みなさんのプロジェクトにおいて対応すべき課題を丁寧に把握した上でプロジェクトメンバーの生産性を最大限に発揮できるワークフローを設計してください。 具体的にどのワークフローを使えばいいか分からないなら、まずは GitHub Flowを試してみてください。 GitHub Actionsを使って簡単なビルドを行いつつ、コードレビューをするとGitを使うことの利便性を享受できます。 この記事によって、読者の皆さんがご自分のチーム内におけるGitワークフローを改善するきっかけになれば、これ以上に嬉しいことはありません。 非常に長いエントリでしたが、最後までお読みいただきありがとうございます。 執筆: @sato.taichi 、レビュー: @yamashita.tsuyoshi ( Shodo で執筆されました )
みなさんこんにちは、 電通国際情報サービス (ISID)X イノベーション 本部ソフトウェアデザインセンターの佐藤太一です。 この記事では、Git を使った仕事のやり方(以降は Git ワークフローと記載)を設計する上での検討事項を説明します。 これによって、読者の皆さんがGitワークフローを適切に定義できるようになることを主たる目的としています。 また、筆者の能力不足によって記載しきれなかった考慮事項について、より深く Git を使いこなしている識者からの指摘を受ける機会を得ることを副次的な目的とします。 この記事には書かれていないものの、検討すべき事項について知見のある方はブログ記事を書いたり、 Twitter 等の SNS で指摘してくださるとありがたいです。 はじめに 基本的な考え方 Git ワークフロー設計における考慮事項 チームの人数 monorepoの検討 参考文献 プロジェクト管理ツールとの連携 Pull Request ブランチ名 頻出する定型業務の自動化(CI/CD サービスとの統合) ビルド 静的解析 ソースコードの自動生成 単体テスト 結合テスト ドキュメントの自動生成 パッケージング 依存ライブラリのアップデート システムテスト アプリケーション運用との統合 Git ワークフローの実際 シングルブランチモデル 参考文献 GitHub Flow 参考文献 GitLab Flow 参考文献 Gitflow (A successful Git branching model) 参考文献 まとめ はじめに この記事は、Git や GitHub の基本的な使い方を読者が理解していることを前提に書いています。 つまり、Git サーバとしての GitHub だけでなく、その機能を十分に使うことを想定しています。 もし基本的な使い方に不安があるなら、まずは以下のサイトや書籍で学習してください。 Git 入門 30分程度でgitについて把握できる Microsoft の教育コンテンツです。 サル先生の Git 入門 Git の初歩の初歩を図解しながら学習できるサイトです 改訂 2 版 わかばちゃんと学ぶ Git 使い方入門 漫画で Git を学習するならこの本がおすすめです 新しい領域として Git を学ぶならとっつき易さで選ぶのがいいと個人的には考えています いちばんやさしいGit&GitHubの教本 第3版 人気講師が教えるバージョン管理&共有入門 Git と GitHub をまとめて学習するならこの本がおすすめです 基本的な考え方 Gitのワークフローを決めるのは仕事の質を上げるためです。失敗の可能性を低減し、また失敗したとしても労せずやり直せることで効率よく働けるようにしましょう。 Gitのワークフローを検討する際、常に意識してほしいのは 作りこみ過ぎない ということです。 まず、起きてもいない問題のすべてを事前に対応しようとしないでください。また、プロジェクトメンバーがワークフローの習熟に使う時間をできるかぎり減らしましょう。 プロジェクトメンバーが複雑すぎるワークフローに振り回されると仕事の生産性は確実に低減し、その結果として仕事の質が落ちていきます。 Gitのワークフローは自分のプロジェクトにおいて問題が起きてもやり直せるギリギリまで軽量化しましょう。 Git ワークフロー設計における考慮事項 この記事の主題となるGitワークフロー設計における考慮事項を説明します。 ここでは、Gitを中心にした仕事のやり方全体を指してGit ワークフローと呼んでいます。 少し抽象的な話が続きますので、Gitワークフローについて考えたことがないなら、記事の後半にある Git ワークフローの実際を読んでから戻ってくると少しわかり易くなるかもしれません。 チームの人数 仕事のやり方を考えるのですから、まずチームがどのようなメンバーで構成されているのか検討しましょう。 例えば、2,3人のチームでは労せずお互いのやっていることを正確に把握できるので、複雑なワークフローは必要ありません。ミスはするものとしてお互い補いあう想定で働くと効率がいいです。 こういった少人数であれば、最低限の ケアレスミス を防ぐためだけにワークフローを定義しましょう。 メンバーが10人を超えたあたりで、お互いの仕事内容を正確に把握しあうのは難しくなります。 これくらいの人数から、Gitワークフローを検討する上でメンバーの入れ替わり頻度について考慮しましょう。 数年間固定されていて気心の知れたメンバー10人と、この3か月で集まった10人では採用すべきワークフローに多少の違いはでるでしょう。 メンバーが固定されているチームでは少人数のチームと同じようなGitワークフローで十分です。変に手順を難しくするのはやめましょう。 メンバーが流動的なチームでは作業記録を残しやすい形でワークフローを定義すると、問題が発生した際に対処し易くなります。 メンバーが30人を超えると大抵のプロジェクトでお互いの仕事内容を正確に把握しあうのは不可能です。 チームを2つか3つに分割した上で役割と責任範囲を明確にした作業分担が必要になるでしょう。 メンバーは流動的で少なくとも四半期に一回程度は誰かが抜けて、誰かが増えます。 つまり、ワークフローに習熟していないメンバーがいつでも一定数存在することを前提にワークフロー操作が失敗しても他のチームにその影響が派生しないことを重視しましょう。 こういう状況ではチーム同士の成果を結合するワークフローはどうしても複雑なものになりがちです。 monorepoの検討 Gitでは小さい単位の開発成果物ごとに リポジトリ を作る方が大抵の場合うまくいきます。 例えば、サーバアプリケーションとクライアントアプリケーション、デプロイ スクリプト 、マニュアル類、設計ドキュメントなどをそれぞれを別な リポジトリ として管理するとよいでしょう。 成果物の種類毎に リポジトリ が分かれていれば、それらを更新するメンバーの役割と責任範囲が自然と明確で分かり易くなります。 例えば、クライアントアプリケーションの開発メンバーには、サーバアプリケーションの リポジトリ に対して読み取り専用の権限を付与することを考えてみましょう。まず、コードの読むことはできるので問題発生時に分析はできます。 一方で、クライアントアプリケーションの修正のつもりでサーバアプリケーションに修正を加えてしまうといったミスは発生しなくなります。 一方で、 リポジトリ が分かれていると問題になるケースもあります。 考えてみてください。.protoや JSON Schemaのように、サーバアプリケーションとクライアントアプリケーションが通信するための プロトコル を定義するIDLは、どちらの リポジトリ に置くのがいいでしょうか?それとも、 通信プロトコル の定義は設計ドキュメントとセットで新しい リポジトリ を作るべきでしょうか?また、クライアントアプリケーションとしてモバイルアプリケーションを実装することにしました、 Android と iOS では リポジトリ を分けるべきでしょうか? このように何かあるたびに リポジトリ を増やしていくと、 リポジトリ の増加は止まりません。 リポジトリ が増えると手元の開発環境を適切な状態に維持するための手順は煩雑になります。また、CIやCDなどのビルドプロセスも複雑になります。 これに対して、開発成果物を全て単一の リポジトリ 内に収めてしまうのがmonorepoです。 単一の リポジトリ 内にあらゆる成果物を入れて管理すれば、メンバーの新規追加時における難しさは大きく低減します。 monorepoを採用することによって、まず新しいメンバーが既存の成果物を探し回るために必要なコストが低減します。 そして、ドキュメントや ソースコード の間で 相対パス を使ったリンクを張れます。種類の成果物同士で情報の連携が取り易いことは、仕様に対する理解の速度を早めます。 Google のように依存ライブラリも含めて全てmonorepoに入れてしまうような組織もあります。 対応を検討すべきデメリットはいくつかあります。 ファイル数やコミット数が多くなるので、単純に リポジトリ が大きくなる GitHub の リポジトリ は5GB程度に収めるよう推奨されている Repository size limits cloneやfetchに時間がかかり易くなる 対応策は、 パーシャルクローンとシャロークローンを活用しよう タグの対象範囲が分かりづらくなり易い タグの 命名規則 をしっかり考える必要がある メンバーが編集できる成果物の範囲を限定するのが難しい GitHub にはCODEOWNERSという仕組みで ディレクト リ単位やファイル単位の必須レビュアーを設定できる コードオーナーについて 参考文献 Git で monorepo を扱う際の課題とヒント Why Google Stores Billions of Lines of Code in a Single Repository monorepo.tools プロジェクト管理ツールとの連携 ソフトウェア開発をするためにGitを使うのですから、プロジェクト管理ツールとGitワークフローは密接に関連します。 GitHub にはタスク管理機能が備わっていますが、ある一定以上の規模で利用しようとするには機能不足です。 ボトムアップ な管理をするにも、例えばタスクの分割と集約の機能がなかったり、チケットの検索クエリが貧弱だったりします。 トップダウン な管理という意味では、例えばタスクの進捗状況を俯瞰するのは非常に難しいですし、承認フローを構築したり WBS を引いたりといったことも出来ません。 ステークホルダー となる組織が複数あり、プロジェクトとの関係性において一定の複雑さがあるならプロジェクト管理ツールを導入すべきです。 理想的には、ソフトウェア開発系のタスクとそれ以外のタスクにおける情報連携を自動的に実施するのが望ましいでしょう。つまり、プロジェクト管理ツールに定義したワークフローとGitを使ったワークフローを上手く連携させるのが望ましいというわけです。 基本的にはプロジェクト管理ツール側に GitHub 上のPull Requestやブランチの情報を取込んでいく形になります。 例えば、広く使われているプロジェクト管理ツールであるJiraには スマートコミット という仕組みがあり、コミットメッセージを所定の書式で記述するとJiraのIssueが持つ状態を操作できます。 プロジェクト管理ツール側がWebhookに対応しているならPull Requestから情報を送信できます。 また、 GitHub Actions を使うならPull Requestでなくても情報をプロジェクト管理ツールに送信できます。 Pull Request Gitはそれぞれの開発者が持っている リポジトリ は完全に独立しており対等なものです。 SVN や CVS といった構成管理ツールを使う場合、開発者のローカルにチェックアウトされた成果物は作業用のコピーであることとは対照的です。 一方で、内部統制がしっかりと効いた開発を行うなら、プロジェクトの進捗と厳密に同期していると言える リポジトリ を一つ決めます。 その中心となる リポジトリ を GitHub 上に置くと使える仕組みがPull Request(PR)です。他のツールではMerge Requestと呼ばれることもあります。 PRを使うと、コードレビューとそれにひもづく定型作業の自動化(CI)をサーバ上で実行できます。 GitHub を使うプロジェクトでは、Gitワークフローを設計するならPRをどうやって使うかが議論の中心になるでしょう。 もしPRを使うのであれば、Issue Templateを用意するとPR自体の質を底上げできます。 About issue and pull request templates ブランチ名 Gitを利用する際にブランチ名を工夫すると、CIで作業を自動化し易くなります。 ワークフローの設計次第ではもう少しルールを追加しますが、基本的にはこれだけです。 作業内容を想像し易い単語をブランチ名に含める ブランチ名は基本的に半角英数だけを使う 意味の区切りは / を使う 区切り文字として / を使うのは、GitKrakenを始めとした GUI クライアントが / 区切りでブランチを階層表示してくれるからです。 この画像では dev/my-task 、 dev/your-task に加えて折りたたまれた test/awesome ブランチがあります。 頻出する定型業務の自動化(CI/CD サービスとの統合) Gitのワークフローを作りこむ理由は、定型業務を自動化してより効率よく働くためです。 どんな作業をCIの中に組込みたいのかをしっかりと検討することはワークフロー設計をする上で大切です。 ここでは、参考のためにCIへ組み込むと便利な定型業務を列挙しますが、最初から全てに取り組もうとしないでください。 ご自分のプロジェクトにおいて明らかに恩恵があると思われるものを少量取り入れるのがおすすめです。 PRに伴って動作するCIワークフローのパフォーマンスが悪いと開発効率は確実に低減しますので、あれもこれもと盛り込み過ぎないようにしましょう。 また、筆者が知らなかったり、列挙できなかった定型業務は非常に多岐にわたることが予想されます。 読者の皆さんがご自分のプロジェクトで定型化している業務を SNS やブログで共有して下さることを期待しています。 ビルド CIに組み込む作業として一番最初に思い浮かぶのがビルドです。 ここでいうビルドは、 ソースコード から実行可能な状態に変換する過程で発生する定型的な業務全般を指しています。 静的解析 コンパイル 型の プログラミング言語 なら コンパイラ がある程度の静的解析に基づくエラーを出力してくれます。 大抵の プログラミング言語 には、Lintと呼ばれるタイプの ソースコード の妥当性を検証するツールがあります。 特に筆者が好きなのは、ベストプ ラク ティスに基づいたコードへ矯正するタイプの静的解析ツールです。 使うことが明確に非推奨というわけではないけども、新しいコードではそのような書き方をしない方がよいという知識を複数の プログラミング言語 にわたって学習し続けるのは非常に難しいです。 例えば、ReactのuseEffectに [] を指定すべきケースは限定的で基本的に何か値を設定したほうがいいとか。 goは1.13でerrorの望ましい書き方が変わったとか。 アプリケーションとしては動作する以上、望ましくないスタイルのコードを書いていても気が付きませんよね。しかし、望ましくないスタイルのコードはソフトウェアの品質を確実に低減させます。 こういったことを学習するきっかけをえるためにLintツールはPRからトリガーされるタスクに組み込むのが望ましいでしょう。 ソースコード の自動生成 ソースコード の自動生成は、それを実施すべきかどうかを判断するのが難しいタスクです。 ジェネリック スやテンプレートなど言語の機能を利用することで、継続的な ソースコード の自動生成は不要にできる場合もあります。 また、自動生成した ソースコード をGitのような構成管理ツールにチェックインするかどうかも注意深く検討してください。 自動生成した ソースコード をチェックインする場合には、 リポジトリ のサイズが大きくなり易い代わりに、CIの実行時間を抑えられます。 一方で、自動生成した ソースコード をチェックインしない場合には、 リポジトリ のサイズを小さく保てる代わりにCIの実行時間が長くなります。 筆者としては、 ソースコード の自動生成は開発者のローカルマシンで実行しPRを出して リポジトリ にチェックインする方式を好んで使っています。それは、基本的には望ましくないことだと分かっていても、生成物に対して手を入れたいという要求を完全に消すことはできないからです。 単体テスト データベースや アプリケーションサーバ を使わない 単体テスト は、PRからトリガーされるタスクとして実行したいタスクです。開発者が実施するテストのあり方を学びたい人には 和田さんのスライド をおすすめしておきます。 QuickCheckのようなパラメタライズドテストや、コード カバレッジ の計測は実行コストが高いのでそれほど頻繁に行わなくてもいいかもしれません。そういう高コストなテストは、Gitワークフローからは切り離して夜中や早朝に定期実行するようなアプローチをおすすめします。 結合テスト ここではデータベースや アプリケーションサーバ 、リバースプロキシなどを構成した上で実施するテストを 結合テスト とします。 テストに時間がかかりすぎるとか、テストが終わらなくて タイムアウト するとか言った問題はスローテスト問題と呼ばれています。 長期間にわたって価値を生み出すソフトウェアを実装していくにあたって、スローテスト問題は避けられません。 スローテスト問題に対する基本的なアプローチは、品質を担保できるギリギリの頻度で実行し、テストの実行コストと品質の トレードオフ における妥当な割合を見つけることです。 機械学習 によってテストの実行対象を賢く選択してくれる Launchable は、この問題に対する画期的な解決策を提供してくれるかもしれないと期待しています。 筆者の個人的な好みは、 ナイトリー ビルドのような形で一日に数回は 結合テスト を実行するものの、日常的なPRトリガーのワークフローからは外すことです。 ドキュメントの自動生成 Javadoc のようなドキュメントコメントから開発者向けドキュメントを自動生成するタスクもまたビルドタスクの一部としてよく組込みます。 フレームワーク やライブラリのように繰り返し再利用されるものを実装する際にはドキュメントコメントをしっかり書くのが望ましいでしょう。一方で、アプリケーションコードのドキュメントコメントは必要最小限に留めておくのがおすすめです。 筆者の経験上、コメント部分は動作しないためかコードと整合性をもってメンテナンスされづらく、その結果コメントとコードの内容にズレがおきることでコードを理解する妨げになる事の方が多いからです。 ドキュメントの自動生成は多くても一日に一回程度、大抵の場合は一週間に一回くらいの頻度で実施すれば事足りるので、PRから実行されるCIタスクには組み込まないことが多いです。 代わりに、クーロンジョブのような形で定期的に実行してPRを自動生成する方が低コストです。 今の GitHub Pagesにはアクセス制御機能があり、許可された開発者だけが閲覧できるサイトを簡単に構築できることは知っておいてください。 Changing the visibility of your GitHub Pages site パッケージング パッケージングは、Dockerコンテナイメージや、jarのような形式で アーカイブ されたファイルを作ることです。 単に アーカイブ すればいいものから署名が必要なものまで、言語やデプロイ先によって実行すべきタスクは様々です。 ただ、大きな傾向としてパッケージングはリリース作業の一部として実行するタスクです。 パッケージングとして実施すべきタスクの内容は極めて複雑で多岐にわたるため、今回はそういうものがあるとだけ言っておきます。 依存ライブラリのアップデート 現代的なソフトウェア開発において オープンソース ソフトウェア( OSS )の利用は避けられません。 そして、 OSS のライブラリは高頻度にアップデートされます。特に緊急性の高いセキュリティパッチと呼ばれるようなアップデートは実施しなければなりません。 とはいえ、定期的な依存ライブラリのアップデートを手動でやっていると時間がどれだけあっても不足します。つまり、自動化するしかありません。そのためには、比較的高品質な 回帰テスト が必要になります。 依存ライブラリのアップデートを自動的にやってくれるサービスとしては、 Renovate や、 GitHub に標準で組み込まれている Dependabot を使うのが良いでしょう。これらのサービスを利用するとライブラリをアップデートするPRを自動的に作ってくれます。 自動的に作られるPRをGitワークフローの中でどういう位置づけにするのかは、丁寧に検討してください。深く考えずに導入すると、無限に生成されるPRに押しつぶされてしまいますよ。 これは、筆者がメンテナンスしている社内ツールの 回帰テスト が不安定なせいで自動マージが上手く動作せず蓄積してしまったPRの山です。 システムテスト Gitのワークフローを検討する上で、 システムテスト の位置づけは整理するのが望ましいでしょう。 まずは、ワークフローの一部に システムテスト を組み込むのかどうかを検討してください。 システムテスト の自動化は極めて深遠な話題ですので、大抵のプロジェクトでは組み込まないという結論になるでしょう。 ソフトウェアが価値を生み長生きするならば、規模は大きくなり複雑になっていきます。 その中で システムテスト の自動化は取り組むべき課題の一つです。 Gitワークフローの一部として システムテスト を実行すべき状況になっていないかを、ときどき気にかけてください。 アプリケーション運用との統合 Gitワークフローとアプリケーション運用の統合については、パッケージングの話題でありデプロイの話題です。 少なくとも、ワークフローの終了ステータスをどのような形で、いつ誰に通知するのかは検討してください。 伝統的にはショートメッセージサービス(SMS)や電子メールを使っていますよね。 現代的にはSlackやTeams、LINEなどチャットツールへのメッセージ送信となるでしょう。 また、アプリケーション運用側からGitに対する情報提供をどのように実施するのかを検討するのも忘れないでください。 基本的にはプロジェクト管理ツールに対するタスクの起票( GitHub Issuesなど)を介して行うことになるはずです。 Git ワークフローの実際 ここからは、ワークフロー設計の参考になるようなGitワークフローをいくつか紹介します。 ただし、具体的な作業手順については説明していません。参考文献に詳細な説明のあるページをリンクしておきましたので参考にしてください。 ここで紹介しているものは、あくまでも基本的な型であって、これをそのまま導入すべきものではありません。 とはいえ、一定の複雑さがあるワークフローを導入する際、最初のうちは基本的な型のまま何も変えずに導入することがGitワークフローのあり方をチームとして理解する助けになるでしょう。 この説明では、デフォルトのブランチをmainブランチと記載しています。 以前は、 GitHub におけるデフォルトのブランチ名はmasterでしたが、世相を反映して現在はmainをデフォルトのブランチ名とすることが推奨されています。 GitHub、これから作成するリポジトリのデフォルトブランチ名が「main」に。「master」から「main」へ変更 シングルブランチモデル シングルブランチモデルは、開発者はサーバの リポジトリ をcloneしたらmainブランチに変更作業をコミットしていき、作業が終わり次第mainブランチをサーバにpushする方式です。 これは、 SVN からGitへ ソースコード 管理ツールを移行するチームが一時的に使う方式として検討する余地があります。 単に SVN をGitで代替し、基本的なコマンドの使い方や動作を理解する期間を設けることでツールの移行に伴う生産性の低下を緩やかにできます。 一方でシングルブランチモデルはソフトウェアの設計や、作業分担次第ではあるものの非常にコンフリクトが発生し易い使い方です。 push前に必ずrebaseしてローカル ディレクト リ内でコンフリクトを解決する。もしくは、同じファイルを同時に複数の人が修正しないよう作業範囲を調整しなければなりません。 つまり、この方式を採用してプロジェクト運営を行うならプロジェクトマネージャーが、仕様の変更や追加に伴うファイルの変更範囲を厳密に理解している必要があります。 チームが2,3人で担当範囲が明確なら、この方式でGitを使い始めるのがいいでしょう。 コンフリクトさえ発生しなければ、覚えなければならないGit固有の知識が最小限で済みます。 参考文献 Centralized Workflow トランクベース開発 GitHub Flow GitHub Flowでは、サーバの リポジトリ をcloneしたらmainブランチから作業用のフィーチャブランチへswitchします。 フィーチャブランチでの作業が終わったら、それをサーバにpushしPRを使ってmainブランチにマージします。 この方式では、gitの3-way mergeが上手く働くのでシングルブランチモデルよりも断然コンフリクトが発生し辛くなります。 原義的な GitHub Flowではmainブランチにマージされた変更は本番環境を含む何らかの実行環境にデプロイすることが重要なのですが、そこまでやらなくても十分に利便性を享受できます。 参考文献 GitHub Flow 翻訳 GitHub公式 GitLab Flow ブランチの管理とデプロイをより丁寧に対応付ける形のワークフローがGitLab Flowです。 開発者がPRを使ってmainブランチに変更をマージしていくことは GitHub Flowと同じです。 GitLab Flowでは、デプロイ作業を実施するブランチを専用に設けることで、開発におけるPRのマージとデプロイの周期やタイミングを分離します。 mainブランチにマージされたアプリケーションがテスト環境にデプロイされ、そこで問題が見つからなければ本番環境にデプロイされるというようなワークフローを想定すると、このような形になるでしょう。 大規模な開発では、テスト環境が複数用意されているものです。 テストの目的や、担当者の責任範囲によって環境が分離されているようなら環境に対応したブランチを用意した上で、それらのブランチへのマージをトリガーにデプロイを実行するでしょう。 パッケージソフト ウェアのビジネスでは、リリース済みで新機能の追加がないとしても、セキュリティの問題や深刻なバグへの対応を実施するためパッチを適用して保守していくことが望まれます。 このような状況にGitLab Flowの考え方を適用すると、それぞれのリリースに応じてブランチを作り、mainブランチから必要な変更だけを取り出してマージしていく(チェリーピック)ことになります。 このバージョンブランチを伸ばしていく保守方針は変更コストが高くなり易いので、なるべく選ばない方がいいでしょう。 しかし、これはソフトウェアの収益モデルと直接関連するので、ビジネスオーナーと開発者が丁寧な議論を実施すべき話題です。 参考文献 GitLab Flow GitLab flowから学ぶワークフローの実践 Gitflow (A successful Git branching model) Gitflowはここまで説明してきたワークフローの集大成となるものです。 開発者は、サーバの リポジトリ をcloneしたらdevlopブランチから作業用のフィーチャブランチへswitchします。 フィーチャブランチでの作業が終わったら、それをサーバにpushしPRを使ってdevelopブランチにマージします。 必要な変更作業が終わったら、リリースの担当者がdevelopブランチから新しいreleaseブランチをswitchし、アプリケーションのリリースに伴う作業を実施した成果をコミットします。ここでコミットされるものは、例えば、軽微な作業ミスの修正やバグの対応、ドキュメントの修正などです。 そういった作業が全て終了したら、releaseブランチをサーバにpushしPRを使ってmainブランチにマージしてタグを打ちます。 そうです、Gitflowにおけるmainブランチはアプリケーションの静止点を記録するためだけのブランチなのです。 ただし、緊急対応を行うホットフィックスブランチだけは例外です。 緊急対応を行う開発者は、mainブランチから作業用のホットフィックスブランチへswitchします。 作業が終わったらホットフィックスブランチをサーバにpushしPRを使ってdevelopブランチとmainブランチの両方へマージします。 その上で、mainブランチにタグを打ちアプリケーションをリリースします。 Gitflowでは非常に複雑な状況が想定されています。またそれぞれの開発者がGitに対してかなり習熟していることが前提のワークフローです。 中身を詳細に理解した上で、全ての要素が必要であると判断できるなら、リリースまでの作業を何度か実施してみてください。それでもなおプロジェクトの運営方針と合致していると確信できる場合のみGitflowを採用してください。 参考文献 A successful Git branching model 翻訳 まとめ 筆者は、Gitワークフローの設計で最も重要なのは 作りこみ過ぎない ことだと考えています。 そのために、Gitワークフローにおける検討事項を適切に把握しましょう。 みなさんのプロジェクトにおいて対応すべき課題を丁寧に把握した上でプロジェクトメンバーの生産性を最大限に発揮できるワークフローを設計してください。 具体的にどのワークフローを使えばいいか分からないなら、まずは GitHub Flowを試してみてください。 GitHub Actionsを使って簡単なビルドを行いつつ、コードレビューをするとGitを使うことの利便性を享受できます。 この記事によって、読者の皆さんがご自分のチーム内におけるGitワークフローを改善するきっかけになれば、これ以上に嬉しいことはありません。 非常に長いエントリでしたが、最後までお読みいただきありがとうございます。 執筆: @sato.taichi 、レビュー: @yamashita.tsuyoshi ( Shodo で執筆されました )
こんにちは! 電通国際情報サービス 金融ソリューション事業部の山下です。 今回は、 ゲームエンジン の Unreal Engine と、 iOS アプリの LiveLinkFace を用いたデジタルヒューマンのリアルタイムフェイスリグを行う手順を紹介します。 手順 MetaHuman Creator でデジタルヒューマンを作成する デジタルヒューマンを Unreal Projectにエクスポートする LiveLinkFaceアプリでデジタルヒューマンを動かす 実行環境 PC: macOS 12.1 Monterey Unreal Engine 4.27(β版のUE5でも動作可能ですが、今回は UE4 での手順を説明します) Quixel Bridge 2021.0.1 Mobile: iPhone X (ARKitとdepthAPIがサポートされているFaceID搭載機種が必要になります) iOS 15.2.1 LiveLinkFace 1.1.2 Network: PCとMobileが同じネットワークに接続していること(同一 Wifi 環境 or Lightning Ethernet など) 手順1. デジタルヒューマンの作成 まず、 MetaHuman Creator でデジタルヒューマンを作成します。 MetaHuman Creator は、 Epic Games が提供する高精細なデジタルヒューマンを誰でも簡単に作成できる クラウド サービスです。 プリセットされたデジタルヒューマンをベースにした顔や髪型などの モデリング が可能ですが、本記事における詳細な操作説明は割愛します。 今回は、以下のデジタルヒューマンを作成しました。 手順2. デジタルヒューマンを Unreal Projectにエクスポートする Unreal Engine にて、Blankプロジェクトを作成してプロジェクトを立ち上げます。 以下の プラグイン をインストールしましょう。 - 「Edit」->「Plugins」 - Apple ARKit - Apple ARKit Face Support - Live Link 次に、 Quixel Bridge アプリを立ち上げます。(UE5の場合はQuixel Bridgeが Unreal Engine 自体に組み込まれていますが、 UE4 では別途インストールが必要となります) MetaHuman Creator で利用したものと同じEpicGamesアカウントを用いてログインすると、先ほど作成したデジタルヒューマンを確認できます。 エクスポートを行う為に、以下の設定を行います。 - 「Settings」->「Download Settings」->「Modelsタブ」 - 項目「MetaHumans」 :「UAsset + Source Asset」 - 「Download」実行(完了まで数十分かかります) - Settings」->「Export Settings」->「Export Target」 - 項目「ExportTarget」 :「 Unreal Engine 」 - 項目「Engine Version」:自身の Unreal Engine バージョン - 項目「Plugin Location」:自身の Unreal Engine Plugin ディレクト リパス - 「Export」実行 - 初めて実行する場合は Unreal Engine 側で不足している プラグイン のWarningが表示されますが、全て有効(Enable Missing)を選択して必要 プラグイン をインストールして下さい Exportが完了すると、 Unreal Engine プロジェクトの「Content Browser」パネルにデジタルヒューマンのアセットが追加されます。 Unreal Engine プロジェクトに、先ほど追加されたアセットを ドラッグアンドドロップ で配置します。 Unreal Projectへデジタルヒューマンのエクスポートができました。 手順3. LiveLinkFaceアプリでデジタルヒューマンを動かす まず、Mobile側でLiveLinkFace iOS アプリを立ち上げ、以下の設定を行います。 - 「Setting」->「Live Link」-> 「TARGETS」 -> 「Add Target」 - 「IP Address」:接続先PCのプライベート IPアドレス を設定 頭の回転も連携させる為に、「Setting」->「Stream Head Rotation」をONにします。 Mobile側の設定は以上です。 次に、PC側の Unreal Engine 側で、Mobileデ バイス がSource Subjectとして追加されていることを確認します。 - 「Window」->「Live Link」 最後に、World Outlinerパネルからデジタルヒューマンのアセットを選択して、以下を設定します。 - 「LLink Face Subj」:自身が追加したSource Subjectを選択 - 「LLink Face Head」:ON 完成 Unreal Engine のプレイボタンを押すと、リアルタイムフェイスリグが確認できます! いかがでしたでしょうか。 EpicGames社が提供するUnrealEngine、MetaHuman、LiveLinkFaceを用いて、ノーコードでデジタルヒューマンのフェイスリグを行いました。 実はこのMetaHuman、既に映画やゲームなどの開発にも利用されており、先日公開されたPS5/ Xbox 向けデモ The Matrix Awakens: An Unreal Engine 5 Experience では、実際にハリウッド映画並のクオリティでリアルタイムに動くゲームが公開されており、その作品の主人公もMetaHumanで作成されています。 メタバース に対する注目が集まっている中、基盤となる ゲームエンジン や周辺システムも個人レベルで簡単にアクセスできるようになってきており、ますますこの領域に目が離せません。 現在ISID金融ソリューション事業部では ブロックチェーン や NFT関連の研究開発 を行っております。 既に Decentraland や Sandbox などの VR サービス内ではNFTアイテムが取引可能になっており、将来的なオープンな メタバース と ブロックチェーン の親和性は高いと考えられます。引き続き3DCG領域の技術もウォッチしていきたいと思います! 参考 Getting Started with MetaHumans in Unreal Engine Using the MetaHuman Facial Rig Recording Facial Animation from an iOS Device Introducing The Matrix Awakens: An Unreal Engine 5 Experience 執筆: @yamashita.yuki 、レビュー: @sato.taichi ( Shodo で執筆されました )
こんにちは! 電通国際情報サービス 金融ソリューション事業部の山下です。 今回は、 ゲームエンジン の Unreal Engine と、 iOS アプリの LiveLinkFace を用いたデジタルヒューマンのリアルタイムフェイスリグを行う手順を紹介します。 手順 MetaHuman Creator でデジタルヒューマンを作成する デジタルヒューマンを Unreal Projectにエクスポートする LiveLinkFaceアプリでデジタルヒューマンを動かす 実行環境 PC: macOS 12.1 Monterey Unreal Engine 4.27(β版のUE5でも動作可能ですが、今回は UE4 での手順を説明します) Quixel Bridge 2021.0.1 Mobile: iPhone X (ARKitとdepthAPIがサポートされているFaceID搭載機種が必要になります) iOS 15.2.1 LiveLinkFace 1.1.2 Network: PCとMobileが同じネットワークに接続していること(同一 Wifi 環境 or Lightning Ethernet など) 手順1. デジタルヒューマンの作成 まず、 MetaHuman Creator でデジタルヒューマンを作成します。 MetaHuman Creator は、 Epic Games が提供する高精細なデジタルヒューマンを誰でも簡単に作成できる クラウド サービスです。 プリセットされたデジタルヒューマンをベースにした顔や髪型などの モデリング が可能ですが、本記事における詳細な操作説明は割愛します。 今回は、以下のデジタルヒューマンを作成しました。 手順2. デジタルヒューマンを Unreal Projectにエクスポートする Unreal Engine にて、Blankプロジェクトを作成してプロジェクトを立ち上げます。 以下の プラグイン をインストールしましょう。 - 「Edit」->「Plugins」 - Apple ARKit - Apple ARKit Face Support - Live Link 次に、 Quixel Bridge アプリを立ち上げます。(UE5の場合はQuixel Bridgeが Unreal Engine 自体に組み込まれていますが、 UE4 では別途インストールが必要となります) MetaHuman Creator で利用したものと同じEpicGamesアカウントを用いてログインすると、先ほど作成したデジタルヒューマンを確認できます。 エクスポートを行う為に、以下の設定を行います。 - 「Settings」->「Download Settings」->「Modelsタブ」 - 項目「MetaHumans」 :「UAsset + Source Asset」 - 「Download」実行(完了まで数十分かかります) - Settings」->「Export Settings」->「Export Target」 - 項目「ExportTarget」 :「 Unreal Engine 」 - 項目「Engine Version」:自身の Unreal Engine バージョン - 項目「Plugin Location」:自身の Unreal Engine Plugin ディレクト リパス - 「Export」実行 - 初めて実行する場合は Unreal Engine 側で不足している プラグイン のWarningが表示されますが、全て有効(Enable Missing)を選択して必要 プラグイン をインストールして下さい Exportが完了すると、 Unreal Engine プロジェクトの「Content Browser」パネルにデジタルヒューマンのアセットが追加されます。 Unreal Engine プロジェクトに、先ほど追加されたアセットを ドラッグアンドドロップ で配置します。 Unreal Projectへデジタルヒューマンのエクスポートができました。 手順3. LiveLinkFaceアプリでデジタルヒューマンを動かす まず、Mobile側でLiveLinkFace iOS アプリを立ち上げ、以下の設定を行います。 - 「Setting」->「Live Link」-> 「TARGETS」 -> 「Add Target」 - 「IP Address」:接続先PCのプライベート IPアドレス を設定 頭の回転も連携させる為に、「Setting」->「Stream Head Rotation」をONにします。 Mobile側の設定は以上です。 次に、PC側の Unreal Engine 側で、Mobileデ バイス がSource Subjectとして追加されていることを確認します。 - 「Window」->「Live Link」 最後に、World Outlinerパネルからデジタルヒューマンのアセットを選択して、以下を設定します。 - 「LLink Face Subj」:自身が追加したSource Subjectを選択 - 「LLink Face Head」:ON 完成 Unreal Engine のプレイボタンを押すと、リアルタイムフェイスリグが確認できます! いかがでしたでしょうか。 EpicGames社が提供するUnrealEngine、MetaHuman、LiveLinkFaceを用いて、ノーコードでデジタルヒューマンのフェイスリグを行いました。 実はこのMetaHuman、既に映画やゲームなどの開発にも利用されており、先日公開されたPS5/ Xbox 向けデモ The Matrix Awakens: An Unreal Engine 5 Experience では、実際にハリウッド映画並のクオリティでリアルタイムに動くゲームが公開されており、その作品の主人公もMetaHumanで作成されています。 メタバース に対する注目が集まっている中、基盤となる ゲームエンジン や周辺システムも個人レベルで簡単にアクセスできるようになってきており、ますますこの領域に目が離せません。 現在ISIDは web3領域のグループ横断組織 を立ち上げ、Web3および メタバース 領域のR&Dを行っております(カテゴリー「3DCG」の記事は こちら )。 もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください! 私たちと同じチームで働いてくれる仲間を、是非お待ちしております! ISID採用ページ(Web3/メタバース/AI) 参考 Getting Started with MetaHumans in Unreal Engine Using the MetaHuman Facial Rig Recording Facial Animation from an iOS Device Introducing The Matrix Awakens: An Unreal Engine 5 Experience 執筆: @yamashita.yuki 、レビュー: @sato.taichi ( Shodo で執筆されました )
こんにちは! 電通国際情報サービス 金融ソリューション事業部の山下です。 今回は、 ゲームエンジン の Unreal Engine と、 iOS アプリの LiveLinkFace を用いたデジタルヒューマンのリアルタイムフェイスリグを行う手順を紹介します。 手順 MetaHuman Creator でデジタルヒューマンを作成する デジタルヒューマンを Unreal Projectにエクスポートする LiveLinkFaceアプリでデジタルヒューマンを動かす 実行環境 PC: macOS 12.1 Monterey Unreal Engine 4.27(β版のUE5でも動作可能ですが、今回は UE4 での手順を説明します) Quixel Bridge 2021.0.1 Mobile: iPhone X (ARKitとdepthAPIがサポートされているFaceID搭載機種が必要になります) iOS 15.2.1 LiveLinkFace 1.1.2 Network: PCとMobileが同じネットワークに接続していること(同一 Wifi 環境 or Lightning Ethernet など) 手順1. デジタルヒューマンの作成 まず、 MetaHuman Creator でデジタルヒューマンを作成します。 MetaHuman Creator は、 Epic Games が提供する高精細なデジタルヒューマンを誰でも簡単に作成できる クラウド サービスです。 プリセットされたデジタルヒューマンをベースにした顔や髪型などの モデリング が可能ですが、本記事における詳細な操作説明は割愛します。 今回は、以下のデジタルヒューマンを作成しました。 手順2. デジタルヒューマンを Unreal Projectにエクスポートする Unreal Engine にて、Blankプロジェクトを作成してプロジェクトを立ち上げます。 以下の プラグイン をインストールしましょう。 - 「Edit」->「Plugins」 - Apple ARKit - Apple ARKit Face Support - Live Link 次に、 Quixel Bridge アプリを立ち上げます。(UE5の場合はQuixel Bridgeが Unreal Engine 自体に組み込まれていますが、 UE4 では別途インストールが必要となります) MetaHuman Creator で利用したものと同じEpicGamesアカウントを用いてログインすると、先ほど作成したデジタルヒューマンを確認できます。 エクスポートを行う為に、以下の設定を行います。 - 「Settings」->「Download Settings」->「Modelsタブ」 - 項目「MetaHumans」 :「UAsset + Source Asset」 - 「Download」実行(完了まで数十分かかります) - Settings」->「Export Settings」->「Export Target」 - 項目「ExportTarget」 :「 Unreal Engine 」 - 項目「Engine Version」:自身の Unreal Engine バージョン - 項目「Plugin Location」:自身の Unreal Engine Plugin ディレクト リパス - 「Export」実行 - 初めて実行する場合は Unreal Engine 側で不足している プラグイン のWarningが表示されますが、全て有効(Enable Missing)を選択して必要 プラグイン をインストールして下さい Exportが完了すると、 Unreal Engine プロジェクトの「Content Browser」パネルにデジタルヒューマンのアセットが追加されます。 Unreal Engine プロジェクトに、先ほど追加されたアセットを ドラッグアンドドロップ で配置します。 Unreal Projectへデジタルヒューマンのエクスポートができました。 手順3. LiveLinkFaceアプリでデジタルヒューマンを動かす まず、Mobile側でLiveLinkFace iOS アプリを立ち上げ、以下の設定を行います。 - 「Setting」->「Live Link」-> 「TARGETS」 -> 「Add Target」 - 「IP Address」:接続先PCのプライベート IPアドレス を設定 頭の回転も連携させる為に、「Setting」->「Stream Head Rotation」をONにします。 Mobile側の設定は以上です。 次に、PC側の Unreal Engine 側で、Mobileデ バイス がSource Subjectとして追加されていることを確認します。 - 「Window」->「Live Link」 最後に、World Outlinerパネルからデジタルヒューマンのアセットを選択して、以下を設定します。 - 「LLink Face Subj」:自身が追加したSource Subjectを選択 - 「LLink Face Head」:ON 完成 Unreal Engine のプレイボタンを押すと、リアルタイムフェイスリグが確認できます! いかがでしたでしょうか。 EpicGames社が提供するUnrealEngine、MetaHuman、LiveLinkFaceを用いて、ノーコードでデジタルヒューマンのフェイスリグを行いました。 実はこのMetaHuman、既に映画やゲームなどの開発にも利用されており、先日公開されたPS5/ Xbox 向けデモ The Matrix Awakens: An Unreal Engine 5 Experience では、実際にハリウッド映画並のクオリティでリアルタイムに動くゲームが公開されており、その作品の主人公もMetaHumanで作成されています。 メタバース に対する注目が集まっている中、基盤となる ゲームエンジン や周辺システムも個人レベルで簡単にアクセスできるようになってきており、ますますこの領域に目が離せません。 現在ISIDは web3領域のグループ横断組織 を立ち上げ、Web3および メタバース 領域のR&Dを行っております(カテゴリー「3DCG」の記事は こちら )。 もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください! 私たちと同じチームで働いてくれる仲間を、是非お待ちしております! ISID採用ページ(Web3/メタバース/AI) 参考 Getting Started with MetaHumans in Unreal Engine Using the MetaHuman Facial Rig Recording Facial Animation from an iOS Device Introducing The Matrix Awakens: An Unreal Engine 5 Experience 執筆: @yamashita.yuki 、レビュー: @sato.taichi ( Shodo で執筆されました )
電通国際情報サービス オープン イノベーション ラボの比嘉です。 今回のテーマは、スマート コントラ クト。スマート コントラ クトとは ブロックチェーン 上にデプロイされるプログラムのことで、今回は、 Gethはじめました の続きになります。 まだ、上記の記事をやってない方は、お手数をおかけしますが先に上記の記事をやってください。GethはEthereumクライアントの中で公式に推奨されているクライアントです。 Gethの再起動 Solidityのインストール macOSの場合 Windowsの場合 スマートコントラクトのコード solc スマートコントラクトのデプロイ まとめ Gethの再起動 上記記事で、Gethのメインプロセスを終了させた方は、もう一度再起動しましょう。 $ cd private_net $ geth --networkid 1203 --nodiscover --datadir . 別のターミナルを立ち上げて、メインプロセスにコンソールで接続します。 $ cd private_net $ geth attach geth.ipc 採掘が止まっている場合は、採掘を開始しましょう。 > eth.mining false > miner.start() null Solidityのインストール Ethereumでスマート コントラ クトを書くための プログラミング言語 としては、Solidity, Vyper, Fe, lllなどがありますが、よく使われているのはSolidityです。そこで、今回はSolidityをインストールします。 Solidityをインストールするための 公式サイトはこちら macOS の場合 Homebrewを事前にインストールし、次のコマンドを実行しましょう。 $ brew update $ brew upgrade $ brew tap ethereum/ethereum $ brew install solidity $ brew linkapps solidity brew update を実行するときに Error: homebrew-core is a shallow clone. のエラーが、起きる場合があります。その場合はメッセージに、書いてあるとおりに、gitコマンドを実行しましょう。 インストールがうまくいっていれば、次のコマンドが成功します。 $ solc --version Windows の場合 ダウンロードサイト から、 solc-windows.exe を落としてインストールしましょう。 スマート コントラ クトのコード 最初のスマート コントラ クトとして、数値をスマート コントラ クトの状態変数に格納したり、取り出したりするプログラムを書いてみましょう。 NumberRegister.sol pragma solidity ^ 0.8 . 10 ; contract NumberRegister { uint num; function set( uint _num) public { num = _num; } function get() public view returns ( uint ) { return num; } } Solidityの細かい文法については、今後の記事で取り上げるので、細かいことは気にしなくて大丈夫です。この NumberRegiseter.sol をprivate_netの ディレクト リに保存しましょう。 solc SolidityのプログラムをEthereumで実行できるようにするには、 solc で コンパイル します。 コンパイル とは、 NumberRegiseter.sol のような人間が見て理解しやすいコードをコンピューターが実行できるように変更することです。 もう一つ、ターミナルを立ち上げて、 solc を実行しましょう。 $ cd private_net $ solc --abi --bin NumberRegister.sol 次のような出力が表示されたはずです。 ======= NumberRegister.sol:NumberRegister ======= Binary: 608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806360fe47b11461003b5780636d4ce63c14610057575b600080fd5b610055600480360381019061005091906100c3565b610075565b005b61005f61007f565b60405161006c91906100ff565b60405180910390f35b8060008190555050565b60008054905090565b600080fd5b6000819050919050565b6100a08161008d565b81146100ab57600080fd5b50565b6000813590506100bd81610097565b92915050565b6000602082840312156100d9576100d8610088565b5b60006100e7848285016100ae565b91505092915050565b6100f98161008d565b82525050565b600060208201905061011460008301846100f0565b9291505056fea2646970667358221220348a0bef0ed2915311a28c4b28b351b950a27275e260ed0a915108c3b0257d2c64736f6c634300080a0033 Contract JSON ABI [{"inputs":[],"name":"get","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"}] Binaryのところに書いてある 6080 ではじまり 0033 で終わる文字列の先頭に0xを付加した上で、シングルクォートでくくり、Gethのコンソールに貼り付けます。BinaryはEVM(Ethereumの 仮想マシン )が理解できる バイトコード です。 > bin = '0x608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806360fe47b11461003b5780636d4ce63c14610057575b600080fd5b610055600480360381019061005091906100c3565b610075565b005b61005f61007f565b60405161006c91906100ff565b60405180910390f35b8060008190555050565b60008054905090565b600080fd5b6000819050919050565b6100a08161008d565b81146100ab57600080fd5b50565b6000813590506100bd81610097565b92915050565b6000602082840312156100d9576100d8610088565b5b60006100e7848285016100ae565b91505092915050565b6100f98161008d565b82525050565b600060208201905061011460008301846100f0565b9291505056fea2646970667358221220348a0bef0ed2915311a28c4b28b351b950a27275e260ed0a915108c3b0257d2c64736f6c634300080a0033' 同様に Contract JSON ABI もコンソールに貼り付けましょう。ABIはスマート コントラ クトの入出力の仕様になります。 > abi = [{"inputs":[],"name":"get","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"}] ここで定義した bin と abi は、この後で使うので覚えておいてください。binはEVM(Ethereumの 仮想マシン )が理解できる バイトコード 、abiはスマート コントラ クトの入出力の仕様です。 スマート コントラ クトのデプロイ 先ほどのスマート コントラ クトをEthereumネットワークにデプロイしましょう。 > cnt = eth.contract(abi).new({from: eth.accounts[0], data: bin}) Error: authentication needed: password or unlock at web3.js:6347:37(47) at web3.js:5081:62(37) at web3.js:3021:48(134) at <eval>:1:28(16) Error: authentication needed: password or unlock が発生した場合は、アカウントをunlockAcount()しましょう。 トランザクション を実行する場合は、アカウントをunlockAccount()する必要があります。このエラーは何度も見ることになるので、どう対応すれば良いか体で覚えましょう。 > personal.unlockAccount(eth.accounts[0]) Unlock account 0x29faad1bb68151278c47df617766bf045c9b2b00 Passphrase: true > cnt = eth.contract(abi).new({from: eth.accounts[0], data: bin}) { abi: [{ inputs: [], name: "get", outputs: [{...}], stateMutability: "view", type: "function" }, { inputs: [{...}], name: "set", outputs: [], stateMutability: "nonpayable", type: "function" }], address: undefined, transactionHash: "0x13658235f5bff4afefd57b504a048f5c2bc37241bacfd9ce58177627aa1882b2" } cntの中身のaddressがundefinedになっていますね。これは、このスマート コントラ クトのデプロイがまだ終わっていないことを表しています。Gethのメインプロセスのログで採掘がきちんと行われていることを確認したら、cnt.addressを確認しましょう。 > cnt.address "0x102118ad7f8bede0158d2353660f63ea5780f966" スマート コントラ クトに、アクセスするにはABI(スマート コントラ クトの入出力の仕様)とaddressが必要です。それでは、NumberRegister コントラ クトを作りましょう。 > cnt2 = eth.contract(abi).at(cnt.address) { abi: [{ inputs: [], name: "get", outputs: [{...}], stateMutability: "view", type: "function" }, { inputs: [{...}], name: "set", outputs: [], stateMutability: "nonpayable", type: "function" }], address: "0x102118ad7f8bede0158d2353660f63ea5780f966", transactionHash: null, allEvents: function(), get: function(), set: function() } スマート コントラ クトの状態を変更しない場合は、 トランザクション なしで実行できます。それでは、NumberRegister.get()メソッドを呼び出してみましょう。 コントラクトオブジェクト.メソッド名.call() で呼びだすことができます。 > cnt2.get.call() 0 スマート コントラ クトの状態を変更する場合、 コントラクトオブジェクト.メソッド名.sendTransaction() を呼び出します。それでは、NumberRegister.set()を呼び出してみましょう。 > cnt2.set.sendTransaction(1, {from: eth.accounts[0]}) Error: authentication needed: password or unlock at web3.js:6347:37(47) at web3.js:5081:62(37) at web3.js:4137:41(57) at <eval>:1:36(10) エラーが出ていない人は気にしなくて大丈夫です。上記のエラーが出た人は、unlockAccount()を呼び出しましょう。 > personal.unlockAccount(eth.accounts[0]) Unlock account 0x29faad1bb68151278c47df617766bf045c9b2b00 Passphrase: true > txid = cnt2.set.sendTransaction(1, {from: eth.accounts[0]}) "0xf12e076acec31684bade23f3ca12c14396160a86464ce1298bbe10e795824f2e" Gethのメインプロセスのログで採掘が動いていることを確認し、NumberRegister.get()を呼び出してみましょう。 > cnt2.get.call() 1 cnt2.set.sendTransaction() の第一引数で指定した値が、設定されていることが分かります。 まとめ スマート コントラ クトを コンパイル すると、ABI(入出力の仕様)とバイナリー(EVMが理解できる バイトコード )が出力されます。 バイナリーをEthereumネットワークにデプロイするとaddressが付加されます。 ABIとaddressを使って コントラ クトオブジェクトを作成して、スマートコンタクトにアクセスします。 スマート コントラ クトの状態を変更しない場合、 コントラクトオブジェクト.メソッド名.call() を呼び出します。 スマート コントラ クトの状態を変更する場合、 コントラクトオブジェクト.メソッド名.sendTransaction() を呼び出します。 今回はここまで。Gethを止めておきましょう。コンソールはCTL-D。メインプロセスはCTL-Cで止めます。正直、GethのコンソールはNode.jsのモジュールも使えないなど、かなり不便です。次回からは、開発環境として Hardhat を使います。 僕の書いたNFT関連の記事 Gethはじめました NFT入門 執筆: @higa 、レビュー: @sato.taichi ( Shodo で執筆されました )
電通国際情報サービス オープン イノベーション ラボの比嘉です。 今回のテーマは、スマート コントラ クト。スマート コントラ クトとは ブロックチェーン 上にデプロイされるプログラムのことで、今回は、 Gethはじめました の続きになります。 まだ、上記の記事をやってない方は、お手数をおかけしますが先に上記の記事をやってください。GethはEthereumクライアントの中で公式に推奨されているクライアントです。 Gethの再起動 Solidityのインストール macOSの場合 Windowsの場合 スマートコントラクトのコード solc スマートコントラクトのデプロイ まとめ Gethの再起動 上記記事で、Gethのメインプロセスを終了させた方は、もう一度再起動しましょう。 $ cd private_net $ geth --networkid 1203 --nodiscover --datadir . 別のターミナルを立ち上げて、メインプロセスにコンソールで接続します。 $ cd private_net $ geth attach geth.ipc 採掘が止まっている場合は、採掘を開始しましょう。 > eth.mining false > miner.start() null Solidityのインストール Ethereumでスマート コントラ クトを書くための プログラミング言語 としては、Solidity, Vyper, Fe, lllなどがありますが、よく使われているのはSolidityです。そこで、今回はSolidityをインストールします。 Solidityをインストールするための 公式サイトはこちら macOS の場合 Homebrewを事前にインストールし、次のコマンドを実行しましょう。 $ brew update $ brew upgrade $ brew tap ethereum/ethereum $ brew install solidity $ brew linkapps solidity brew update を実行するときに Error: homebrew-core is a shallow clone. のエラーが、起きる場合があります。その場合はメッセージに、書いてあるとおりに、gitコマンドを実行しましょう。 インストールがうまくいっていれば、次のコマンドが成功します。 $ solc --version Windows の場合 ダウンロードサイト から、 solc-windows.exe を落としてインストールしましょう。 スマート コントラ クトのコード 最初のスマート コントラ クトとして、数値をスマート コントラ クトの状態変数に格納したり、取り出したりするプログラムを書いてみましょう。 NumberRegister.sol pragma solidity ^ 0.8 . 10 ; contract NumberRegister { uint num; function set( uint _num) public { num = _num; } function get() public view returns ( uint ) { return num; } } Solidityの細かい文法については、今後の記事で取り上げるので、細かいことは気にしなくて大丈夫です。この NumberRegiseter.sol をprivate_netの ディレクト リに保存しましょう。 solc SolidityのプログラムをEthereumで実行できるようにするには、 solc で コンパイル します。 コンパイル とは、 NumberRegiseter.sol のような人間が見て理解しやすいコードをコンピューターが実行できるように変更することです。 もう一つ、ターミナルを立ち上げて、 solc を実行しましょう。 $ cd private_net $ solc --abi --bin NumberRegister.sol 次のような出力が表示されたはずです。 ======= NumberRegister.sol:NumberRegister ======= Binary: 608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806360fe47b11461003b5780636d4ce63c14610057575b600080fd5b610055600480360381019061005091906100c3565b610075565b005b61005f61007f565b60405161006c91906100ff565b60405180910390f35b8060008190555050565b60008054905090565b600080fd5b6000819050919050565b6100a08161008d565b81146100ab57600080fd5b50565b6000813590506100bd81610097565b92915050565b6000602082840312156100d9576100d8610088565b5b60006100e7848285016100ae565b91505092915050565b6100f98161008d565b82525050565b600060208201905061011460008301846100f0565b9291505056fea2646970667358221220348a0bef0ed2915311a28c4b28b351b950a27275e260ed0a915108c3b0257d2c64736f6c634300080a0033 Contract JSON ABI [{"inputs":[],"name":"get","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"}] Binaryのところに書いてある 6080 ではじまり 0033 で終わる文字列の先頭に0xを付加した上で、シングルクォートでくくり、Gethのコンソールに貼り付けます。BinaryはEVM(Ethereumの 仮想マシン )が理解できる バイトコード です。 > bin = '0x608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806360fe47b11461003b5780636d4ce63c14610057575b600080fd5b610055600480360381019061005091906100c3565b610075565b005b61005f61007f565b60405161006c91906100ff565b60405180910390f35b8060008190555050565b60008054905090565b600080fd5b6000819050919050565b6100a08161008d565b81146100ab57600080fd5b50565b6000813590506100bd81610097565b92915050565b6000602082840312156100d9576100d8610088565b5b60006100e7848285016100ae565b91505092915050565b6100f98161008d565b82525050565b600060208201905061011460008301846100f0565b9291505056fea2646970667358221220348a0bef0ed2915311a28c4b28b351b950a27275e260ed0a915108c3b0257d2c64736f6c634300080a0033' 同様に Contract JSON ABI もコンソールに貼り付けましょう。ABIはスマート コントラ クトの入出力の仕様になります。 > abi = [{"inputs":[],"name":"get","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"}] ここで定義した bin と abi は、この後で使うので覚えておいてください。binはEVM(Ethereumの 仮想マシン )が理解できる バイトコード 、abiはスマート コントラ クトの入出力の仕様です。 スマート コントラ クトのデプロイ 先ほどのスマート コントラ クトをEthereumネットワークにデプロイしましょう。 > cnt = eth.contract(abi).new({from: eth.accounts[0], data: bin}) Error: authentication needed: password or unlock at web3.js:6347:37(47) at web3.js:5081:62(37) at web3.js:3021:48(134) at <eval>:1:28(16) Error: authentication needed: password or unlock が発生した場合は、アカウントをunlockAcount()しましょう。 トランザクション を実行する場合は、アカウントをunlockAccount()する必要があります。このエラーは何度も見ることになるので、どう対応すれば良いか体で覚えましょう。 > personal.unlockAccount(eth.accounts[0]) Unlock account 0x29faad1bb68151278c47df617766bf045c9b2b00 Passphrase: true > cnt = eth.contract(abi).new({from: eth.accounts[0], data: bin}) { abi: [{ inputs: [], name: "get", outputs: [{...}], stateMutability: "view", type: "function" }, { inputs: [{...}], name: "set", outputs: [], stateMutability: "nonpayable", type: "function" }], address: undefined, transactionHash: "0x13658235f5bff4afefd57b504a048f5c2bc37241bacfd9ce58177627aa1882b2" } cntの中身のaddressがundefinedになっていますね。これは、このスマート コントラ クトのデプロイがまだ終わっていないことを表しています。Gethのメインプロセスのログで採掘がきちんと行われていることを確認したら、cnt.addressを確認しましょう。 > cnt.address "0x102118ad7f8bede0158d2353660f63ea5780f966" スマート コントラ クトに、アクセスするにはABI(スマート コントラ クトの入出力の仕様)とaddressが必要です。それでは、NumberRegister コントラ クトを作りましょう。 > cnt2 = eth.contract(abi).at(cnt.address) { abi: [{ inputs: [], name: "get", outputs: [{...}], stateMutability: "view", type: "function" }, { inputs: [{...}], name: "set", outputs: [], stateMutability: "nonpayable", type: "function" }], address: "0x102118ad7f8bede0158d2353660f63ea5780f966", transactionHash: null, allEvents: function(), get: function(), set: function() } スマート コントラ クトの状態を変更しない場合は、 トランザクション なしで実行できます。それでは、NumberRegister.get()メソッドを呼び出してみましょう。 コントラクトオブジェクト.メソッド名.call() で呼びだすことができます。 > cnt2.get.call() 0 スマート コントラ クトの状態を変更する場合、 コントラクトオブジェクト.メソッド名.sendTransaction() を呼び出します。それでは、NumberRegister.set()を呼び出してみましょう。 > cnt2.set.sendTransaction(1, {from: eth.accounts[0]}) Error: authentication needed: password or unlock at web3.js:6347:37(47) at web3.js:5081:62(37) at web3.js:4137:41(57) at <eval>:1:36(10) エラーが出ていない人は気にしなくて大丈夫です。上記のエラーが出た人は、unlockAccount()を呼び出しましょう。 > personal.unlockAccount(eth.accounts[0]) Unlock account 0x29faad1bb68151278c47df617766bf045c9b2b00 Passphrase: true > txid = cnt2.set.sendTransaction(1, {from: eth.accounts[0]}) "0xf12e076acec31684bade23f3ca12c14396160a86464ce1298bbe10e795824f2e" Gethのメインプロセスのログで採掘が動いていることを確認し、NumberRegister.get()を呼び出してみましょう。 > cnt2.get.call() 1 cnt2.set.sendTransaction() の第一引数で指定した値が、設定されていることが分かります。 まとめ スマート コントラ クトを コンパイル すると、ABI(入出力の仕様)とバイナリー(EVMが理解できる バイトコード )が出力されます。 バイナリーをEthereumネットワークにデプロイするとaddressが付加されます。 ABIとaddressを使って コントラ クトオブジェクトを作成して、スマートコンタクトにアクセスします。 スマート コントラ クトの状態を変更しない場合、 コントラクトオブジェクト.メソッド名.call() を呼び出します。 スマート コントラ クトの状態を変更する場合、 コントラクトオブジェクト.メソッド名.sendTransaction() を呼び出します。 今回はここまで。Gethを止めておきましょう。コンソールはCTL-D。メインプロセスはCTL-Cで止めます。正直、GethのコンソールはNode.jsのモジュールも使えないなど、かなり不便です。次回からは、開発環境として Hardhat を使います。 僕の書いたNFT関連の記事 Gethはじめました NFT入門 執筆: @higa 、レビュー: @sato.taichi ( Shodo で執筆されました )
皆さん、こんにちは。 電通国際情報サービス X イノベーション 本部ソフトウェアデザインセンターの陳 欣瑩です。 業務で Amazon ECSとCodeDeployを使ってBlue/Greenデプロイを実施してみたのでその方法をご紹介します。 CodeDeployを使ったECSのBlue/Greenデプロイの手順を紹介する記事は少なくありませんが、実際にやってみると意外とハマったことが多かったです。 本記事では、ハマったことや使ってみた感想についてもご紹介したいと思います。 CodeDeployを使ったBlue/Greenデプロイについて 方法 手順の自動化 CodeDeployの設定 トラフィックの再ルーティング デプロイ設定 元のリビジョンの終了 ハマったこと CodeDeployのinstallイベントが一向に終わらない テストトラフィックの動作確認ができない リスナーポートの設定 どのドメインからテスト環境にアクセスすべきかがわからなかった Next.jsを利用する場合のAPI URL問題 使ってみた感想 デプロイの所要時間はとても短い 本番と同じ環境で動作確認できる 何よりダウンタイム0はすごい まとめ 参考にした情報 CodeDeployを使ったBlue/Greenデプロイについて CodeDeployを使ってBlue/Greenデプロイを実現するには、ターゲットグループを2つ用意する必要があります。 ALBのルーティング制御によって、 トラフィック を流すターゲットグループを切り替えることで、ダウンタイムなしで環境を切り替えることを実現できます。 図から詳しく説明します。 本番環境はユーザーがアクセス可能な環境で、テスト環境は開発者のみアクセス可能な、動作確認のための環境だと想像してください。 Target Group1とTarget Group2がありますが、初期状態では、本番環境とテスト環境の トラフィック は両方ともTarget Group1に流します。 CodeDeployを利用し、新しいコンテナイメージをデプロイすると、テスト環境の トラフィック の転送先は新しいコンテナーを持つTarget Group2に切り替えます。 本番環境の トラフィック はそのまま古いコンテナーを持つTarget Group1に流すため、デプロイ期間においても本番環境へのアクセスは可能です。 テスト環境での動作確認が完了後、CodeDeployを利用してALBの本番環境への トラフィック 転送を制御できます。本番環境もテスト環境も最新のコンテナーを持つTarget Group2に トラフィック を転送します。 トラフィック の転送の切り替えはほとんど時間がかからないため、ダウンタイムほぼ0でデプロイできます。 Blue/Greenデプロイは本番環境とテスト環境の入れ替えのイメージがありますが、CodeDeployの場合はデプロイ完了後、本番環境もテスト環境も同じターゲットグループに トラフィック を転送します。 次のデプロイを実行すると、Target Group1は最新のコンテナーを持つようになリます。 デプロイ実行後、テスト環境のリスナーは自動的にTarget Group1に トラフィック を転送し、本番環境のリスナーはそのままTarget Group2に トラフィック を転送します。 本番環境の トラフィック の転送を制御することで、テスト環境と本番環境は両方ともTarget Group1に トラフィック を転送します。 方法 AWS マネジメントコンソールから以下のリソースを作成しました。 VPC などネットワークインフラ CodeDeployにECSを更新するアクセス許可を付与するIAMロール ALB ECRレポジトリ ECS クラスタ ー ECSタスク定義 ECSサービス Route53を利用する場合は、Aレコードを作成し、ルーティング先をALBにする リソースの作成、およびBlue/Greenデプロイの実行手順は以下の記事を参考にしました。 https://aws.amazon.com/jp/premiumsupport/knowledge-center/codedeploy-ecs-blue-green-deployment/ https://aws.amazon.com/jp/blogs/news/use-aws-codedeploy-to-implement-blue-green-deployments-for-aws-fargate-and-amazon-ecs/ 今回は本番環境で HTTPS を利用したいため、本番環境のリスナーポートを443、テスト環境のリスナーポートを8443にしました。 手順の自動化 AWS for GitHub Actionsを組み合わせれば、 GitHub Actionsワークフローを利用してCodeDeployの実行までの手順を自動化できます。 Dockerfileをbuildし、タグをつけてECRにpushする amazon-ecr-login ECSタスク定義を更新する amazon-ecs-render-task-definition 更新されたタスク定義を使ってCodeDeployのデプロイを実行させる amazon-ecs-deploy-task-definition GitHub にタグをプッシュすることで、既存のECSリソースにCodeDeployを使用したBlue/Greenデプロイができます。ただし、デプロイ後の トラフィック 転送先の切り替えなど、CodeDeployに対する操作は AWS マネジメントコンソールから手動で操作する必要があります。 CodeDeployの設定 AWS マネジメントコンソールから、CodeDeployの以下の設定を変更できます。(アプリケーション>デプロイグループを選択>編集) トラフィック の再ルーティング トラフィック の再ルーティングとは、ALBで本番 トラフィック の転送先のターゲットグループを切り替えることを指します。 デフォルトでは、 トラフィック が直ちに置き換え先環境に再ルーティングされるように設定されています。 トラフィック が再ルーティングされる前に、動作確認したい場合は再ルーティングするタイミング、つまり待機する日数、時間、分数を指定できます。動作確認のために再ルーティングを保留できる時間は最短5分、最長時1日間23時間55分まで指定できます。 Lambda関数の検証テストをAppSpecファイルに追加すれば、設定した待機時間内に検証テストが自動的に実行されます。 テスト環境のポートにアクセスすれば動作確認ができます。動作確認が完了後、再ルーティングを実行するために、CodeDeployの「 トラフィック の再ルーティング」ボタンを指定した待機時間内に押下する必要があります。(CodeDeployのコンソールでデプロイIDをクリックした後の画面にあります) 待機時間が経過しても、再ルーティングが実行されない場合は、デプロイの状態は失敗になります。 デプロイ設定 デプロイの速度や、デプロイ成功または失敗の条件など、ルールを設定できます。 元のリビジョンの終了 新しいタスクのデプロイが完了後、元のタスクセットを終了するまでの時間を設定できます。デフォルトは1時間です。 設定した時間内に、デプロイしたものに問題があったら、いつでも元のタスクセットに ロールバック できます。 再ルーティングの実行後でも ロールバック はできます。 終了処理が開始すると ロールバック することはできません。 ハマったこと CodeDeployのinstallイベントが一向に終わらない CodeDeployのコンソールでは詳しいログ情報やエラーメッセージが表示されないため、最初は原因がよくわからず困りました。 今回は、Dockerfileに不備があり、起動できない状態のコンテナーをデプロイしようとしているのが原因でした。他の記事を読むと、IAMロールに必要な権限がない場合や、task-definition. json にミスがあった場合でもCodeDeoloyのinstallが延々と続くらしいです。 何かの不備があるとCodeDeployでのinstallイベントは一向に終わらなくなります。しかし、Dockerfileやtask-definition. json は変更を頻繁に加えるものではないため、デプロイが成功したものを使い続ければこのような問題は発生しないでしょう。 テスト トラフィック の動作確認ができない ECSとCodeDeployを使用してBlue/Greenデプロイを実施すると、設定した待機時間内に、テスト環境のリスナーポートにアクセスし動作確認ができます。しかし、リスナーポートの設定が不適切な場合やWebアプリケーションのURLがハードコードされる場合は、動作確認できないこともあります。 リスナーポートの設定 最初は、本番環境のリスナーポートを HTTPS /443、テスト環境のリスナーポートをHTTP/8080にしましたが、テスト環境のリスナーポートにアクセスできませんでした。 理由としては、検証で使っていた .dev の ドメイン ではHTTPが使えないからです。他にも、HTTPを HTTPS にリダイレクトする要件があれば、両方とも HTTPS のポートにしたほう望ましいでしょう。 どの ドメイン からテスト環境にアクセスすべきかがわからなかった 最初は、本番環境と同じ ドメイン でなくALBの ドメイン を使ってテスト環境にアクセスしてしまいました。 本番環境と異なる ドメイン からアクセスすると、場合によってログインできなくなったり、 API リク エス トを投げられなくなったりすることもあります。 本番環境の ドメイン は https://example.com であれば、それと同じ ドメイン のテストポート https://example.com:8443 からテスト環境にアクセスするのが正解です。 Next.jsを利用する場合の API URL問題 Next.jsのgetServerSidePropsを利用し、 API リク エス トを送信するには、 API エンドポイントのURLを次のように指定する必要があります。 axios.get(https://example.com/api/hello) https://example.com の部分を 環境変数 として設定してしまう場合は、異なるポートからアクセスし API にリク エス トを送信すると、CORSエラーが発生します。 それを回避するために、URLのハードコードをやめて、以下のようにgetServerSidePropsのcontextからホスト名とポート番号を取得しました。 axios.get(https://${ctx.req.headers.host!}/api/hello) ただし、 プロトコル はcontextから取得できないため、 https を固定するまたは 環境変数 に入れる必要があります。 使ってみた感想 デプロイの所要時間はとても短い 今回は GitHub Actionsを利用すると、ほとんどのワークフローの処理時間は1秒程度で完結できました。DockerfileのbuildおよびECRへのpushは、相対的に時間かかりましたが、Dockerfileの改善により処理速度の短縮が期待できます。 GitHub Actionsのワークフローが成功した後、CodeDeployでのデプロイ(置き換えタスクセットのデプロイ、テスト トラフィック ルーティングのセットアップ)は約2、3分間くらいかかります。動作確認を含め、デプロイの全体を数分程度に抑えることができたのですごいと思いました。 本番と同じ環境で動作確認できる テスト トラフィック で動作確認し、問題がなければ本番 トラフィック の転送先を切り替えればデプロイが完了しますので、テスト トラフィック の転送先のターゲットグループは本番に昇格するみたいなイメージですね。万が一動作確認でバグを見つけても、本番環境に影響せず ロールバック ができます。 何よりダウンタイム0はすごい また、 トラフィック の再ルーティングはほとんど時間がかからないため、デプロイで発生するダウンタイムは0に近いです。テスト トラフィック で動作確認できるため、ユーザーはデプロイ作業に影響されなくシステムを使い続けられます。 まとめ 本記事では、 Amazon ECSとCodeDeployを使ってBlue/Greenデプロイメンを実施する方法、ハマったところや使ってみた感想についてご紹介しました。デプロイの時間を短縮し、ダウンタイムなしでデプロイできるので、本当に便利だと思いました。 AWS によくまとめてある設定手順がありますので、皆さんご機会がありましたらぜひ使ってみてください。 最後までお読みいただきありがとうございました。 参考にした情報 https://aws.amazon.com/jp/premiumsupport/knowledge-center/codedeploy-ecs-blue-green-deployment/ https://aws.amazon.com/jp/blogs/news/use-aws-codedeploy-to-implement-blue-green-deployments-for-aws-fargate-and-amazon-ecs/ https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/deployment-type-bluegreen.html 執筆: @chen.xinying 、レビュー: @sato.taichi ( Shodo で執筆されました )
皆さん、こんにちは。 電通国際情報サービス X イノベーション 本部ソフトウェアデザインセンターの陳 欣瑩です。 業務で Amazon ECSとCodeDeployを使ってBlue/Greenデプロイを実施してみたのでその方法をご紹介します。 CodeDeployを使ったECSのBlue/Greenデプロイの手順を紹介する記事は少なくありませんが、実際にやってみると意外とハマったことが多かったです。 本記事では、ハマったことや使ってみた感想についてもご紹介したいと思います。 CodeDeployを使ったBlue/Greenデプロイについて 方法 手順の自動化 CodeDeployの設定 トラフィックの再ルーティング デプロイ設定 元のリビジョンの終了 ハマったこと CodeDeployのinstallイベントが一向に終わらない テストトラフィックの動作確認ができない リスナーポートの設定 どのドメインからテスト環境にアクセスすべきかがわからなかった Next.jsを利用する場合のAPI URL問題 使ってみた感想 デプロイの所要時間はとても短い 本番と同じ環境で動作確認できる 何よりダウンタイム0はすごい まとめ 参考にした情報 CodeDeployを使ったBlue/Greenデプロイについて CodeDeployを使ってBlue/Greenデプロイを実現するには、ターゲットグループを2つ用意する必要があります。 ALBのルーティング制御によって、 トラフィック を流すターゲットグループを切り替えることで、ダウンタイムなしで環境を切り替えることを実現できます。 図から詳しく説明します。 本番環境はユーザーがアクセス可能な環境で、テスト環境は開発者のみアクセス可能な、動作確認のための環境だと想像してください。 Target Group1とTarget Group2がありますが、初期状態では、本番環境とテスト環境の トラフィック は両方ともTarget Group1に流します。 CodeDeployを利用し、新しいコンテナイメージをデプロイすると、テスト環境の トラフィック の転送先は新しいコンテナーを持つTarget Group2に切り替えます。 本番環境の トラフィック はそのまま古いコンテナーを持つTarget Group1に流すため、デプロイ期間においても本番環境へのアクセスは可能です。 テスト環境での動作確認が完了後、CodeDeployを利用してALBの本番環境への トラフィック 転送を制御できます。本番環境もテスト環境も最新のコンテナーを持つTarget Group2に トラフィック を転送します。 トラフィック の転送の切り替えはほとんど時間がかからないため、ダウンタイムほぼ0でデプロイできます。 Blue/Greenデプロイは本番環境とテスト環境の入れ替えのイメージがありますが、CodeDeployの場合はデプロイ完了後、本番環境もテスト環境も同じターゲットグループに トラフィック を転送します。 次のデプロイを実行すると、Target Group1は最新のコンテナーを持つようになリます。 デプロイ実行後、テスト環境のリスナーは自動的にTarget Group1に トラフィック を転送し、本番環境のリスナーはそのままTarget Group2に トラフィック を転送します。 本番環境の トラフィック の転送を制御することで、テスト環境と本番環境は両方ともTarget Group1に トラフィック を転送します。 方法 AWS マネジメントコンソールから以下のリソースを作成しました。 VPC などネットワークインフラ CodeDeployにECSを更新するアクセス許可を付与するIAMロール ALB ECRレポジトリ ECS クラスタ ー ECSタスク定義 ECSサービス Route53を利用する場合は、Aレコードを作成し、ルーティング先をALBにする リソースの作成、およびBlue/Greenデプロイの実行手順は以下の記事を参考にしました。 https://aws.amazon.com/jp/premiumsupport/knowledge-center/codedeploy-ecs-blue-green-deployment/ https://aws.amazon.com/jp/blogs/news/use-aws-codedeploy-to-implement-blue-green-deployments-for-aws-fargate-and-amazon-ecs/ 今回は本番環境で HTTPS を利用したいため、本番環境のリスナーポートを443、テスト環境のリスナーポートを8443にしました。 手順の自動化 AWS for GitHub Actionsを組み合わせれば、 GitHub Actionsワークフローを利用してCodeDeployの実行までの手順を自動化できます。 Dockerfileをbuildし、タグをつけてECRにpushする amazon-ecr-login ECSタスク定義を更新する amazon-ecs-render-task-definition 更新されたタスク定義を使ってCodeDeployのデプロイを実行させる amazon-ecs-deploy-task-definition GitHub にタグをプッシュすることで、既存のECSリソースにCodeDeployを使用したBlue/Greenデプロイができます。ただし、デプロイ後の トラフィック 転送先の切り替えなど、CodeDeployに対する操作は AWS マネジメントコンソールから手動で操作する必要があります。 CodeDeployの設定 AWS マネジメントコンソールから、CodeDeployの以下の設定を変更できます。(アプリケーション>デプロイグループを選択>編集) トラフィック の再ルーティング トラフィック の再ルーティングとは、ALBで本番 トラフィック の転送先のターゲットグループを切り替えることを指します。 デフォルトでは、 トラフィック が直ちに置き換え先環境に再ルーティングされるように設定されています。 トラフィック が再ルーティングされる前に、動作確認したい場合は再ルーティングするタイミング、つまり待機する日数、時間、分数を指定できます。動作確認のために再ルーティングを保留できる時間は最短5分、最長時1日間23時間55分まで指定できます。 Lambda関数の検証テストをAppSpecファイルに追加すれば、設定した待機時間内に検証テストが自動的に実行されます。 テスト環境のポートにアクセスすれば動作確認ができます。動作確認が完了後、再ルーティングを実行するために、CodeDeployの「 トラフィック の再ルーティング」ボタンを指定した待機時間内に押下する必要があります。(CodeDeployのコンソールでデプロイIDをクリックした後の画面にあります) 待機時間が経過しても、再ルーティングが実行されない場合は、デプロイの状態は失敗になります。 デプロイ設定 デプロイの速度や、デプロイ成功または失敗の条件など、ルールを設定できます。 元のリビジョンの終了 新しいタスクのデプロイが完了後、元のタスクセットを終了するまでの時間を設定できます。デフォルトは1時間です。 設定した時間内に、デプロイしたものに問題があったら、いつでも元のタスクセットに ロールバック できます。 再ルーティングの実行後でも ロールバック はできます。 終了処理が開始すると ロールバック することはできません。 ハマったこと CodeDeployのinstallイベントが一向に終わらない CodeDeployのコンソールでは詳しいログ情報やエラーメッセージが表示されないため、最初は原因がよくわからず困りました。 今回は、Dockerfileに不備があり、起動できない状態のコンテナーをデプロイしようとしているのが原因でした。他の記事を読むと、IAMロールに必要な権限がない場合や、task-definition. json にミスがあった場合でもCodeDeoloyのinstallが延々と続くらしいです。 何かの不備があるとCodeDeployでのinstallイベントは一向に終わらなくなります。しかし、Dockerfileやtask-definition. json は変更を頻繁に加えるものではないため、デプロイが成功したものを使い続ければこのような問題は発生しないでしょう。 テスト トラフィック の動作確認ができない ECSとCodeDeployを使用してBlue/Greenデプロイを実施すると、設定した待機時間内に、テスト環境のリスナーポートにアクセスし動作確認ができます。しかし、リスナーポートの設定が不適切な場合やWebアプリケーションのURLがハードコードされる場合は、動作確認できないこともあります。 リスナーポートの設定 最初は、本番環境のリスナーポートを HTTPS /443、テスト環境のリスナーポートをHTTP/8080にしましたが、テスト環境のリスナーポートにアクセスできませんでした。 理由としては、検証で使っていた .dev の ドメイン ではHTTPが使えないからです。他にも、HTTPを HTTPS にリダイレクトする要件があれば、両方とも HTTPS のポートにしたほう望ましいでしょう。 どの ドメイン からテスト環境にアクセスすべきかがわからなかった 最初は、本番環境と同じ ドメイン でなくALBの ドメイン を使ってテスト環境にアクセスしてしまいました。 本番環境と異なる ドメイン からアクセスすると、場合によってログインできなくなったり、 API リク エス トを投げられなくなったりすることもあります。 本番環境の ドメイン は https://example.com であれば、それと同じ ドメイン のテストポート https://example.com:8443 からテスト環境にアクセスするのが正解です。 Next.jsを利用する場合の API URL問題 Next.jsのgetServerSidePropsを利用し、 API リク エス トを送信するには、 API エンドポイントのURLを次のように指定する必要があります。 axios.get(https://example.com/api/hello) https://example.com の部分を 環境変数 として設定してしまう場合は、異なるポートからアクセスし API にリク エス トを送信すると、CORSエラーが発生します。 それを回避するために、URLのハードコードをやめて、以下のようにgetServerSidePropsのcontextからホスト名とポート番号を取得しました。 axios.get(https://${ctx.req.headers.host!}/api/hello) ただし、 プロトコル はcontextから取得できないため、 https を固定するまたは 環境変数 に入れる必要があります。 使ってみた感想 デプロイの所要時間はとても短い 今回は GitHub Actionsを利用すると、ほとんどのワークフローの処理時間は1秒程度で完結できました。DockerfileのbuildおよびECRへのpushは、相対的に時間かかりましたが、Dockerfileの改善により処理速度の短縮が期待できます。 GitHub Actionsのワークフローが成功した後、CodeDeployでのデプロイ(置き換えタスクセットのデプロイ、テスト トラフィック ルーティングのセットアップ)は約2、3分間くらいかかります。動作確認を含め、デプロイの全体を数分程度に抑えることができたのですごいと思いました。 本番と同じ環境で動作確認できる テスト トラフィック で動作確認し、問題がなければ本番 トラフィック の転送先を切り替えればデプロイが完了しますので、テスト トラフィック の転送先のターゲットグループは本番に昇格するみたいなイメージですね。万が一動作確認でバグを見つけても、本番環境に影響せず ロールバック ができます。 何よりダウンタイム0はすごい また、 トラフィック の再ルーティングはほとんど時間がかからないため、デプロイで発生するダウンタイムは0に近いです。テスト トラフィック で動作確認できるため、ユーザーはデプロイ作業に影響されなくシステムを使い続けられます。 まとめ 本記事では、 Amazon ECSとCodeDeployを使ってBlue/Greenデプロイメンを実施する方法、ハマったところや使ってみた感想についてご紹介しました。デプロイの時間を短縮し、ダウンタイムなしでデプロイできるので、本当に便利だと思いました。 AWS によくまとめてある設定手順がありますので、皆さんご機会がありましたらぜひ使ってみてください。 最後までお読みいただきありがとうございました。 参考にした情報 https://aws.amazon.com/jp/premiumsupport/knowledge-center/codedeploy-ecs-blue-green-deployment/ https://aws.amazon.com/jp/blogs/news/use-aws-codedeploy-to-implement-blue-green-deployments-for-aws-fargate-and-amazon-ecs/ https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/deployment-type-bluegreen.html 執筆: @chen.xinying 、レビュー: @sato.taichi ( Shodo で執筆されました )