LoginSignup
19
7

More than 3 years have passed since last update.

お前らのCFデプロイはダサい

Last updated at Posted at 2019-12-20

これはよくある煽り系釣りタイトルみたいなものです。怒らないでください。
怒った方はごめんなさい。
(※ この記事は SAP Advent Calendar 2019 の12月21日分の記事としても執筆しています)

2020年2月追記
本記事をさらにアップグレードした、やはりお前らのCFデプロイはダサいを公開しました。

ダサいデプロイとは - パラダイムへの反骨

わたくし、お片づけが大好きな"片づけコンサルタント"でございます。
特に、心ときめくようなシンプル、かつモダンでイケてるシステムアーキテクチャを作ることに興奮を隠しきれません。

そんな片づけコンサルタントがSAP Cloud PlatformのCloud Foundry(CF)での開発で許せないことの一つに、MTAアプリケーションの手動ビルド、手動デプロイというプロセスがあります。

イチイチBuildボタンをポチポチしては、
image.png
完了までシバシバ待ち、
完了したらデプロイボタンを押してまたムクムク待ち…
image.png

時は令和です。
みなさん、こんなダサいことをしている場合ではございません。

今回はこんな、心ときめかない手動ビルド、手動デプロイというプロセスをブチコリと排除して、かわいく自動でビルド、デプロイを行ってくれるアーキテクチャを作ってスッキリしたDevOps※実行環境の構築を目指しましょう。

※DevOpsについてはこちら

それでは早速方法を見てみましょう。

理想的なアーキテクチャ -ユートピア

本来、SAP Cloud PlatformのCFで作られるべきDevOpsを実現するアーキテクチャは、だいたいこんな感じであるとわたくしは思っております。

image.png

あぁ・・・・//

失礼、取り乱してしまいました。
上記で何を行っているかといいますと、ざっくり以下のような感じです。

  • ローカル、もしくはNeo環境のWebIDEから、CF環境に置いたGitlabコンテナに対してMTAプロジェクトのプッシュ
  • GitlabへのプッシュをトリガーにしてJenkinsコンテナ内でMTAプロジェクトをビルド
  • MTAビルド時に、共通ライブラリをnexusコンテナから取得する
  • JenkinsからCFランタイム環境へMTAアプリケーションをデプロイ
  • JenkinsからGitlabへ.mtarファイルをプッシュし、.mtarファイルをCTS+にて各CF環境へ配備

あぁ、なんと美しいのでしょう。
これにて手動のビルド、デプロイや移送などというダサい作業からは解脱できるのです。

ですが
こちらは2019年現在実現できません。。
何故なら、現在SAP Cloud PlatformのCF環境にはストレージサービス(NFS)が存在しないのです!
そのため、JenkinsやGitlabなどのコンテナを立てることはできても、開発オブジェクトやユーザ情報、コンフィグなどを永続化させることができず、コンテナの再起動がかかる度に消えてしまうのです。。

そのことを知った時、私は途方に暮れました。
悔しくて夜も眠れず、朝も起きられませんでした。

しかし!
そんな私を救ってくれたのがAzure DevOpsだったのです!!

2020年2月追記
Cloud Foundry環境にコンテナを立ててDevOpsを実現することがベストプラクティスだと悦に入っていましたが、現時点ではAzure DevOpsの方が断然楽にDevOpsを実現できて良いです。
完全に寝返ってしまいました。すいません。

Azure DevOpsの登場 -メシアの出現

image.png

このAzure DevOpsとは、Microsoft Azureの中の1サービスであり、GitやJenkinsのようなCI/CDツールとしての役割を包含したものです。
今回はこの、美しいサービスを利用してDevOpsを実現していくことにします!

前提プロジェクト -MTA

今回は、workshop1128というMTAプロジェクトの自動ビルド、自動デプロイを行っていきます。
その構成はこちらです。
image.png

MTAプロジェクトの下にJavaモジュール、UI5モジュール、hdiモジュールを作成した形です。
もう少し詳しく見るためにmta.yamlを添えておきます。

mta.yaml
ID: workshop1128
_schema-version: '2.1'
parameters:
  deploy_mode: html5-repo
version: 0.0.1
modules:
  - name: workshop1128_appRouter
    type: approuter.nodejs
    path: workshop1128_appRouter
    parameters:
      disk-quota: 256M
      memory: 256M
    requires:
      - name: workshop1128_html5_repo_runtime
      - name: uaa_workshop1128
  - name: workshop1128_ui_deployer
    type: com.sap.html5.application-content
    path: workshop1128_ui_deployer
    requires:
      - name: workshop1128_html5_repo_host
    build-parameters:
      requires:
        - name: workshop1128ui5
          artifacts:
            - './*'
          target-path: resources/workshop1128ui5
  - name: hdi1128
    type: hdb
    path: hdi1128
    requires:
      - name: hdi_hdi1128
  - name: workshop1128java
    type: java
    path: workshop1128java
    parameters:
      memory: 1024M
    provides:
      - name: workshop1128java_api
        properties:
          url: '${default-url}'
    requires:
      - name: ls_tokyo-connectivity
      - name: dest_workshop1128
      - name: uaa_workshop1128
      - name: hdi_hdi1128
        properties:
          JBP_CONFIG_RESOURCE_CONFIGURATION: '[tomcat/webapps/ROOT/META-INF/context.xml: {"service_name_for_DefaultDB" : "~{hdi-container-name}"}]'
  - name: workshop1128ui5
    type: html5
    path: workshop1128ui5
    build-parameters:
      builder: grunt
      supported-platforms: []
      build-result: dist
