AWS上のRDS(MySQL)にiOSアプリからアクセスするための手順です。
すべての作業をスムーズに進めるため、次の作業を終えている必要があります。
- AWSアカウントの作成
- Python2.7、pipのインストール
- CocoaPodsのインストール
また、AWSで行うすべての作業が同一リージョンで行われることを前提としています。
AWSでRDSインスタンスを作成する
AWSコンソールのRDSにアクセスし、DBインスタンスの起動
をクリックします。
ユースケースは開発/テスト
を選択し、次へ
をクリックします。
※使用する環境に適したユースケースを設定してください。
DB詳細の指定では最下部にある設定
の各項目に入力します。
DBインスタンス識別子
にはSampleInstance
と入力します。
マスターユーザの名前
及びマスターパスワード
にはDBにアクセス可能なユーザ情報を入力します。
マスターユーザのアカウント情報は後の作業使うため、メモに残します。
入力を終えたら次へ
をクリックします。
[詳細設定]の設定を行います。
ネットワーク&セキュリティの各項目を下図のように設定します。
データベースの設定ではデータベースの名前
にSampleDB
と入力します。
データベース名は後の作業で使うため、メモに残します。
その他項目は初期状態のままで問題ありません。
入力が完了したら最下部にあるDBインスタンスの作成
をクリックします。
処理が完了するまで暫く待ちます。
処理中にDBインスタンスの詳細の表示
をクリックしても問題ありません。
DBインスタンスの詳細画面の要約にあるDBインスタンスのステータス
が利用可能であれば、正常にDBが作成されています。
セキュリティグループのインバウンド制約を変更し、Lambda関数からアクセスできるようにします。
セキュリティグループをクリックし、管理画面を表示します。
画面下部にあるインバウンド
タブをクリックし、編集
をクリックします。
ソース欄のIPアドレスを0.0.0.0/0
に変更し、保存
をクリックします。
セキュリティグループの管理画面を終了します。
最後にDBインスタンスの詳細画面から今後使用する情報をメモに残します。
- VPC
- サブネットグループ
- サブネット
- セキュリティグループ
- エンドポイント
Mobile HubでiOSアプリを追加する
AWSコンソールのMobile Hubにアクセスし、Create
をクリックします。
プロジェクト名にSampleApp
と入力し、Next
をクリックします。
Set up your backendでは何も行わずにNext
をクリックします。
Connect to your backendでは何も行わずにDone
をクリックします。
SampleAppの設定画面下部Add More Backend Features中のCloud Logic
をクリックします。
API nameにExecuteSQL
と入力し、Create API
をクリックします。
この状態になるとAPIの作成完了です。
自動的にLambda及びAPI Gatewayにそれぞれ処理が追加されています。
Lambdaのデプロイパッケージを作成する
ローカル環境でLambdaにデプロイするためのパッケージを作成します。
環境はPython2.7を用います。
まず何れかの場所に作業フォルダを作成します。
テキストエディットで新規書類を作成し、次のコードを入力します。
"エンドポイント"
"マスターユーザ名"
"マスターユーザパスワード"
"データベース名"
はMySQLインスタンス作成時にメモした情報に置き換えます。
host_url = "エンドポイント"
db_username = "マスターユーザ名"
db_password = "マスターユーザパスワード"
db_name = "データベース名"
入力を終えたらrds_config.py
という名称で作業フォルダに保存します。
再度テキストエディットで新規書類を作成し、次のコードを入力します。
注意:Pythonはインデントが 超重要 な言語です。入力の際はインデントがズレないように気をつけます。
import sys
import logging
import rds_config
import pymysql
import json
rds_host = rds_config.host_url
name = rds_config.db_username
password = rds_config.db_password
db_name = rds_config.db_name
logger = logging.getLogger()
logger.setLevel(logging.INFO)
try:
conn = pymysql.connect(rds_host, user=name, passwd=password, db=db_name, connect_timeout=5)
except:
logger.error("ERROR: Unexpected error: Could not connect to MySql instance.")
sys.exit()
logger.info("SUCCESS: Connection to RDS mysql instance succeeded")
def handler(event, context):
if ("body" in event):
param = event["body"]
if (isinstance(param, unicode)):
paramDic = json.loads(param)
else:
paramDic = param
if ("sql" in paramDic):
sql = paramDic["sql"].strip()
logger.info(sql)
if sql.upper().find("SELECT") == 0:
with conn.cursor(pymysql.cursors.DictCursor) as cur:
cur.execute(sql)
data = cur.fetchall()
result = {
"body": json.dumps(data)
}
else:
with conn.cursor() as cur:
cur.execute(sql)
conn.commit()
result = {
"body": "executed: " + sql
}
else:
result = {
"body": """ "sql" param not exsists. """
}
else:
result = {
"body": "body is not exists"
}
return result
入力を終えたらapp.py
という名称で作業フォルダに保存します。
pipコマンドでpymysqlライブラリを作業フォルダにインストールします。
コンソールを開き、次のコマンドを実行します。
$pip install PyMySQL -t 作業フォルダのパス
作業フォルダ内に準備した4つのファイルとフォルダを圧縮します。
圧縮ファイル名はapp.zip
とします。
注意:作業フォルダごと圧縮しないよう気をつけてください。
Lambda関数の実行環境を設定する
AWSコンソールのAWS Lambdaにアクセスし、画面左にある関数
をクリックします。
表示された関数一覧にMobile Hubにより自動作成された関数があることを確認します。
関数名をクリックし、詳細画面を表示します。
関数コードの各項目を次のように変更します。
- コードエントリタイプを
.zip ファイルをアップロード
に変更 - ランタイムを
Python2.7
に変更 - ハンドラを
app.handler
に変更
関数パッケージアップロード
をクリックし、先程作成したapp.zip
を選択します。
続けてサブネットとセキュリティグループもメモを元に設定します。
サンプルアプリを実行
Mobile Hubからサンプルアプリのプロジェクトファイルをダウンロードし、正しくSQL問い合わせができることを確認します。
AWSコンソールのMobile Hubにアクセスし、SampleApp
を選択します。
SampleApp詳細画面右上にあるResources
をクリックします。
Download
をクリックし、表示されるドロップダウンではiOS Swift
を選択します。
SampleApp-aws-my-sample-app-ios-swift.zip
がダウンロードされるので、任意の場所で展開します。
コンソールを開き、以下のコマンドで関連ライブラリをインストールします。
$cd 展開したフォルダ内の podfile までのパス
$pod install
インストールが完了したらMySampleApp.xcworkspace
を開き、実行します。
サンプルアプリで動作確認
アプリトップ画面に表示されているCloud Logic
をタップします。
案内画面下部にあるDemo Cloud Logic
をタップします。
Select Method一覧にあるPOST
をタップします。
Request Bodyの値を書き換え、Invoke
をタップすることで結果がResponseに表示されます。
一連のタスクを実行し、iOSアプリからAWS RDSに対して問い合わせが行われることを確認します。
Request bodyその1
{
"sql" : "create table Employee3 ( EmpID int NOT NULL, Name varchar(255) NOT NULL, PRIMARY KEY (EmpID))"
}
Response
executed: create table Employee3 ( EmpID int NOT NULL, Name varchar(255) NOT NULL, PRIMARY KEY (EmpID))
Request bodyその2
{
"sql" : "insert into Employee3 (EmpID, Name) values(1, 'Joe')"
}
Response
executed: insert into Employee3 (EmpID, Name) values(1, 'Joe')
Request bodyその3
{
"sql" : "insert into Employee3 (EmpID, Name) values(2, 'Bob')"
}
Response
executed: insert into Employee3 (EmpID, Name) values(2, 'Bob')
Request bodyその4
{
"sql" : "insert into Employee3 (EmpID, Name) values(3, 'Mary')"
}
Response
executed: insert into Employee3 (EmpID, Name) values(3, 'Mary')
Request bodyその5
{
"sql" : "select * from Employee3"
}
Response
[{\"EmpID\": 1, \"Name\": \"Joe\"}, {\"EmpID\": 2, \"Name\": \"Bob\"}, {\"EmpID\": 3, \"Name\": \"Mary\"}]