Database Cloud ServiceとJava Cloud Serviceをオーケストレーションし自動生成してみた


# 概要
Database Cloud ServiceやJava Cloud Serviceのインスタンスをコマンドライン・ベース(PSM CLI)で作成を行いました。

- [Oracle Cloudのコマンドライン・インターフェース(CLI)を使えるようにしてみた](http://qiita.com/shinyay/items/a3773b37fdbb677e52b1)
- [Database Cloud ServiceのインスタンスをPSM CLIで作成してみた](http://qiita.com/shinyay/items/e6e0c038090039dabb18)
- [Java Cloud ServiceのインスタンスをPSM CLIで作成してみた](http://qiita.com/shinyay/items/f106463d656401ced368)
- [Java Cloud ServiceにWebLogic マルチテナント・インスタンスをPSM CLIで作成してみた](http://qiita.com/shinyay/items/e20d87de881128d8ecd8)

それぞれのインスタンスを作成する時には、それぞれのPSM CLIのコマンドを利用して、それぞれのJSONファイルを利用しました。

![psm-stack_01.png](https://qiita-image-store.s3.amazonaws.com/0/127983/58bc9062-dc1f-c22b-9a0d-5faf538adc4c.png)

1. **psm dbcs**コマンドでDatabase Cloud Serviceのインスタンスとそのバックアップ用のStorage Cloud Service上にコンテナの作成
2. **psm jcs**コマンドでJava Cloud Serviceのインスタンスとそのバックアップ用のStorage Cloud Service上にコンテナの作成、そしてDatabase Cloud Serviceインスタンスへのデータソース作成

このようにそれぞれのインスタンス生成コマンドでそれぞれのインスタンス構成ペイロード(JSONファイル)を作成して使用しました。

また、**psm jcs**でJava Cloud Service インスタンスを作成する前提として、必ずDatabase Cloud Serviceインスタンスを事前に作成しておく必要があります。
そのため、**psm dbcs**や、ブラウザベースGUIにより別途作成操作が必要になります。
既にDB環境を構成済みの場合は、構成済みDBを利用できるので**psm jcs**のみで済みます。一方で、初めてJava Cloud Service環境を作成する場合は「Storage Cloud Service」にバックアップ用コンテナを作成した後、「Database Cloud Service」でインスタンスを作成し、「Java Cloud Serive」インスタンスを作成するという手順になります。

このように、Oracle Cloud Serviceのインスタンスによっては、依存関係があり前提となるOracle Cloud Seriviceインスタンスがないと作成できない場合があります。

![psm-stack_02.png](https://qiita-image-store.s3.amazonaws.com/0/127983/b0756d42-11e8-7cbe-68f3-cc15ae2992de.png)

このような依存関係も考慮してOrace Cloud Serviceを組み合わせた構成パターンとして環境を作成する方法が**Oracle Cloud Stack Manager**です。

# Oracle Cloud Stack Manager
Oracle Cloud Sack Managerとは、複数のOracle Cloud Serviceを**Cloud Stack**という単位にまとめて管理する仕組みです。
例えば、JCSインスタンス1つに対して、アプリケーションが使用するDBを分離するようにDBCSインスタンスを2つ構成する、というようなパターンがあるとします。
このパターン、統合した複数のOracle Cloud Serviceを1つの**Cloud Stack**として取り扱います。

![psm-stack_03.png](https://qiita-image-store.s3.amazonaws.com/0/127983/3368cb06-ec2a-b550-1f87-e0625c76f490.png)

このCloud Sackは**Template**から生成します。
TemplateはYAMLフォーマットで作成します。

## Cloud Srack Template
Templateには、以下の内容が含まれます。

|構成要素|内容|
|---|---|
|Resource|Oracle Cloud Serviceが提供するクラウド・サービス|
|Parameter|Resourceを構成する要素(ユーザが静的に設定)|
|Attribute|Resourceを構成する要素(インスタンス作成時に動的に設定)|

YAMLフォーマットで作成しますが、上記内容を踏まえた記載は以下のようになります。

```yaml
---
  Template定義
    Template Parameters (Optional)
    Resources
    Resource定義
      Resource Parameters
    Resource定義
      Resource Parameters
    Template Attributes (Optional)
```
YAMLの前半でテンプレートとして使用する変数の属性を定義します。ここで定義した変数を実行時にコマンド引数として割り当てます。

YAMLの後半ではリソースを定義しています。リソースとは、例えばJava Clous ServiceのようなOracle Cloud Serviceの提供するクラウド・サービスです。
PSM CLIを使用した際に定義したインスタンス構成ペイロードJSONファイルのように変数を定義していきます。属性値は、テンプレートで定義している内容を取得できます。

**depends_on**で定義する属性が、Resourceに対する依存関係です。
この依存関係で指定されているResourceが先に作成されるように動作します。

## Cloud Stack Manager 使用方法概要
Cloud Stack Managerは、大きく分けて２つの操作があります、

- Cloud Templateの管理
- Cloud Stackの管理

### Cloud Templateの管理
PSM CLIで以下のコマンドが用意されています。

|PSM CLIコマンド|内容|
|---|---|
|psm stack validate-template|Cloud Template YAMLファイルのインポート事前妥当性チェック|
|psm stack import-template|Cloud Templateのインポート|
|psm stack list-templates|インポート済みのCloud Template一覧表示|
|psm stack describe-template|インポート済みのCloud Template詳細表示|
|psm stack export-template|Cloud Templateのエクスポート|
|psm stack delete-template|インポート済みCloud Templateの削除|

#### 1. 妥当性チェック
Cloud Templatetをインポートするには、事前に妥当性確認を行う必用があります。

コマンド・シンタックスは以下のようになります。

```bash
psm stack validate-template -f filePath -p param1:value1 param2:value2 ... paramN:valueN
```
- **-f**: Stack Template YAMLファイルへのパス

#### 2. テンプレートのインポート
Cloud Templateをインポートします。

コマンド・シンタックスは以下のようになります。

```bash
psm stack import-template -f filePath 
```

#### 3. テンプレートの確認
インポートできたテンプレートは以下のコマンドで確認します。

```bash
psm stack list-templates
```

### Cloud Stackの管理
PSM CLIで以下のコマンドが用意されています。

|PSM CLIコマンド|内容|
|---|---|
|psm stack create|Cloud Stackを作成|
|psm stack list|Cloud Stackの一覧表示|
|psm stack describe|Cloud Stackの詳細表示|
|psm stack delete|Cloud Stackの削除|
|psm stack operation-status|作成中の状況表示

#### Cloud Stackの作成
インポートしたCloud Templateを指定して、Cloud Templateを作成します。

```bash
psm stack create -n name -d description -t template -f RETAIN|ROLLBACK -p param1:value1 param2:value2 ... paramN:valueN
```

- **-n**: Cloud Stack名
- **-t**: Clout Template名
- **-f**: 失敗時の挙動
    - RETAIN: 維持
    - ROLLBACK: ロールバック

## Cloud Stack作成例
Cloud Stackを作成してみます。
構成はシンプルにJCSインスタンスとDBCSインスタンスを1つずつ用意し、それぞれのバックアップ用コンテナを構成するCloud Stackとします。

![psm-stack_04.png](https://qiita-image-store.s3.amazonaws.com/0/127983/b01e40f7-7d92-0ce5-d582-4dd18412fa48.png)

### Stack Template 作成例
以下のようなStack Templateを作成しました。

- JCSandDBCS.yaml

```yaml
---
  template: 
    templateName: JCSandDBCS
    templateVersion: 1.0.1
    templateDescription: Stack template for a Weblogic 12.2 installation against an Oracle database 12.1 with cloud backup.
    parameters: 
      wlAdminUser: 
        label: Weblogic Admin username
        description: Weblogic Admin username
        type: String
        default: weblogic
      wlAdminPwd: 
        label: Weblogic Admin password
        description: Weblogic Admin console password
        type: String
        mandatory: true
        sensitive: true
      dbPwd: 
        label: Database access password
        description: Database access password
        type: String
        mandatory: true
        sensitive: true
      publicKeyText: 
        label: Public key text
        description: Public key text for accessing the provisioned vms
        type: String
        mandatory: true
        sensitive: true
      backupStorageContainer: 
        label: Backup container
        description: Eg., Storage-IDDomain/Container_Stack
        type: String
        mandatory: true
      cloudStorageUser: 
        label: Cloud Storage user name
        description: Storage account username
        type: String
        mandatory: true
      cloudStoragePassword: 
        label: Cloud Storage password
        description: Storage account password
        type: String
        mandatory: true
        sensitive: true
      subscriptionType: 
        label: Subscription type
        description: The subscription type
        type: String
        default: HOURLY
      computeShape: 
        label: Default compute shape
        description: compute shape for each of the resource nodes
        type: String
        default: oc3
    resources: 
      backupContainer: 
        type: OSS.Container
        parameters: 
          cloudStorageContainer: 
            Fn::GetParam: backupStorageContainer
          cloudStorageUser: 
            Fn::GetParam: cloudStorageUser
          cloudStoragePassword: 
            Fn::GetParam: cloudStoragePassword
      JCS: 
        type: jaas
        parameters: 
          serviceName: 
            Fn::Join: 
              - "-"
              - 
                - 
                  Fn::GetParam: serviceName
                - JAAS
          cloudStorageContainer: 
            Fn::GetParam: backupStorageContainer
          cloudStorageUser: 
            Fn::GetParam: cloudStorageUser
          cloudStoragePassword: 
            Fn::GetParam: cloudStoragePassword
          trial: false
          parameters: 
            - 
              VMsPublicKey: 
                Fn::GetParam: publicKeyText
              adminUserName: 
                Fn::GetParam: wlAdminUser
              adminPassword: 
                Fn::GetParam: wlAdminPwd
              dbServiceName: 
                Fn::GetAtt: 
                  - DBCS
                  - serviceName
              dbaName: sys
              dbaPassword: 
                Fn::GetParam: dbPwd
              shape: 
                Fn::GetParam: computeShape
              type: weblogic
              version: 12.2.1.0.1
            - 
              VMsPublicKey: 
                Fn::GetParam: publicKeyText
              haEnabled: true
              keepAlive: true
              shape: 
                Fn::GetParam: computeShape
              type: OTD
        depends_on: 
          - backupContainer
      DBCS: 
        type: dbaas
        parameters: 
          serviceName: 
            Fn::Join: 
              - "-"
              - 
                - 
                  Fn::GetParam: serviceName
                - DBAAS
          version: 12.1.0.2
          level: PAAS
          edition: EE
          subscriptionType: 
            Fn::GetParam: subscriptionType
          description: DB Service
          shape: 
            Fn::GetParam: computeShape
          vmPublicKeyText: 
            Fn::GetParam: publicKeyText
          parameters: 
            - 
              type: db
              usableStorage: 15
              adminPassword: 
                Fn::GetParam: dbPwd
              sid: ORCL
              failoverDatabase: no
              backupDestination: BOTH
              cloudStorageContainer: 
                Fn::GetParam: backupStorageContainer
              cloudStorageUser: 
                Fn::GetParam: cloudStorageUser
              cloudStoragePwd: 
                Fn::GetParam: cloudStoragePassword
        depends_on: 
          - backupContainer
```

### 妥当性チェック

```bash
$ psm stack validate-template -f ./JCSandDBCS.yaml -p ...
```

```json
{
    "details":{
        "message":"Validation completed. No errors found"
    }
}
```

### テンプレートのインポート

```bash
$ psm stack import-template -f ./JCSandDBCS.yaml
```

```json
{
    "templateName":"JCSandDBCS",
    "latestVersion":"1.0.1",
    "description":"Stack template for a Weblogic 12.2 installation against an Oracle database 12.1 with cloud backup.",
    "createdOn":"2016-09-20T06:36:16.006+0000",
    "createdBy":"shinyay",
    "links":[
        {
            "rel":"canonical",
            "href":"https://psm.europe.oraclecloud.com:443/paas/api/v1.1/instancemgmt/plprivatee/templates/cst/instances/JCSandDBCS"
        },
        {
            "rel":"self",
            "href":"https://psm.europe.oraclecloud.com:443/paas/api/v1.1/instancemgmt/plprivatee/templates/cst/instances"
        }
    ]
}
```

### Cloud Stackの作成
AppDevという名前でCloud Stackを作成します。

```bash
$ psm stack create -n AppDev -t JCSandDBCS -p ...
```

```yaml
{
    "details":{
        "message":"Submitted job to create stack [AppDev] in domain [plprivatee].",
        "jobId":"2218634"
    }
}
```

### Cloud Stack作成確認
```bash
$ psm stack operation-status -j 2218634
```

```json
{
    "activityLogId":1120673,
    "serviceName":"AppDev",
    "serviceType":"cloudstack",
    "identityDomain":"IDDOMAIN",
    "serviceId":59390,
    "jobId":2218634,
    "startDate":"2016-09-20T06:54:11.974+0000",
    "endDate":"2016-09-20T07:39:56.394+0000",
    "status":"SUCCEED",
    "operationId":59390,
    "operationType":"CREATE_SERVICE",
    "summaryMessage":"CREATE_SERVICE",
    "authDomain":"IDDOMAIN",
    "authUser":"shinyay",
    "initiatedBy":"USER",
    "messages":[
        {
            "activityDate":"2016-09-20T06:54:11.974+0000",
            "message":"Stack creation request accepted"
        },
        {
            "activityDate":"2016-09-20T06:54:11.981+0000",
            "message":"Initializing stack AppDev"
        },
        {
            "activityDate":"2016-09-20T06:54:12.820+0000",
            "message":"Preparing to create service AppDev-DBAAS"
        },
        {
            "activityDate":"2016-09-20T06:54:18.521+0000",
            "message":"Request submitted to create service AppDev-DBAAS"
        },
        {
            "activityDate":"2016-09-20T07:20:19.399+0000",
            "message":"Successfully created service AppDev-DBAAS"
        },
        {
            "activityDate":"2016-09-20T07:20:19.560+0000",
            "message":"Preparing to create service AppDev-JAAS"
        },
        {
            "activityDate":"2016-09-20T07:20:29.534+0000",
            "message":"Request submitted to create service AppDev-JAAS"
        },
        {
            "activityDate":"2016-09-20T07:39:55.837+0000",
            "message":"Successfully created service AppDev-JAAS"
        },
        {
            "activityDate":"2016-09-20T07:39:56.394+0000",
            "message":"Stack AppDev configured"
        }
    ]
}
```

# まとめ
Oracle Cloud Stack Managerを利用するとクラウド・サービス単位ではなく、クラウド・システム構成単位としてオーケストレーションされた環境が出来上がります。また、Stack Templateは一度作成すると、別のデータセンターでも再利用できます。
この機能により、Oracle Cloud Service上で Immutable Infrastructureとして、いつでも、どこでも同じ環境を手軽に構成する事が可能になります。