メニューを閉じる

テクノデジタルグループ

メニューを開く

2022.08.03

インフラ

【AWS】クロスアカウントデプロイメント with Git submodule の問題と解決

はじめに

初投稿のMTと申します。ちなみにマニュアル車の運転はできるはずですがもう怖くてできません。
できるエンジニアには程遠い私ですが、せっかくなので様々なことを試してみて、
得た知見を書いていけたらなと思います。
よろしくお願いいたします。

今回の記事は、AWS Codeシリーズを用いてCI/CDパイプラインを構築する中に発生した問題です。
クロスアカウントのCI/CDの記事は有りますが、本問題に関しては見つからず、時間かかってしまいました。
もし同様の問題にぶつかった方、対応されている方の参考になれば幸いです。

概要

今回私がぶつかった問題はタイトルの通り、
「Git submodule を適用した管理ソースを別アカウントにデプロイしたい」
という要望を実現しようとした時に発生した事象です。
詳細については後ほど述べますが、端的にいうと、
「どこでどうやってsubmoduleを最新化するか」が問題になりました。
この問題に関して、正直かなり力技ですが、解決策の一つを提示したいと思います。

解決策

とりあえず早速どのように解決したか、という話をさせていただきます。
と言ってもとてもシンプルな方法です。
CodeBuildで直接git pullしちゃいましょう!
かなり力技ですが、自分の調べた限りでは、これ以外に解決策が見つかりませんでした。
ひとまず、解説に移りたいと思います。

解説

「Git submodule を適用した管理ソースを別アカウントにデプロイしたい」
という要望の実現のため、まず自分は問題を2つに分けました。
1. Git submoduleを用いてCodeCommit管理されているソースのデプロイ
2. クロスアカウントのパイプライン構築
これらに関しては参考になりそうな記事が多く存在していました。
例として自分が参考にした記事をご紹介させていただきます。
1.の参考
2.の参考

これらの内容に関して詳しく知りたい場合は上記の記事や他の記事を探して参考にしていただいて、
ここではざっくりとだけ紹介すると

1.の解決

ソースアーティファクトに.gitファイルを含むようにしましょう
→そのために、CodePipelineのSourceステージを編集し、
[出力アーティファクト形式]を「完全クローン」に変更する。
→CodeBuildでサブモジュールをアップデートする。
これでsubmoduleを含むビルドの実行とデプロイが可能です。

2.の解決

アカウントAのCodeCommitでソース管理を行い、アカウントBでデプロイを行うとします。
構築するパイプラインの処理の流れは、
1. アカウントAのCodeCommitが変更される
2. アカウントBのKMSを用いて暗号化したアーティファクトをアカウントBのS3に保存する
3. アカウントBのCodebuildがS3からアーティファクトを取得、KMSで復号
4. 以降は通常のパイプラインと大差なし
という形になり、そのための権限付与にさえ気をつければ、大きな問題なく設定可能なものです。

※なお、CodeCommitの変更を検知して自動的にデプロイを開始させる設定のためには、
EventBridgeの設定が必要です。
(参考:(クロスアカウントでのEventBridgeのリレー)

では、これらをどちらも実装すれば問題なく動くはず!
と思っていたのですが、そう上手くはいきませんでした…

エラー発生

CodeBuildでエラー表示されました。
詳細なエラーはメモしていなかったためご紹介できないのですが、
エラーとしては、「該当のコミットへのアクセスができません」と言ったものでした。

ここで注目するべきは、解決策1.で出てきた[出力アーティファクト形式]でした。
この形式の「完全クローン形式」について解説を読むと、
> AWS CodePipeline はリポジトリに関するメタデータを渡し、後続の操作で完全な git クローンを作成できます。AWS CodeBuild 操作に対してのみサポートされます。
もう一つの形式であるデフォルトの形式は
> AWS CodePipeline では、パイプラインのアーティファクトにデフォルトの zip 形式が使用されます。リポジトリに関する git メタデータは含まれません。

つまり、デフォルトの方式だと.gitファイルを除いたリポジトリの複製が
アーティファクトに保存されるのに対して、
完全クローン形式は、cloneをするための情報のみが保管されることになります。
つまり、アカウントA用の情報を使って、アカウントBでCodeCommitに
アクセスしようとしていることになるわけです。
失敗するのも当たり前ですね。

解決まで

この問題を解決する方法として、自分がとった手段は至ってシンプル、
「アクセスする権限を渡して、git cloneしてしまう」というものです。
もっと効果的かつ安全な手段はあるかもしれませんが、
時間の問題もあり、今回の解決策を取りました。

CodeBuildでは、env配列の中で、
git-credential-helperというものを利用する設定があるのですが、
本稿での動作検証時はうまく動作させることができなかったので、
同様のenvハッシュで、パラメータストアから値を取得することで、
安全にCodeCommitのgit認証情報を受け渡すことにしました。

手順

1. アカウントAのCodeCommitにアクセスできるIAMを作成する。
2. 作成したIAMユーザのgit認証情報を作成する
3. アカウントBの SystemManager>パラメータストア に2.で作成した
認証情報を適当な名前で登録(型はSecure String)
4. アカウントBのCodeBuildの権限に、ssm:Get*の権限を付与する(スコープは適宜調整)
5. アカウントBのCodeBuild用のbuildspec.ymlファイルのenvハッシュに
parameter-storeハッシュを追加し、認証情報をパラメータストアから読み出す
6. 取得した認証情報を使ってgit操作する

問題点

上記方法で解決はできました。
しかし、権限周りは基本的にロールで管理した方が安全であることから、
このように権限を操作するのは、煩雑化を招きかねません。
また、CodeBuild内部の操作も複雑になりがちで、
作成者以外がわかりにくいものになりやすいと考えられます。
これらを解消できる良い解決策がないかは引き続き探したいと思います。

終わりに

今回の記事は、以上です。
AWSを始めとしたクラウドサービスは、
様々な人が、自身のサービスを展開する基盤としてとても有用なものであり、
多くの要望に対応できるように改良が重ねられていますが、
できないことや、できるけれど煩雑な箇所は、
どうしても出てくると思うので、そこに関して、
最適解を出せるよう知識を身につけたいと思います。
本稿をご覧いただきありがとうございました。
本稿が何か課題解決のきっかけになれば幸いです。


【テクノモバイルではエンジニア/デザイナーを積極採用中です!】

下記項目に1つでも当てはまる方は是非、詳細ページへ!
  • 自分でアプリを作ってみたい
  • ITで世の中にワクワクを生み出したい
  • 使いやすさ、デザインにこだわったWebサイトを開発したい

採用情報の詳細はこちら


Qangaroo(カンガルー)

  • 徹底した見やすさと優れた操作性で、テストの「見える化」を実現。
  • テストの進捗が見える。開発がスマートに進む。
  • クラウド型テスト管理ツール『Qangaroo(カンガルー)』
https://qangaroo.jp/

最近の記事

SNS共有