tl;dr
- 本記事は検証が十分ではなく、また一つのやり方でありbest wayというわけではないことに留意する
- 本記事はあくまでもクライアントのインストールだけに留めているのでその他必要な設定に関しては省略していることに留意する
- あらかじめS3にrpmファイルを配置しておく
- ebのインスタンスプロファイル(プロフィール)には該当のS3へのRead権限があるIAMロールを指定する
- ebextensionsでS3からダウンロードしてrpm -iの記述をする
本記事はLIFULL Advent Calendar 2017の9日目の記事です。
LIFULL Advent Calendar 2017 その2もよろしくお願いします。
ElasticBeanstalk使ってますか?
(本記事内ではElasticBeanstalkをebと称します)
ebのインスタンスからOracleに接続したい場面ってありませんか?
ただOracleに繋ぐ場合、クライアントをインストールする必要がありますよね。でもそのクライアントってOracleのサイトでログインしてからじゃないとダウンロードできなくてなかなか機械的にはやりづらいところですよね。
ebにはせっかくebextensionsという環境をカスタマイズするための仕組みが導入されているのに、サクッとはできないのが悲しいところ。
本記事ではサクッとできないところを解決する一つの方法を提示します。
事前にrpmファイルをS3に配置する
Oracleのサイトから以下のrpmファイルをダウンロードします。
Linux x86-64用のページに行きます。デッドリンクになってたらググってください。
ダウンロードページに行ったら以下の3つのファイルをダウンロードします。
- oracle-instantclient12.2-basic-12.2.0.1.0-1.x86_64.rpm
- oracle-instantclient12.2-sqlplus-12.2.0.1.0-1.x86_64.rpm
- oracle-instantclient12.2-devel-12.2.0.1.0-1.x86_64.rpm
途中のバージョン番号などは変わってる可能性があります。
とにかくbasicとsqlplusとdevelを抑えておけば良いです。
※ガーって書いたけどsqlplus要らなかった説、あります。
ダウンロードできたら上記の3つのファイルをアップロードします。
おそらく規約的に誰でもアクセスできるようなところにアップロードするのはNGなので上げる先としてS3を選択します。
IAM Roleの作成
先程アップロードしたファイルのGet*権限を持つIAM Roleを作成します。
面倒なのでここではAmazonS3ReadOnlyAccessポリシーを流用します。
またebのデフォルトで使われる各種ポリシーもアタッチします。
ebextensionsの設定
ebextensionsはebのアプリケーションルートディレクトリに「.ebextensions」ディレクトリを作成し、その下に*.configファイルを置くことでebのデプロイ/インスタンス起動時などに実行してくれる各種設定・コマンド群を記述できる仕組みです。
ドキュメントにも記載されているとおり以下の設定が使えます。
- packages
- rpm, yum, rubygems, pythonの順にパッケージ管理ツールを実行できる。Oracleクライアントもyumでインストールできるならこの設定が使えるのに
- groups
- グループの設定が可能
- users
- ユーザの設定が可能
- sources
- 公開URLからアーカイブファイルをダウンロードして任意のディレクトリに配置する。Oracleのzipファイルも認証いらずならこの設定が使えるのに
- files
- インスタンス内にファイルを作成
- commands
- アプリケーションとウェブサーバの設定が終わったら実行される。今回はこれを使用
- services
- インスタンス起動時に開始/終了したいサービスの設定が可能
- container_commands
- アプリケーションのソースコードが抽出される前に実行される。なのでこの設定の中では一番最後に実行される
ということでcommandsの記述をしていきます。
commands:
01_get_ora_basic:
command: aws s3 cp s3://sample.oracle-client/oracle-instantclient-basic.rpm /tmp/ora-basic.rpm
02_get_ora_sqlplus:
command: aws s3 cp s3://sample.oracle-client/oracle-instantclient-sqlplus.rpm /tmp/ora-sqlplus.rpm
03_get_ora_devel:
command: aws s3 cp s3://sample.oracle-client/oracle-instantclient-devel.rpm /tmp/ora-devel.rpm
04_install_basic:
command: rpm -i --replacepkgs /tmp/ora-basic.rpm
05_install_sqlplus:
command: rpm -i --replacepkgs /tmp/ora-sqlplus.rpm
06_install_devel:
command: rpm -i --replacepkgs /tmp/ora-devel.rpm
awsコマンドが利用可能なのでaws s3 cp
でアップロードしたファイル群を/tmp以下にダウンロードします。
そしてそれが終わったらrpm -i --replacepgs
でインストールします。
--replacepkgs
オプションがない場合、再デプロイ時に「すでにインストールされています」みたいなエラーになってデプロイができなくなったから指定したような気がします。
commands:
01_make_ld_conf:
command: 'echo "/usr/lib/oracle/12.2/client64/lib" > /etc/ld.so.conf.d/oracle.conf'
02_ld_config:
command: 'ldconfig'
03_make_symlink:
command: 'sudo ln -sf /usr/include/oracle/12.2/client64 /usr/lib/oracle/12.2/client64/include'
commandsではなくfilesでいいのでは?と思うかもしれませんが、filesでやってしまうと先述の通り実行順序はcommandsが後なので/usr/lib/oracle/
などがまだ存在せずエラーになります。
ちなみに01,02とファイルを分けた理由は単なる可読性のためなので一緒くたでもいいと思います。
option_settings:
- option_name: NLS_LANG
value: Japanese_Japan.UTF8
- option_name: ORACLE_HOME
value: /usr/lib/oracle/12.2/client64
- option_name: PATH
value: "$PATH:/usr/lib/oracle/12.2/client64"
- option_name: NLS_DATE_FORMAT
value: "YYYY/MM/DD HH24:MI:SS"
- option_name: TNS_ADMIN
value: /usr/lib/oracle/12.2/client64
環境変数各種設定です。options_settingsを使わなくともAWSコンソールの環境プロパティ画面でも設定できたかもしれないです。上記のとfilesと同様にディレクトリが存在しないから、だったかもしれないです。(なのでディレクトリを指定していないものに関してはコンソールの方で良いかも)
ebextensionsの設定はここまで。
アプリケーションを作る(Rubyで)
サンプルなのでザクっと作ります。
source 'https://rubygems.org'
gem 'ruby-oci8'
gem 'sequel'
gem 'sinatra', '~> 2.0.0'
SQLの便利ライブラリであるsequelとOracleのクライアントであるruby-oci8を指定します。
require './app.rb'
run Sinatra::Application
sinatraでアプリケーションを動かす際のお決まりです。
require 'sinatra'
post '/' do
begin
status 200
'success'
end
end
アプリケーションです。
最終的なファイル構成はこのようになります。
$ tree -a
.
├── .ebextensions
│ ├── 01_oracle_install.config
│ ├── 02_setupfiles.config
│ └── 03_setenv.config
├── Gemfile
├── app.rb
└── config.ru
ebを作成する
抑えるポイントはIAMインスタンスプロファイル(スクショ上ではプロフィール:新しいUIだと名前が変わったみたいですね)にて先ほど作成しておいたIAMロールを選択することです。
※キーペアの名前がちょっとアレな名前だったので黒塗りにしてます。
あとはRubyアプリケーション、テスト用なので単一インスタンス、RDSなし、t2.microなどの設定でアプリケーションを作成します。
t2.microより弱いインスタンスだとgemインストール時にメモリが足りなくてコケた記憶があるので検証時でもt2.micro以上をおすすめします。
postメソッドで受けるように作っちゃったのでcurlしてみます。
無事"success"が返ってきてアプリケーションが動作していることが確認できます。
え?Oracleの接続・動作確認してないじゃないかって?
それはまた別の話、ということで…。
クライアントがインストールされていなかったらそもそもruby-oci8のgemのインストールがコケます。
正常に作成できる=インストールはできている、ということで一つよろしくお願いします。
余談ですがLambdaの場合は@ikeisukeさんの記事が参考になるかもしれません。
AWS Lambda (Node.js-v4.3.2)からOracleに接続する(ORA-21561への対応)