きな粉もち.net

.NET関連仕事に携わっています。OSSのソースを読んで気がついたことを中心に呟いたりブログに投稿したりしています。最近はUiPathを使ったRPAも研究中。気軽にフォローやツッコミよろしくおねがいします! Gitはここを使っています https://github.com/kinakomotitti

Azure× Github × 自作Webアプリの開発・公開環境について整理してみた

この記事の目的

この記事では、
Nzenの開発・公開環境の整理をした時のメモ
を目的としています。

本題

★全体の構成について

コードの構成管理をしつつ、CI/CDの環境も構築したい。


…ということで、

最小限の投資でできる範囲の開発環境を構築することにしました。

既にある程度の開発をGithubで進めていたので、
ソースコードリポジトリGithubを使います。
しかし、Githubには、Ci/CDをするための設定がないため、
ほかのサービスの機能を使って、CI/CDを構築することにしました。


Githubと連携し、自由にCI/CD環境を構築することができるもの…


ということで、Azure DevopsのPiplinesを利用することにしました。
テスト…というテストはまだ整備していないですが、
CI/CD環境は基本的にすべてをPiplineの機能を使って実現していこうと思います。

アプリの公開については、アカウントがあるのでAzureを使うことにしました。
Azureのどのサービスを利用するか…という点については、当初、
Webアプリの公開になるので、WebAppsでいいかと思っていましたが、

・結構な頻度で更新する
・すぐに立ち上がってほしい
・細かいアプリ設定は環境変数で変更できるようにしたい

という気持ちが高まってきたので、コンテナーをデプロイできるものにしようと考えなおしました。
ということで、今回は、Azure Container Instanseを利用してアプリを公開します。

コンテナを使ってアプリを公開することになったので、
コンテナのためのリポジトリレジストリ?)も必要になりました。
レジストリについては、Docker hubか、Azure Container Registoryか迷っていますが、
動作確認のために使っていた環境があるので、Azureを使っていこうと思います。


いずれ利用料金的なところで問題が出てきたら
Docker hubやその他のサービスに切り替えていこうと思います。

ということで、第一弾の開発・公開環境の構成はこのようになりました。
f:id:kinakomotitti:20190422234330p:plain

★各種設定1)Azure Piplines

Azure Piplinesでは、以下のことを実行します。
1)Webアプリケーションのビルド
2)ビルドしたモジュールの単体テスト
3)Docker Imageのビルド
4)Docker ImageをAzure Container Registoryに登録
5)ACIで動いているコンテナのDocker Imageの更新

ASP,NETの「Dockerサポート」では、
上記の1)と、3)を実行するDockerfileを作成してくれます。
f:id:kinakomotitti:20190422234504p:plain

これに単体テスト実行処理を追加するか、
すべてを分けて実行するようにするか検討する必要があります。

…が、まだテストの実装まで至っていないので、
1~3)までをDocker Imageのビルドと一緒に行ってしまう方向で進めます。
いずれ、テストをするようになったときに再度検討します。


★各種設定2)環境変数

(今後作っていく)DBへの接続文字列や、
Cognitive Searcviceへの接続情報など、
ローカルの開発環境と、公開環境で異なる情報が存在します。

今までは、Configファイルに外だししてきましたが、
コンテナ化されたアプリケーションに対しては、
環境変数で切り替えるのがベストプラクティスとされています。
<ここに参考URL>

Nzenもこのプラクティスにならって、環境依存の情報は環境変数に外だしすることにしました。
こんな感じのクラスを使って、環境変数に外だしした情報を管理しようと思います。

    public class ApplicationEnv
    {
        public static ApplicationEnv Env = new ApplicationEnv();

        private ApplicationEnv()
        {
            var config = new ConfigurationBuilder().AddEnvironmentVariables().Build();
            var propList = typeof(ApplicationEnv).GetProperties();
            foreach (var item in propList)
            {
                var temp = string.Empty;
                try
                {
                    temp = config.GetValue<string>(item.Name.ToString());
                }
                catch (Exception) { }
                if (temp != null) item.SetValue(this, temp);
            }
        }

        #region プロパティ

        /// <summary>
        /// (いずれ実装する)DBへの接続文字列
        /// </summary>
        public string ConnectionString { get; set; } = string.Empty;

        /// <summary>
        /// Cognitive ServiceのAPI設定
        /// </summary>
        public string SpeechAPI_Key { get; set; } = string.Empty;

        /// <summary>
        /// Cognitive Serviceのリージョン設定
        /// </summary>
        public string SpeechAPI_Region { get; set; } = string.Empty;

        #endregion
    }


環境変数に設定した情報を使ってアプリケーションを動かす仕組みは完成しました。



その環境依存の環境変数の情報はどこに設定すればよいのでしょうか…
いくつか方法はあると思いますが、思いついたのは以下の3パターンでした。
①Dockerfile中に埋め込む
②Azure Piplineの処理の中(ACI更新時)
③初回のACI作成時

Githubにコミットしたとき、パスワードなどの情報が含まれないようにしたいので、
①は除外しました。
初回だけだと、やり方を忘れてしまいそうなので、③も除外しました。

ということで、②のAzure Piplineの処理の中で、ACIの更新を行う処理に
環境変数を設定する処理を追加することにしました。



まとめ(られなかったこと)、今後の課題

ひとまず、GithubとAzureを使ってそれっぽい開発環境の構築ができました。
ただ、まだ暫定対応しているところもいろいろあるので、今後ブラッシュアップしていこうと思います。


課題1;単体テスト計画について考える
課題2:テストの実装
課題3:CI/CDをステップごとに定義するか、Docker build時に一気にやってしまうか決める