Oracle Cloud Stack Manager を使用して Application Container Cloud Service と MySQL Cloud Service を自動プロビジョニングしてみた


![](https://raw.githubusercontent.com/shinyay/oracle-stack-accs-mysqlcs/1.0.0/docs/images/accs_with_mysql.png)

[「Application Container Cloud Service から MySQL Cloud Service へバインドしてみた」](http://qiita.com/shinyay/items/62b810609e3d661a108f) では、個別に構成した **Application Container Cloud Servcie** と **MySQL Cloud Service** をサービスバインディングを使用して連携しました。

これは、Oralce Cloud の機能である **Cloud Stack Manager** を用いて、自動で複数のクラウド・サービスを単体ユニットの **クラウド・スタック** という単位でプロビジョニングします。

## 説明
**Oracle Cloud Stack Manager** はクラウド・スタックという単位で複数のクラウド・サービスを管理し、自動でプロビジョニングする機能です。

### Cloud Stack Manager テンプレートを構成するコンポーネント
複数のクラウド・サービスをクラウド・スタックとして構成し管理する ***Cloud Stack Manager*** ですが、構成情報は **YAML** で定義します。構成する情報は、**Cloud Stack Manager テンプレート** として作成し、以下のコンポーネントを含むように構成します:

- **Resources**    (リソース)
- **Parameters**   (パラメータ)
- **Attributes**   (属性)
- **Dependencies** (依存関係)

#### 1. リソース
- **プロビジョニングする Oracle Cloud のリソース** を定義
  - (スタックに組み入れるクラウド・サービスの定義)

リソース定義には以下の要素が含まれます:
- **リソースの作成時に使用されるタイプ**
  - (以下に17/03/31 時点で使用できる一覧を掲載)
- **一意のID**
- **説明(オプション)**
- **パラメータ**

|リソース・タイプ|説明|
|---|---|
|**`apaas`**|**Application Container Cloud Service** 内のアプリケーション|
|**`bdcsce`**|**Big Data Cloud Service - Compute Edition** 内のサービスインスタンス|
|**`dbaas`**|**Database Cloud Service** 内のデータベース・デプロイメント|
|**`jaas`**|**Java Cloud Service** 内のサービス・インスタンス|
|**`MySQLCS`**|**MySQL Cloud Service** 内のサービス・インスタンス|
|**`OEHCS`**|**Event Hub Cloud Service** 内のサービス・インスタンス|
|**`OEHPCS`**|**Event Hub Cloud Service** 内のプラットフォーム・インスタンス|
|**`OSS.Container`**|**Storage Cloud Service** 内のストレージ・コンテナ|

#### 2. パラメータ
- **クラウド・サービスを構成するための設定値** を定義

##### 2.1 テンプレート・パラメータ
- テンプレート・ノードに対して定義するパラメータ

Cloud Stack Manager に対して入力するパラメータ:
- PSM CLI のパラメータ引数として入力
- Cloud Stack Manager 画面から入力

###### 2.1.1 テンプレート・パラメータ例
- ユーザ名
- パスワード
- コンピュート・シェイプ

定義時に必要な情報は以下の内容:
- 名前
- データ型 (テキスト / 数値 / ブール / SSH鍵)
- パラメータ必須要否
  - パラメータ・デフォルト値

##### 2.2 リソース・パラメータ
- 各リソース・ノードに対して定義するパラメータ

各リソース (各クラウド・サービス) が **REST API** で定義しているパラメータ

###### 2.2.1 リソース・パラメータ例
Application Container Cloud Serivce の場合:

- name
- runtime
- subscription
- archiveURL
- deployment
  - memory
  - instances

*JSON の階層構造をインデントにより表現可能*

#### 3. リソース属性
- **プロビジョニングの過程で生成されるパラメータ値** を設定

**`GetAtt`** 関数を使用してランタイム属性の値を取得

###### 3.1. リソース属性例
`HRDatabase` としてい定義されているリソースの *リソース・パラメータ* : `serviceName` を取得

```
dbServiceName:
  Fn::GetAtt: [HRDatabase, serviceName]
```

構成されたクラウド・サービス・インスタンスに対して REST API を使用してインスタンス情報を参照すると、設定済みの各種パラメータが確認できます:

- 例: Java Cloud Service の Coherence 使用時

```
"options": [{
  "type": "datagrid",
  "clusters": [{
    "clusterName": "ExampleI_DGCluster",
    "scalingUnitCount": 4,
    "scalingUnitName": "BASIC",
    "shape": "oc3",
```

以下のリソース属性は、`HRWeb` として定義されたJava Cloud Service の Coherence のコンピュート・シェイプを取得

```
shape:
  Fn::GetAtt: [HRWeb, options.clusters.shape]
```

#### 4. 依存関係
- **プロビジョニングする順番を決定** するために使用
  - 依存するリソースが作成された後に、依存関係を定義したリソースが作成される
  - 依存関係がないリソースは、 **並行に作成を実施** する

```
<リソース名>:
    :
  depends_on:
    - <依存するリソース名>
```

### 今回使用している Stack Manager テンプレート
```
---
  template:
    templateName: Pokemon-Stack-Template
    templateVersion: 1.0.0
    templateDescription: Stack for ACCS with MySQLCS
    parameters:
      mySQLPwd:
        label: MySQL Admin Password
        description: Password for MySQL Administrator
        type: String
        mandatory: false
        default: P@ssw0rd
        sensitive: true
      PokemonAppJavaURL:
        label: Pokemon Java App Archive URL
        description: Pokemon App Location in Storage Congtainer
        type: String
        mandatory: false
        default: ACCS/mysql-connect-1.0.1-SNAPSHOT.zip
      publicKeyText:
        label: Public Key Text
        description: Public Key Text for Accessing the provisioned vms
        type: ssh
        mandatory: true
        sensitive: true
    resources:
      PokemonMySQL:
        type: MySQLCS
        parameters:
             serviceParameters:
                serviceName: PokemonDB
                serviceLevel: PAAS
                subscription: HOURLY
                serviceDescription: Database for Pokemon Data
                serviceVersion: 5.7
                vmPublicKeyText:
                    Fn::GetParam: publicKeyText
                backupDestination: NONE
             componentParameters:
                mysql:
                  shape: oc3
                  mysqlUserName: root
                  mysqlUserPassword:
                    Fn::GetParam: mySQLPwd
      PokemonAppJava:
        type: apaas
        parameters:
            name: PokemonApp
            runtime: java
            subscription: MONTHLY
            archiveURL:
                Fn::GetParam: PokemonAppJavaURL
            deployment:
                memory: 1G
                instances: 2
                services:
                      -
                        identifier: PokemonDBBinding
                        name:
                          Fn::GetAtt:
                            - PokemonMySQL
                            - serviceName
                        type: MySQLCS
                        username: root
                        password:
                          Fn::GetParam: mySQLPwd
        depends_on:
            - PokemonMySQL
```

## 動作イメージ

以下の動作イメージは、PSM CLI を使用して Stack Manager テンプレートの検証から Cloud Stack の作成までを実施するものです:

![](https://raw.githubusercontent.com/shinyay/oracle-stack-accs-mysqlcs/1.0.0/docs/images/stack-for-accs-mysqlcs.gif)


## 使用前提
- PaaS Service Manager Command Line (psm cli) の導入
  - [Downloading the Command Line Interface](https://docs.oracle.com/en/cloud/paas/java-cloud/pscli/downloading-command-line-interface.html)
  - [Oracle Cloudのコマンドライン・インターフェース(CLI)を使えるようにしてみた](http://qiita.com/shinyay/items/a3773b37fdbb677e52b1)

## Cloud Stack 作成方法（今回のサンプルを例に）
### 1. Stack Managet テンプレートのシンタックス検証

- **psm stack validate-template -f [Stack Template]**
  - psm stack validate-template -f pokemon-stack.yaml

### 2. Stack Managet テンプレートのインポート
Cloud Stack Managr に Stack Manager テンプレートをインポートします

- **psm stack import-template -f [Stack Template]**
  - psm stack import-template -f pokemon-stack.yaml

### 3. Cloud Stack の作成
Stack Manager テンプレートから Cloud Stack を作成します。テンプレート・パラメータで定義している内容を入力します。

- **psm stack create -n [Stack Name] -t [Stack Template Name] -d [Description] -p [Parameter KEY:VALUE]**
  - psm stack create -n PokemonAppStack -t Pokemon-Stack -d "Pokemon Encyclopedia App Stack" -p publicKeyText:"`cat ~/.ssh/id_rsa.pub`"

## まとめ
Cloud Stack Manager を使用すると、複数のクラウド・サービスのプロビジョニングが自動で一括して行えます。個別に作成する場合は、作成待ち時間が発生してしまいますが、この機能を利用すると作成要求を出すと完了まで手放しで待つのみなので非常に便利です。