[Oracle Cloud] Boot Volume Backup を、Events と Oracle Functions をつかって自動的に他リージョンへコピーする

# はじめに

Oracle Cloud Infrastructure(以下OCI) では、Compute Instance という名前のコンピュートサービスを提供しています。ベアメタル、仮想マシン、HPC、GPU など様々なユースケースを満たせるようなサービスとなっています。Compute Instance には定期バックアップの機能があり、同一のリージョン内で定期的にバックアップを行ってくれます。地域の大規模災害を考えると、普段使用しているリージョンから他のリージョンへバックアップをコピーしたいです。他リージョンにコピーする機能はありますが、手動のコピーとなっています。Oracle Functions の FaaS を活用することで、自動的にコピーが可能です。

今回の記事では、自動的に Boot Volume の Backup を他リージョンへコピーする方法を紹介します。

**注意点 : 今回の記事で紹介するプログラムを、商用環境に使うのはかなり厳しい条件があります。他リージョンへのコピー機能は、同時に1コピーしか実行することが出来ません。同時に2以上のリージョンコピーを実行すると、上限に引っかかりエラーが発生します。つまり、同じ時間帯に複数の Compute Instance が Boot Volume Backup を行う環境では使用することが出来ません。今回紹介した サンプルプログラムを改良して、複数のコピーを直列に順繰り処理を行うアーキテクチャが必要です。Streaming や DBMS を使用してキューを管理する必要があると思います。**



# 概要図

![1579397429621.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/7c134fc6-090a-18cf-3413-79e5b95c4379.png)



# Function の 設定

## Function Deploy

まず、Functions を動かす準備が出来ていない場合は、以下の Document や Quick Start Guide を参考にして、事前準備をします。
Preparing for Oracle Functions
https://docs.cloud.oracle.com/iaas/Content/Functions/Concepts/functionsprerequisites.htm

Quick Start Guide
https://www.oracle.com/webfolder/technetwork/tutorials/infographics/oci_faas_gettingstarted_quickview/functions_quickview_top/functions_quickview/index.html

Functions を動かす準備が出来たら、GitHub から Sample コードをclone します

https://github.com/Sugi275/oci-bootvolumebackup-multicopy

```
# 作業用ディレクトリ作成
mkdir ~/fnwork/
cd ~/fnwork/

# GitHub から clone
git clone https://github.com/Sugi275/oci-bootvolumebackup-multicopy.git
```



clone したディレクトリへ移動します

```
cd ~/fnwork/oci-bootvolumebackup-multicopy/
```

Functions へ multiregioner の function を Deploy します。`--app` に渡すアプリケーション名は環境によって書き換えてください

```
fn --verbose deploy --app susugiya
```



次に、Deploy した Functions の OCID をコピーします。

![1579400947203.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/ac7990f8-8276-0aa6-1be3-917338f52370.png)



## Function の 環境変数設定

Functions に環境変数を設定します。2種類の環境変数が必要です。

- OCI_SOURCE_REGION : Object Storage のコピー元のリージョン名を指定します。今回の例では、`ap-tokyo-1` としています
- OCI_DESTINATION_REGION : Object Storage のコピー先のリージョン名を指定します。現在の実装では1個しか指定できません。今回の例では、`us-ashburn-1` としています。

`serverlessdemo` と表示されている部分は、Oracle Functions のアプリケーション名なので、適宜環境に合わせて変更してください

```
fn config func serverlessdemo oci-bootvolumebackup-multicopy OCI_SOURCE_REGION "ap-tokyo-1"
fn config func serverlessdemo oci-bootvolumebackup-multicopy OCI_DESTINATION_REGION "us-ashburn-1"
```



設定値の確認

```
> fn ls config func serverlessdemo oci-bootvolumebackup-multicopy
KEY                     VALUE
OCI_DESTINATION_REGION  us-ashburn-1
OCI_SOURCE_REGION       ap-tokyo-1
```



## Function の logging

Functions では、logging として現段階は2種類の方式がサポートされています

- Object Storage へ出力
- syslog



開発環境としては、syslog を使用するのが楽で良いです。Object Storage の場合は、出力されるのに約15分ほど待つ必要があるため、すばやい log 確認が出来ません。syslog の場合はすぐに確認できるのでお勧めです。

