EDASプラットフォームでウェブサイトをホストし、GitHubで自動的にアップグレードする方法

このチュートリアルでは、サンプルサイトをEDASプラットフォームでホストし、GitHubを使って自動的にWebサイトをアップグレードする方法を紹介します。

*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/automated-web-app-deployment-from-github-push-using-alibaba-cloud-edas_594687)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*

[Alibaba Cloud Tech Share](https://www.alibabacloud.com/campaign/techshare?spm=a2c65.11461447.0.0.50114d80DZPGF1) 執筆者、Amit Maity。[Tech Share](https://www.alibabacloud.com/campaign/techshare?spm=a2c65.11461447.0.0.50114d80DZPGF1)は、技術的な知識やベストプラクティスをクラウドコミュニティ内で共有することを奨励するAlibaba Cloudのインセンティブプログラムです。

#概要
Alibaba Cloud [Enterprise Distributed Application Service](https://www.alibabacloud.com/product/edas?spm=a2c65.11461447.0.0.50114d80DZPGF1)（EDAS）は、アプリケーションやマイクロサービスをホスティングするためのPaaSプラットフォームを、高可用性、監視、リリース管理機能を備えて提供しています。EDASの機能を拡張するために、EDASとJenkinsを使用して継続的な統合/デプロイメントソリューションを構築することができます。

#アーキテクチャ
この記事では、Javaで書かれたWebアプリケーションを使用し、このアプリケーションのwar buildをEDASにデプロイします。また、このアプリケーションのソースコードはGitHubリポジトリに管理されています。

GitHubリポジトリの変更はJenkinsにプッシュされ、Jenkinsパイプラインプロジェクトのビルドが自動的にトリガーされ、最新バージョンのソースコードを含む新しいwarファイルが生成され、EDAS APIを使用して同じEDASアプリケーションにデプロイされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/b3b7d709-614f-fe1d-2fc3-d9691d8909ea.png)

#前提条件
このチュートリアルは、以下の技術や概念に精通していれば、簡単に理解して従うことができます。

- アリババクラウド環境
アクセス権をお持ちでない方は、以下のリンクを使用して、10ドルのクレジットで1年間無料でアクセスすることができます。
- [アリババクラウド無料アカウント](https://www.alibabacloud.com/referral?spm=a2c65.11461447.0.0.50114d80DZPGF1&referralCode=kwfk44)
- アリババ企業分散アプリケーションサービス
EDASについて詳しく知りたい方は[こちら](https://www.alibabacloud.com/help/doc-detail/42934.htm?spm=a2c65.11461447.0.0.50114d80DZPGF1)
- ジェンキンス
ジェンキンスについて詳しく知りたい方は[こちら](https://jenkins.io/doc/?spm=a2c65.11461447.0.0.50114d80DZPGF1)をクリック
- Pythonのプログラミング知識

#サーバーの設定
ここでデモした完全なソリューションを開発して実行するには、Jenkins、Python 2.7、Dockerがプリインストールされたホストサーバ（Alibaba Cloud ECSまたはその他のLinuxサーバ）が必要です。または、以下のリンクを参照して、Jenkins、Python 2.7、Dockerをダウンロードしてインストールしてください。

- [Jenkinsのインストール](https://jenkins.io/doc/book/installing/?spm=a2c65.11461447.0.0.50114d80DZPGF1)
- [Pythonのインストール](https://www.python.org/downloads/?spm=a2c65.11461447.0.0.50114d80DZPGF1)
- [Dockerのインストール](https://docs.docker.com/install/?spm=a2c65.11461447.0.0.50114d80DZPGF1)
GitHubリポジトリからJenkinsホスト内の任意のディレクトリにサンプルWebアプリケーションをダウンロード/クローンします。

[サンプルWebアプリケーションのソースコード](https://github.com/itexpertshire/webapptest?spm=a2c65.11461447.0.0.50114d80DZPGF1)

クラウドアカウントで以下のサービスを購入し、有効化します。

- オブジェクトストレージサービス(OSS)
- エンタープライズ分散アプリケーションサービス(EDAS)
- コンピューティングサーバ(ECS)

#OSS、ECS、EDASの設定
先に進む前に、必要なすべてのアリババクラウドサービスを設定するために、単一のリージョン（中国-北京）を決定してください。これにより、複数のリージョンのサービスを統合する際の技術的な課題を回避することができます。

1、OSSコンソールに新しいバケットを作成し、EDASアプリケーションとしてデプロイされるWebアプリケーションのjava warファイルを保存します。バケットのアクセスポリシーがpublic readに設定されていることを確認してください。そうしないと、EDASインスタンスがデプロイ用のwarファイルを取得できない可能性があります。
バケット名とOSSのエンドポイントをメモしておきます。後日、このソリューションの設定ファイルをバケット名とOSSエンドポイントで更新する必要があります。
2、Alibabaのクラウドコンソールで、最小1GBのメモリとCentOS 7.4のOSでECSインスタンスを作成します。リージョンはOSSリージョンと同じものを選択します。また、このホスト用に新しいVPCネットワークを作成し、パブリックIPを割り当てます。
3、ECSインスタンスが起動したら、VNCでホストに接続した後、EDASエージェントをインストールします。以下は、エージェントをインストールするために実行するコマンドです。ECS ホストのリージョンに応じてリージョン部分を変更してください。この例では "e cn-beijing "が弊社ECSのリージョンです。

```
wget -q -O /root/install.sh http://edas-bj.oss-cn-beijing-internal.aliyuncs.com/intl/install.sh && sh /root/install.sh -full
```

4、Products->EDAS->Resources->ClustersでEDASクラスタを設定します。クラスタ作成フォームに以下の内容を入力します。このEDASクラスタにECSインスタンスのVPCネットワークを割り当てます。
**リージョン**：ECSホストと同じ
**クラスター名**： ご希望に応じて
**タイプ**： ECS
**ネットワークタイプ**： VPC
**VPCネットワーク**：ECSホストのVPCネットワーク

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/b6b82aa9-a3ff-cd0a-a359-8caefbedbc1e.png)

5、クラスタが作成されたら、クラスタの詳細ページを開き、クラスタホストを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/540796e4-a16d-b29e-0017-6fa0b3be0928.png)

6、クラスタホストの追加フォームで、インポートECSオプションを選択し、Synchronize ECSボタンをクリックするとECSホストのリストが表示されます。ホストを選択し、残りの手順に従ってクラスタのセットアップを完了します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/4d38565f-62e8-5093-611a-e5e3581414b2.png)

7、さて、EDAS->アプリケーション管理->アプリケーションから以下の設定オプションでEDASアプリケーションを作成します。
クラスタ：前のステップで作成したクラスタの名前
ランタイム環境：デフォルト値を使用
Java 環境：JDK8
注：次のステップボタンを有効にするには、フォームにすべての詳細を入力した後、数分待つ必要があるかもしれません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/191e8833-5db9-331d-7198-f51333ca40f3.png)

次のステップでは、デプロイ方法をwarとして選択し、クラスタホストのリストからインスタンスを選択します。Deploy Nowオプションを使用し、`https://warfiles.oss-cn-beijing.aliyuncs.com/webapptest.war` urlを使用してサンプルのWebアプリケーションのwarファイルをデプロイします。
アプリケーションが作成されたら、設定ファイルで更新する必要があるので、アプリケーションIDをメモしておきます。

8、デプロイが成功したら、以下のようにEDASアプリケーションが起動しているかどうかを確認します。もし実行中であれば、[http://<](https://www.alibabacloud.com/blog/automated-web-app-deployment-from-github-push-using-alibaba-cloud-edas_594687)ECS HostのパブリックIP>:8080（デフォルトのhttpポート）を使用してウェブサイトにアクセスしてみてください。全てが期待通りに動作していれば、以下のようなWebページを見ることができるはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/a86afd82-be56-5289-4831-4ac79bfc5a26.png)


サンプルWebアプリケーションページ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/54eefe6b-4ad4-692a-30aa-db4f1461f0c9.png)

#Jenkinsのセットアップ
既にJenkinsが動作するようにLinuxホストが設定されており，管理者権限でJenkinsのホームページにアクセスできることを前提としています。また、推奨されるプラグインはすべてJenkinsの初期設定時にインストールされています。Jenkinsの起動に苦労している場合は、[Jenkinsのインストール](https://jenkins.io/doc/book/installing/?spm=a2c65.11461447.0.0.50114d80DZPGF1)のリンクを参照してください。また、ポート443でのインターネットトラフィックの受信を許可するように、Linuxホストネットワークのファイアウォールルールが適切に設定されていることを確認してください。

それでは、残りの設定手順に従ってJenkinsを設定し、自動ビルドとデプロイを行うようにしましょう。

1、このチュートリアルのデモを簡単にするために、Jenkinsのセキュリティ設定を無効にしてください。しかし、本番環境ではこの設定はお勧めできません。
Jenkins->Manage Jenkins->Configure Global Security
このようにセキュリティを無効にします。
(警告: 不正アクセスを避けるために、本番環境ではこのステップを避け、適切なセキュリティ設定を設定する必要があります)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/169a5a09-e247-b4ff-7d3a-baa58a471391.png)

2、プラグインマネージャから以下のJenkinsプラグインがインストールされているかどうかを確認してください。インストールされていない場合は、インストールしてください。
Jenkins->Jenkinsを管理->プラグインの管理
利用可能なタブをクリックして、フィルター欄にgitと入力します。以下のプラグインを選択してインストールします。これらのプラグインが検索結果に表示されない場合は、すでにインストールされている可能性があります。
Gitプラグイン
GitHub
GitHub 統合プラグイン

3、ビルドパイプラインプロジェクトを設定する前に、Jenkinsで以下の設定を更新します。
Jenkins->Jenkinsの管理->システムの設定
以下のようにGitHubサーバーを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/3fd3b383-6c51-7fa9-7563-75d92352c75c.png)

GitHubのプルリクエストをgithubプロジェクトのURLで更新します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/b31775d2-e766-78d4-1f2d-ebb7ed9021f0.png)

4、自動ビルド用のPipelineプロジェクトを作成します。
Jenkins->新規項目
プロジェクト名を入力し、パイプラインの種類を選択して、[OK]をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/489d4b52-db30-8357-dc5e-1b7c260f927b.png)

本プロジェクトの以下の構成を以下のように更新します。
Jenkins->WebAppBuild->Configure
GitHubプロジェクトにGitHubリポジトリのURLを入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/d08d9c5b-60aa-524e-7149-ef3cc2fad6fd.png)