resources:
  - name: workshop1128_html5_repo_runtime
    parameters:
      service-plan: app-runtime
      service: html5-apps-repo
    type: org.cloudfoundry.managed-service
  - name: workshop1128_html5_repo_host
    parameters:
      service-plan: app-host
      service: html5-apps-repo
    type: org.cloudfoundry.managed-service
  - name: hdi_hdi1128
    parameters:
      config:
        schema: sawayaka
    properties:
      hdi-container-name: '${service-name}'
    type: com.sap.xs.hdi-container
  - name: uaa_workshop1128
    parameters:
      path: ./xs-security.json
      service-plan: application
      service: xsuaa
    type: org.cloudfoundry.managed-service
  - name: dest_workshop1128
    parameters:
      service-plan: lite
      service: destination
    type: org.cloudfoundry.managed-service
  - name: ls_tokyo-connectivity
    parameters:
      service-plan: lite
      service: connectivity
    type: org.cloudfoundry.existing-service

Azure DevOpsをさわってみよう -初体験

ということで早速上記で用意したMTAプロジェクトをAzure DevOpsでブチコリと料理する方法をご紹介しましょう。

Gitリポジトリの利用

まずはAzure DevOpsのGitサービスであるReposから新しいRepositoryを作成していきます。

image.png

元々GitにあるオブジェクトをCloneしてくることが出来るので、既にSAP Cloud Platformで利用しているGitリポジトリを入力すればOKです。

image.png

そうするとこのような形で先ほどのworkshop1128プロジェクトをAzure DevOps上に持ってくることができます。

もし継続してAzure DevOpsを使う場合は、こちらのリポジトリをリモートリポジトリとして使用すれば、後述するCI/CDパイプラインをGitへのプッシュをトリガにして実行することも可能です。

image.png

CI/CDツールとしてのパイプライン構築

メインとなる自動ビルド、自動デプロイを実行する、パイプラインの構築を行っていきます。
まずはPipelinesを選択します。

image.png

New build pipelineを選択して新規パイプラインを作成します。

image.png

パイプラインで扱うプロジェクトを、先ほどのAzure DevOpsのGitから持ってきます。
他にもGithubやBitbucketがあり、SAP Cloud PlatformのGitサービスも選択できるように見えていますが、パイプラインを自由に定義できなくなってしまうので、Azure DevOpsのGitを使うのが良いかと思います。

image.png

先ほど移したworkshop1128プロジェクトを選択する。

image.png

ここからパイプラインの定義をしていきます。
様々な言語でビルド、デプロイを行うためのテンプレートyamlが用意されていますが、MTAのテンプレートは用意されていないので、今回はNode.jsのテンプレートを暫定的に選択して中身を入れ替えることにします。

image.png

このNode.jsのために書かれたazure-pipeline.yamlを以下のように書き換えてください。
image.png

azure-pipelines.yml
# Starter pipeline

name: sawayaka-mta-project
resources:
  containers:
  - container: mta
    image: 'ppiper/mta-archive-builder:latest'
    options: --user 0:0
  - container: cfcli
    image: 'ppiper/cf-cli'
    options: --user 0:0 --privileged
  - container: node
    image: 'geekykaran/headless-chrome-node-docker:latest'
    options: --privileged


trigger:
- master


stages:
- stage: build
  displayName: Build MTA for SAP Cloud Platform
  jobs:
    - job: build
      pool:
        vmImage: 'ubuntu-latest'
      container: mta
      steps:
        - bash: 'mtaBuild --build-target CF --mtar MySampleApp.mtar build'
        - publish: $(System.DefaultWorkingDirectory)/.
          artifact: WebApp


- stage: deploy
  displayName: Deployment to SAP Cloud Platform (cf)
  jobs:
    - job: deploy
      pool:
        vmImage: 'ubuntu-latest'
      container: cfcli
      steps:
        - download: current
          artifact: WebApp
        - bash: 'cf login -u "$(CF-USER)" -p "$(CF-PASSWORD)" -a "$(CF-API)" -o "$(CF-ORG)" -s "$(CF-SPACE)" && cf deploy $(Pipeline.Workspace)/WebApp/MySampleApp.mtar -f'

この中でMTAプロジェクトのビルド、デプロイを定義しています。
デプロイに必要な環境情報などは、セキュリティの観点から変数化して渡してあげます。
Variablesを開くと、keyとvalueの形で変数化することが可能であるとわかります。
image.png

image.png

必要なのは、CF-API, CF-ORG, CF-PASSWORD, CF-SPACE, CF-USERです。
それぞれに、APIエンドポイント(https://api.cf.eu10.hana.ondemand.com など)、サブアカウント名、CFログインパスワード、スペース名、ログインユーザを定義すればよいです。

image.png

ここまでできれば後は実行するだけです。

image.png

対象となるGitブランチを選択します。
たったこれだけでお片づけが完了です。スッキリ☆
image.png

他の開発でもしながら放っておいている内に、勝手にビルド、デプロイが成功しております。成功すると赤枠のように緑色のバッチが付きます。
image.png

中身を見てみると、ビルド、デプロイの過程で出力されたログも見られます。
この辺りはCF-CLIで操作した時とほとんど変わらないログが吐かれているはずです。
image.png
image.png

実際に、CF環境を見てみるとworkshop1128の中にあるモジュールたちがちゃんとデプロイされていることがわかります。
なんて素敵なんでしょう・・//
image.png

おわりに -ココロトキメク

いかがでしたか?
意外と簡単にDevOps環境って構築できると思えたのではないでしょうか?
今後はテストコードの実行などもパイプライン上で行うことで、よりCI/CDの概念に近づけたり、Ansibleのようなサービスを使って構成管理を実現することがしたいですね☆

みなさまココロトキメク開発ライフを楽しみましょう~

19
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
7