Technical Articles
Multi Target Applicationをproject “Piper”を用いGitブランチ毎に異なった環境へ自動デプロイする
本ブログではMulti Target Application(MTA)を開発する際に、project “Piper”で構築したCI/CDパイプラインを用いてブランチ毎に異なった設定で異なった環境へデプロイする方法をご紹介します。
読者の対象としてMTAをSAP BTP, Cloud Foundry runtimeへデプロイしたことがあり、かつproject “Piper”をGetting Startedレベルで触ったことがある方を想定しています。
イントロダクション
Gitを利用してソースコード管理を行っている場合、developブランチのソースコードが常にStaging環境にデプロイされていたりmainブランチにプッシュされたら自動でProduction環境にデプロイされるという様なフローを作成したい場合があります。また環境毎にデプロイ時の設定、例えば利用するデータベースの切り替えや利用するメモリのサイズ、インスタンスの数等も異なる値を設定する必要が出てきます。
これらを実現するためにMTA拡張記述子と、project “Piper”を利用して定義したCI/CDパイプラインを利用します。
MTA拡張記述子
MTA拡張記述子(MTA Extension Descriptor)とはmta.yamlで定義した情報を保管するデータが含まれるyamlファイルであり、.mtaext拡張子のファイルで定義されます。このファイルをMTAのビルド時やSAP BTP, Cloud Foundry runtimeへのデプロイ時に指定することでmta.yamlファイルで定義されている値を追加、上書きすることが出来ます。
より詳しい解説はこちらのブログをご参照下さい。
今回は各環境(dev, prod)毎に.mtaextファイルを用意し、DBの設定とSAP Cloud Application Programming Modelアプリケーションが利用するメモリサイズ、インスタンスの数を環境毎に異なる値を利用できるようにします。
project “Piper”
project “Piper”はJenkinsでCI/CDパイプラインを構築するためのライブラリを提供しており、JenkinsからMTAのビルドやSAP BTP, Cloud Foundry runtimeへのアプリケーションのデプロイを簡単に行えるようになります。今回はproject “Piper”でGitを利用しているSAP Cloud Application Programming Modelアプリケーションのビルドとデプロイを自動で行えるようにします。
**注意**
本ブログではproject “Piper”でデプロイまでを完結させていますが、SAP Cloud Transport Managementを利用する方がより簡潔に同じことを行える場合があります。
必要に応じてこちらのドキュメントもご参照下さい。
プロジェクト設定
今回は下図の様な非常にシンプルなSAP Cloud Application Programming Modelアプリケーションを題材に説明させて頂きます。
Project Overview
データベースにSAP HANA Cloudを利用するため”cds add hana”コマンドで各種設定を生成しています。
また、mta.yamlファイルに関しては”cds add mta”コマンドを利用し以下の様な設定を自動生成しています。
_schema-version: '3.1'
ID: sap_blog_sample_mta_project
version: 1.0.0
description: "A simple CAP project."
parameters:
enable-parallel-deployments: true
build-parameters:
before-all:
- builder: custom
commands:
- npm ci
- npx -p @sap/cds-dk cds build --production
modules:
# --------------------- SERVER MODULE ------------------------
- name: sap_blog_sample_mta_project-srv
# ------------------------------------------------------------
type: nodejs
path: gen/srv
parameters:
buildpack: nodejs_buildpack
build-parameters:
builder: npm-ci
requires:
# Resources extracted from CAP configuration
- name: sap_blog_sample_mta_project-db
provides:
- name: srv-api # required by consumers of CAP services (e.g. approuter)
properties:
srv-url: ${default-url}
# -------------------- SIDECAR MODULE ------------------------
- name: sap_blog_sample_mta_project-db-deployer
# ------------------------------------------------------------
type: hdb
path: gen/db
parameters:
buildpack: nodejs_buildpack
requires:
# 'hana' and 'xsuaa' resources extracted from CAP configuration
- name: sap_blog_sample_mta_project-db
resources:
# services extracted from CAP configuration
# 'service-plan' can be configured via 'cds.requires.<name>.vcap.plan'
# ------------------------------------------------------------
- name: sap_blog_sample_mta_project-db
# ------------------------------------------------------------
type: com.sap.xs.hdi-container
parameters:
service: hana # or 'hanatrial' on trial landscapes
service-plan: hdi-shared
properties:
hdi-service-name: ${service-name}
mta.yamlファイルからわかるように本サンプルアプリケーションはSAP Cloud Application Programming Modelアプリケーション本体(sap_blog_sample_mta_project-srv)とHDI-Container経由でDBにテーブル定義などをデプロイするDB Deployer(sap_blog_sample_mta_project-db-deployer)から構成されています。
通常mta.yamlのHDI-Container(sap_blog_sample_mta_project-db)の定義に利用するデータベースのIDを以下の様に設定する必要がありますが、後述する方法でこの値をmtaextファイル経由で渡すためここでは記述していません。
# ------------------------------------------------------------
- name: sap_blog_sample_mta_project-db
# ------------------------------------------------------------
type: com.sap.xs.hdi-container
parameters:
service: hana # or 'hanatrial' on trial landscapes
service-plan: hdi-shared
config:
database_id: "****database id****"
properties:
hdi-service-name: ${service-name}
また同様にSAP Cloud Application Programming Modelアプリケーション本体が利用するメモリサイズとインスタンスの数もここでは記述をしていません。
MTA拡張記述子の追加
開発環境向け、本番環境向けの2種類のMTA拡張記述子を追加していきます。開発環境向けは”dev.mtaext”、本番環境向けは”prod.mtaext”とし、プロジェクトのルートにファイルを作成して下さい。
dev.mtaextには以下を記述します。
_schema-version: '3.1'
ID: sap_blog_sample_mta_project_ext
extends: sap_blog_sample_mta_project
version: 1.0.0
modules:
- name: sap_blog_sample_mta_project-srv
parameters:
memory: 256M
instances: 1
resources:
- name: sap_blog_sample_mta_project-db
parameters:
config:
database_id: "database id for dev environment"
それぞれ”sap_blog_sample_mta_project-srv“と”sap_blog_sample_mta_project-db“の設定を拡張し、メモリサイズとインスタンスの数を設定するためのパラメータ、そしてデータベースのIDを設定しています。
prod.mtaextには以下を記述します。
_schema-version: '3.1'
ID: sap_blog_sample_mta_project_ext
extends: sap_blog_sample_mta_project
version: 1.0.0
modules:
- name: sap_blog_sample_mta_project-srv
parameters:
memory: 512M
instances: 2
resources:
- name: sap_blog_sample_mta_project-db
parameters:
config:
database_id: "database id for prod environment"
本番環境向けにはメモリサイズとインスタンスの数を増やし、開発環境とは異なるデータベースIDを指定します。
この時点で環境毎に設定を切り替えられるようになりました。
手動でデプロイする際は以下の様に通常通りビルドをし、cf deployコマンドデプロイする際に”-e”オプションで何れかのmtaextファイルを渡すことでmtaextファイルに記述された内容がmta.yamlファイルで記述された内容に追加、上書きされるようになります。(mbt buildコマンドの”–extensions”オプションでビルド時にmtaextファイルを渡すことも出来ます。)
mbt build
cf deploy mta_archives/sap_blog_sample_mta_project_1.0.0.mtar -e dev.mtaext
CI/CDパイプラインの設定
CI/CDを実現するツールであるJenkinsが参照する設定ファイルを記述していきます。
“cds add pipeline”コマンドで”Jenkinsfile”と”.pipeline/config.yml”ファイルを生成します。(手動での作成でも構いません)
Jenkinsfileは以下の様に記述します。
#!/usr/bin/env groovy
@Library('piper-lib-os') _
pipeline {
agent any
stages{
stage('prepare') {
steps {
checkout scm
setupCommonPipelineEnvironment script:this
}
}
stage('build') {
steps {
script {
mtaBuild script: this
}
}
}
stage('deploy') {
steps {
script {
switch(env.BRANCH_NAME) {
case "develop":
print "deploy to Develop env"
cloudFoundryDeploy(
script: this,
cfApiEndpoint: "API Endpoint of develop env",
cfOrg: "Organization name of develop env",
cfSpace: "Space name of develop env",
cfCredentialsId: '***',
mtaExtensionDescriptor: "dev.mtaext"
)
break
case "main":
print "deploy to Prod env"
cloudFoundryDeploy(
script: this,
cfApiEndpoint: "API Endpoint of prod env",
cfOrg: "Organization name of prod env",
cfSpace: "Space name of prod env",
cfCredentialsId: '***',
mtaExtensionDescriptor: "prod.mtaext"
)
break
}
}
}
}
}
}
“build”ステージでは”mtaBuild”を利用し通常通りMTAのビルドを行います。”deploy”ステージで”env.BRANCH_NAME”から現在のブランチ名を取得し、developブランチとmainブランチで処理を出し分けています。
develop、main、どちらの場合も”cloudFoundryDeploy”を利用しCloud Foundry環境へデプロイを行いますが、渡す引数が異なっています。MTA拡張記述子は”mtaExtensionDescriptor”で指定を行っておりdevelopブランチの場合”dev.mtaext”を、mainブランチの場合”prod.mtaext”を指定しています。
その他のパラメータに関しては”cloudFoundryDeploy”のドキュメントをご参照ください。
config.ymlファイルは以下の様に記述します。
### General project setup
general:
### Step-specific configuration
steps:
mtaBuild:
buildTarget: 'CF'
cloudFoundryDeploy:
deployTool: 'mtaDeployPlugin'
deployType: 'standard'
### Stage-specific configuration
stages:
今回はステージは二つしかない上に”mtaBuild”と”cloudFoundryDeploy”しか使っていないため設定は少なくなっています。
Jenkins設定
Jenkinsでの設定に関しては基本的にproject “Piper”の“Getting Started with Project “Piper”に記載されている手順と同じものになります。
Cx Serverの起動
下記コマンドでCx Serverを起動します。
docker run -it --rm -u $(id -u):$(id -g) -v "${PWD}":/cx-server/mount/ ppiper/cx-server-companion:latest init-cx-server
chmod +x ./cx-server
./cx-server start
パイプラインの設定
1. Cx Serverで起動したJenkinsにログインし、”新規ジョブ作成”(もしくは”New Item”)
2. Multibranch Pipelineを選択
4. プロジェクトのルートのJenkinsfileを利用していることを確認します
5. その他必要に応じて設定を行い、保存
動作確認
Gitリポジトリにmainとdevelopの二つのブランチを作りそれぞれのブランチで変更を加えます。その後Jenkinsの画面から”Scan Multibranch Pipeline Now”を選択すると変更のあったブランチに対して自動でビルドとデプロイが実行されます。
下図の様にエラーなく完了していることを確認し、対象の環境(dev/prod)で指定通りデプロイが完了していることを確認してください。
develop環境にデプロイされているアプリケーションを見ると、以下の様に1インスタンスで256MBのメモリが割り当てられていることがわかります。
production環境では以下の様に2インスタンスでそれぞれ512MBのメモリが割り当てられます。
まとめ
本ブログではMTA拡張記述子とproject “Piper”を用いブランチ毎に異なった環境に異なった設定でMTAをデプロイする方法をご紹介させて頂きました。
繰り返しになりますが、SAP Cloud Transport Managementを利用する方がより簡潔に同じことを行える場合があるので必要に応じてこちらのドキュメントもご参照下さい。