syslog を受け取るために syslog サーバを用意してもよいのですが、開発する時には 無償で使用可能な SaaS の [Papertrail](https://papertrailapp.com/) が簡単でお勧めです。

Papertrail の設定方法は、[こちら](https://qiita.com/sugimount/items/590796840338170f62d8) の記事を参考にしてください。
なお、OCI コンソール上から Papertrail の送付先を設定・確認することが可能です。

Edit Application を選択

![1567003485810.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/1e861e7f-4bec-c122-df83-37ef0c0b9be0.png)


logging 先を設定変更

![1567003522717.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/59bf52b0-839c-bb1c-ad14-3aedbb217cf5.png)




# Dynamic Group

次に、Deploy した Function の権限設定を行います。OCI の Block Volume リソースのみ管理することが出来る設定を行います。Resource Principle 自体の説明は [こちら](https://qiita.com/sugimount/items/db84122d787af7208eb5) を参照してください

OCI のメニューから、Identity > Dynamic Groups へ移動し、 Create Dynamic Group を押します
以下のパラメータを入力し、Create を押します

- NAME : `sugi_bootvolbkup_multicopy`
- DESCRIPTIN : `sugi_bootvolbkup_multicopy`
- Rule に以下の文字列を入力します。`resource.id` の部分は、作成した Function の OCID を指定します。

```
ALL {resource.type = 'fnfunc', resource.id = 'ocid1.fnfunc.oc1.ap-tokyo-1.aaaaaaaaaamzyztlynryqexnrpqei3k2newclb6fmvcfzhv56kgiu7b6qxmq'}
```





# Policy

次に、作成した Dynamic Group に対して、アクセス可能なリソースの制限を Policy で指定します。

Identity > Policies へ移動し、 Create Policy を押します
以下のパラメータを入力し、Create を押します

- NAME : `bootvolumebackup_multicopy_policy`
- DESCRIPTION : `bootvolumebackup_multicopy_policy`
- STATEMENT : 以下の文字列で指定します。 Dynamic Group で作成した名前を指定して、`volume-family`(Block Volume サービス) を `manage`(全操作可能) な権限を付与しています。compartment 名の `suguru.sugiyama` は適宜環境に合わせて変更してください

```
Allow dynamic-group sugi_bootvolbkup_multicopy to manage volume-family in compartment suguru.sugiyama
```



# Events の 設定

次に、Tokyo Region の Boot Volume の Backup の終了をトリガーにして、Events を動かすための設定を行います。
OCI のメニューから、 Application Integration > Events Service を選択します。

Create Rule を押して、以下のパラメータを指定していきます

- DISPLAY NAME : `automatic boot volume backup copy to another region`
- DESCRIPTION : `automatic boot volume backup copy to another region`
- Events Matching : 下の画像を参考にして設定する
  - EVENT TYPE に `Block Volume` と、`Create Boot Volume Backup End` を選択
- Actions : Function の 名前を指定

![1579401834085.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/d5a0e0cf-85c9-100e-ca0a-5af641c0dd94.png)



# 動作確認

それでは準備完了できたので、さっそく動作確認をしてみます。エラーログや実行時のログは logging 先の Papertrail を確認すると、ほぼリアルタイムにログが表示されるので、これを開きながら動作確認すると良いです。

今回は手作業で、Boot Volume Backup を手動で作成します。

Boot Volumes の Create Manual Backup から適当に作成します。


![1579402242802.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/d55a4b1b-cab8-f862-5175-fac05e49d29f.png)


手動の Boot Volume Backup が Creating となっています。一定時間待つと Available になり、Oracle Functions がトリガーされて別リージョンへ Copy 処理が実行されます。

![1579402326377.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/d6d557c0-5852-37b3-24eb-a537efa45835.png)



Available になったあと、Ashburn Region の Boot Volume Backup を確認すると、同じ名前で Creating となっています。Tokyo Region で作成された Boot Volume Backup が自動的に他リージョンへコピーされていることが分かります。

![1579402486572.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/c4a59b0d-ee95-3c44-28a2-1d3ad51f6f09.png)



# 付録 : 今回の検証でわかった、Boot Volume Backup 他リージョンコピー機能の仕様

- コピー元で、Expiration が設定されていたら、コピー先でも設定される。コピー元リージョンでは、Backup Policy を使用してバックアップを行うのがほとんどだと思うので、そういったケースではOracle Functions で削除をハンドリングしなくとも、自動的に削除される。
- コピー元のリージョンで、増分バックアップのものを他リージョンへコピーすると、他リージョンでは Full バックアップになる (コピー先に既に Full バックアップがあったとしても、Fullになる)
- クロスリージョンコピーの並列度は 1 なので、2以上の並列コピーは出来ない。複数コピーを実行すると、以下エラーメッセージが返ってくる。同じタイミングで、コピーを実行した場合は、エラーになるので注意。キューの構造を作る必要がありそう。

```
2020-01-18T23:22:39.352Z        ERROR   oci-bootvolumebackup-multicopy/func.go:190      Service error:LimitExceeded. Allowed limit of parallel cross region copies reached. Maximum allowed no. of parallel cross region operation is 1.. http status code: 400. Opc request id: 8359f66b30bc0101287d30d304445a87/8B42EACB01B940124FAFC29F4AD4C5F9/1913B4629F5F8644215B780FA1C4F658
```



# 参考URL

https://docs.cloud.oracle.com/iaas/Content/Block/Tasks/copyingbootvolumebackupcrossregion.htm