ビルドトリガーのセクションで、GITScmポーリングのためのGitHubフックトリガーを選択し、SCMをポーリングするオプションを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/91b4e223-ef1e-b265-b2e0-964e3cef8db9.png)

詳細プロジェクトオプションで、以下のようにパイプライン定義を選択します。

定義. SCMからのパイプラインスクリプト

SCM: Git

リポジトリ：
- リポジトリ URL: [https://github.com/ username>/.git](https://github.com/?spm=a2c65.11461447.0.0.50114d80DZPGF1)
- 資格情報：GitHub の資格情報
- スクリプトパス：Jenkinsfile

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/a0c2aa48-2b58-9215-56ce-c292ff9089b3.png)

Jekinsfile は [https://github.com/itexpertshire/webapptest/](https://github.com/itexpertshire/webapptest/?spm=a2c65.11461447.0.0.50114d80DZPGF1) で既に利用可能なので注意してください。 github アカウントでプロジェクトのフォークを作成し、Jenkinsfile を修正して独自のパイプラインスクリプトを書いてください。

Jenkinsfile のチュートリアル：

```
pipeline {

agent {

docker {

image 'openkbs/jre-mvn-py3'

args '-u 0 --name=mycontainer -v /home/bitnami/GitHub/webapptest/jenkins/scripts:/root/.m2'

}

}

stages {

stage('Build') {

steps {

sh 'mvn -B -DskipTests clean package'

}

}

stage('Python Library Install') {

steps {

sh './jenkins/scripts/pythoninstall.sh'

}

}

stage('Deliver') {

steps {

sh './jenkins/scripts/deliver.sh'

}

}

}

}
```

1、パイプラインスクリプトはDockerコンテナ内で実行します。ここではDockerイメージopenkbs/jre-mvn-py3を使用します。

引数 -u 0 は root 権限で Docker コンテナを実行するために使用します。

Dockerコンテナ内でJenkinsステージスクリプトを利用するには、Githubプロジェクトをフォルダ内にクローンし、ローカルのjenkninsフォルダをdockerコンテナのディレクトリパスに以下の構文でマッピングします。

```
-v /home/bitnami/GitHub/webapptest/jenkins/scripts:/root/.m2
```

ここでは、githubプロジェクトをJenkinsサーバーのGitHubフォルダにクローンしています。

インストールに応じて、/home/bitnami/GitHub/webapptest/jenkins/scriptsのパスを、Jenkinsのパイプラインステージのスクリプトの場所を指すJenkinsホストのローカルパスに置き換えてください。ここでは絶対パスを忘れずに記載してください。

2、 Build stageでは、mvnツールを起動してGithubプロジェクトのソースコードのwarファイルをビルドします。

3、 Python Library Installステージでは、EDAS APIを呼び出すために必要なPythonライブラリをdockerにインストールし、EDASプラットフォームにWebアプリケーションのコードをデプロイします。

以下のPythonライブラリをインストールする必要があります。

```
aliyun-python-sdk-core==2.12.0

oss2

configparser
```

4、 Deliver.shスクリプトはPythonスクリプトEDAS.pyを実行し、ビルド段階で生成されたjava warファイルをOSSにアップロードし、EDASアプリケーションにデプロイします。EDAS.pyの詳細は後述します。

#GitHubの設定
Jenkins が稼働していて、外部アプリケーションからの http/https リクエストを受け付けることができると仮定します。

フォークされたプロジェクトで、Webhook の設定を行います。

GitHub->{あなたのプロジェクト}->設定->Webhooks

以下のようにwebhookレコードを追加します。UrlはあなたのJenkinsホストの公開IPアドレスに置き換えてください。

レコードを保存した後、webhookのURLは緑のアイコンで検証済みとしてマークされている必要があります。そうでない場合は、Jenkinsで設定を確認してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/cf3f4e91-aa8a-8120-a6ae-2de6cb48a1c6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/1b77dc13-3c4f-12d2-c99d-642b9e39e267.png)

