Oracle Cloudが永遠に無料らしいので開発環境を作ってみたかった (APサーバ編)

開発環境構築の最後として、APサーバを作成しようと思います。

1. [準備編](https://qiita.com/mokkan/items/cc1b6b3ca04c105e807a)
2. [DBサーバ編](https://qiita.com/mokkan/items/0dea4a2f35ed4d28e167)
3. [ネットワーク編](https://qiita.com/mokkan/private/ffb5bae17edce8e563be)
4. APサーバ編 <- いまここ

今回実施することは、以下の3つです。

* VMインスタンスの作成
* DBとの疎通確認
* (インスタンスのポート開放時の注意点のメモ)

## Compute Instance
早速ですが、インスタンスを作成していこうと思います。
OCI上に仮想マシンやベアメタルサーバを構築するには、メニューからCompute->Instancesを選択し、Create Instanceをクリックします。

### Name your instance
作成するインスタンスの名前です。わかりやすい名前をつけましょう！

### Choose an operating system or image source
インスタンスのOSを選択します。デフォルトではOracle Linux(RHEL互換です)が選択されています。
今回はこのままOracle Linuxを使用しようと思いますが、Change Image Sourceをクリックして変更することも可能です。Always FreeではOracle Linuxのほかに、CentOSとUbuntuが使用可能です。

![03-1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/b7a33559-bc58-1797-51e3-217cdf06a457.png)

OSの選択が完了したら、Show Shape, Network and Storage Optionsをクリックして詳細メニューを開きます。

### Availability Domain
Availability Domain(AD)はリージョン内を分割した可用性の単位を示しています。
具体的にはADが異なれば物理的にデータセンターも異なることが保証されます。東京リージョンは1つのADのみで構成されているので変更不可です。

### Instance Type
Bare Metal Machineを選択すると、物理的にサーバを1台占有できます。Always Freeでは対象外なのでVirtual Machineを選択します。

### Instance Shape
Shapeを選択すると、作成するInstanceのCPU数やメモリサイズ、ネットワークの帯域幅等が決定します。Always FreeではVM.Standard.E2.1.Micro (Virtual Machine)のみが使用可能です。

![03-2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/466a1702-82aa-77f0-9249-fdd86b87dcd8.png)

### Configure networking
ここでは、ネットワーク編で作成したVCNとSubnetが選択されていることを確認します。ネットワーク環境を構築していない場合はここで自動構築されます。

どちらの場合についても、必ずAssign a public IP addressを選択するようにします。
デフォルトではDo not assign a public IP addressが選択されているので、そのままでは作成したインスタンスにパブリックIPが割り当てられません。

![03-3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/7c45fea5-efd3-7dc8-6b1f-b1ec0c298d79.png)

#### Use network security group to control trafficについて
OCI上にはSecurity Listのほかに、Network Security Groupという仕組みがあります。
どちらもインスタンスのVNICに対するFirewallの設定ですが、Security ListがSubnet単位で適用されるのに対して、Network Security GroupはSubnetに関係なく、自由な単位でグルーピングしてルールを適用することができます。

今回は簡潔にするためSecurity Listを使用しましたが、基本的にはNetwork Security Groupの使用が推奨されています。
※今回は使用しないのでこの項目にはチェック不要です


### Boot volume
Instanceのブートボリュームの設定です。基本的にどの項目もチェック不要です。

#### Custom boot volume size (in GB)
ブートボリュームのサイズを変更する場合はチェックします。

#### Use in-transit encryption
Instanceとブートボリュームの間の通信を暗号化する設定です。特に事情が無ければチェック不要です。

#### Choose a key from Key Management to encrypt this volume
ブートボリュームの暗号化に独自の鍵を使用するための設定です。
指定せずともOracleの鍵で暗号化はされているので、本当によほどのことが無い限りチェック不要です。

![03-4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/661b0b67-6550-26fe-7f21-9f8e210a6753.png)

### Add SSH Key
InstanceにSSHするための公開鍵を登録します。パスワード認証はできません。

![03-5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/caedf29f-85e4-3802-fc66-cbed45a2ec5e.png)

SSH鍵を登録したら、Show Advanced Optionsをクリックして、Networkingを選択します。プライベートIPやホスト名を指定する場合は、ここで値を設定します。
ホスト名はインスタンス名から自動生成されるので、インスタンス名に日本語を使用している場合はここで明示的に指定しておくのが無難だと思います。

![03-6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/9a21e561-dee0-d41e-b918-2eac4489d71f.png)

以上でInstanceの作成は完了となります。

![03-7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512576/5b05f8cd-9fcb-b142-fadf-f073aca33ce7.png)

※注意点として、Oracle側のデータセンターにそもそも空きがないと、ここで「Out of host capacity.」というエラーが発生してインスタンスの作成ができない場合があります。そうなってしまうと、空きが出るかもしくはサーバが増設されるまで気長に待つしかない感じになります。もし無料利用枠が残っている場合は、Always Freeではない通常のShapeを使用したりしつつ気長に待ちましょう

## 疎通確認
環境構築の最後に、作成したInstanceからDBにSQLを発行して、ちゃんと結果が返ってくることを確認したいと思います。

1. 作成したInstanceにSSHする
1. SQL*Plus(Oracle DBのクライアントツール)をインストールする
1. DBに接続するための設定をする
1. 実際に接続してSQLを発行する

まずはInstanceのパブリックIPにSSHしてログインします。

この時使用するユーザ名は`opc`です。
秘密鍵は、作成時に登録した公開鍵とペアになるものを使用します。
ポートはデフォルトから変更していないので22番ポートのままです。

```
$ ssh -i ./.ssh/id_rsa opc@<InstanceのパブリックIP>
<何か聞かれたらyesと入力する>
[opc@vm01 ~]$
```

ログインできたら、疎通確認用にSQL*Plusをインストールします。
この手順については下記の記事を使用させていただきました。
https://qiita.com/feifo/items/d21b7050d0d4799f5d47

次に、DBに接続するための設定を実施します。この手順については、公式のドキュメントを参照しています。
(Oracle Clientのインストールは上の手順で完了しているのでその次の手順から実施しています)
https://docs.oracle.com/cd/E83857_01/paas/autonomous-data-warehouse-cloud/user/connect-preparing.html#GUID-EFAFA00E-54CC-47C7-8C71-E7868279EF3B

ここまでの手順で接続する準備が整ったので、実際にSQLを発行してみたいと思います。
実行するのはDBサーバ編と同様にサンプルデータセットに対するリクエストです。
https://docs.oracle.com/cd/E83857_01/paas/autonomous-data-warehouse-cloud/user/getting-started.html#GUID-4BB2B49B-0C20-4E38-BCC7-A61D3F45390B

以下に実行結果を示しますが、無事にDBサーバ編と同じ結果が返ってくることが確認できました。
使用しているユーザは`admin`なので、DB構築時に指定した管理者パスワードを入力しています。DB名についている`_high`が一体何者なのかということについては、下記ドキュメントをご参照ください。
https://docs.oracle.com/cd/E83857_01/paas/autonomous-data-warehouse-cloud/user/connect-predefined.html#GUID-9747539B-FD46-44F1-8FF8-F5AC650F15BE

```
[opc@vm01 ~]$ sqlplus admin@testdb01_high

SQL*Plus: Release 18.0.0.0.0 - Production on Fri Oct 25 06:54:06 2019
Version 18.3.0.0.0

Copyright (c) 1982, 2018, Oracle.  All rights reserved.

Enter password:
Last Successful login time: Fri Oct 25 2019 06:37:59 +00:00

Connected to:
Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production
Version 18.4.0.0.0

SQL> SELECT channel_desc, TO_CHAR(SUM(amount_sold), '9,999,999,999') SALES$,
   RANK() OVER (ORDER BY SUM(amount_sold)) AS default_rank,
   RANK() OVER (ORDER BY SUM(amount_sold) DESC NULLS LAST) AS custom_rank
FROM sh.sales, sh.products, sh.customers, sh.times, sh.channels, sh.countries
WHERE sales.prod_id=products.prod_id AND sales.cust_id=customers.cust_id
  AND customers.country_id = countries.country_id AND sales.time_id=times.time_id
  AND sales.channel_id=channels.channel_id
  AND times.calendar_month_desc IN ('2000-09', '2000-10')
  AND country_iso_code='US'
GROUP BY channel_desc;  2    3    4    5    6    7    8    9   10

CHANNEL_DESC         SALES$         DEFAULT_RANK CUSTOM_RANK
-------------------- -------------- ------------ -----------
Direct Sales              1,320,497            3           1
Partners                    800,871            2           2
Internet                    261,278            1           3

```

ざっくりですが疎通確認も完了しました。

## インスタンスのポート開放時の注意点
最後に、インスタンスのポートを開放する際に注意する点について補足したいと思います。

ネットワーク編で記述した通り、Security Listを記述すればインスタンスにアタッチされているVNICに対してのファイアウォールは設定可能です。これに加えて、デフォルトではインスタンスのOS自身のファイアウォール(`firewalld`)も有効になっています。

この2つの片方だけを許可しても当然ながら疎通できないので、ポート開けてるはずなのにアクセスできない？等の問題が発生した場合は、とりあえず疑ってみるのがよいかと思われます。

APサーバ編は以上です。

あとは特にOCIに依存する手順は残っていないと思うので、好きなサーバソフトウェアをインストールするなど、自由に開発環境を構築していきましょう！