EDAS Pythonアプリのチュートリアル
以下は、EDAS APIを使用してJavaアプリケーションをデプロイするPythonスクリプトのチュートリアルです。

**a. edas.cfg**

このファイルには、Pythonスクリプトを実行するために必要なすべての設定値が保持されています。クラウドアカウント/サービスの詳細に応じて、このファイルの設定パラメータを更新してください。



```
AccessKeyId = <Cloud Account Access Key>

AccessKeySecret = < Cloud Account Access Secret Key >

Endpoint = <EDAS End points url> i.e. edas.cn-beijing.aliyuncs.com

Region = <EDAS region>  i.e. cn-beijing

AppId = <EDAS application id>

OSSEndpoint = <OSS End Point url> i.e. oss-cn-shenzhen.aliyuncs.com

OSSBucketName = <OSS Bucket Name> i.e. warfiles
```

**b.  common.py**

このスクリプトはedas.cfgから必要な設定パラメータの値を解析し、EDASアプリケーションデプロイメントAPIを起動するためのメインのPythonスクリプトEDAS.pyに値を返します。

```
# Read config.cfg and parse the configuration parameters

parser = ConfigParser.ConfigParser()

parser.read(cfg_fn)
```

```
# Assign each of the configuration parameters values to separate varaiables

accessKeyId = parser.get("Base", "AccessKeyId")

accessKeySecret = parser.get("Base", "AccessKeySecret")

endpoint = parser.get("Base", "Endpoint")

.

.

.

return accessKeyId,accessKeySecret,endpoint,region . . .
```

**c.  EDAS.py**

このスクリプトでは、EDAS APIを呼び出すコアロジックを使用しています。アリババクラウドは、EDASプラットフォームにアプリケーションをデプロイするための/pop/v5/changeorder/co_deploy APIを提供しています。このAPIはwarファイルの場所をURL形式で受け付けています。そのため、ウォーファイルをAlibaba OSSバケットにアップロードし、ウォーファイルのOSS URLをEDAS apiのパラメータとして渡す必要があります。OSSバケットの読み込みアクセスポリシーはpublicに設定する必要があります。

スクリプトはローカルのwarファイルの場所を入力パラメータとして受け取り、upload_war関数を使ってwarファイルをOSSバケットにアップロードします。アップロードに成功すると、warファイルの完全な OSS url を生成します。

```
def upload_war(warfilepath):

auth = oss2.Auth(accessKeyId, accessKeySecret)

bucket = oss2.Bucket(auth, ossendpoint, ossbucketname)

oss2.resumable_upload(bucket, os.path.basename(warfilepath), warfilepath)

warurl = "https://"+ossbucketname+"."+ossendpoint+"/"+os.path.basename(warfilepath)
```

このスクリプトでは、warファイルをデプロイするためのAPIを呼び出すための "deploy "関数を定義しています。

```
def deploy(warurl):
```

EDAS api が POST メソッドでリクエストを受け付け、api のバージョンを '2017-08-01' に設定する必要があります。

```
request = CommonRequest()

request.set_accept_format('json')

request.set_method('POST')

request.set_protocol_type('https') # https | http

request.set_domain(endpoint)

request.set_version('2017-08-01')
```

以下のように必要なAPIパラメータをすべて設定します。

- RegionId : アプリケーションが設定されている地域
- AppId : EDASアプリケーションのアプリケーションID
- PackageVersion : 固有の数値
- DeployType: url
- WarUrl：warファイルの OSS url
- グループID：すべて

```
request.add_query_param('RegionId', region)

request.add_query_param('AppId',appid )

request.add_query_param('PackageVersion',packageversion)

request.add_query_param('DeployType','url')

request.add_query_param('WarUrl',warurl)

request.add_query_param('GroupId','all')
```

httpリクエストにデプロイメントAPI名 - /pop/v5/changeorder/co_deployを渡します。

```
request.set_uri_pattern('/pop/v5/changeorder/co_deploy')
```

#実行とテスト
Githubに変更をコミットした後のリアルタイムデプロイのデモを行う前に、まず以下のチェックを通過していることを確認しておきましょう。

1、EDASアプリケーションがインターネット経由でアクセス可能であること - [http:// IP of EDAS host instance>:8080](https://www.alibabacloud.com/blog/automated-web-app-deployment-from-github-push-using-alibaba-cloud-edas_594687)

2、 Githubのwebhookが検証されていること


3、初めてJenkinsパイプラインプロジェクトのデプロイを手動でトリガーして、パイプラインがエラーなく実行されることを確認します。(エラーがパーミッション拒否によるものである場合は、以下のコマンドを実行してください)


```
sudo chmod 755 /var/run/docker.sock

sudo gpasswd -a tomcat docker

newgrp docker
```

では、フォークされたgithubリポジトリをJenkinsホストのディレクトリにクローンしてみましょう。ここでは、GitHubというディレクトリにクローンされているとします。

- edas.cfgファイルを./GitHub/webapptest/jenkins/scriptsに更新します。
- ./GitHub/webapptest/JenkinsfileファイルをJenkinsホストにクローンされたpythonスクリプトの絶対パスで更新します。
- ウェブサイトのソースコードフォルダに移動してindex.jspを修正し、変更をgithubリポジトリにコミットします。
- ブラウザでJenkinsのパイプラインプロジェクトを開きます。すでにパイプラインプロジェクトのビルドが開始されているのがわかるはずです。プロジェクトの完全な実行を待ちます。
- ブラウザでEDASのWebURLを開き、Webサイトの変更が反映されているかどうかを確認します。

*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*