AWSを利用したURL短縮サービスを開発しながら、サーバレスアプリの開発方法を学びましょう!
こんな時に代わりになる短いURLを発行するサービスです。
クラウドベンダーの提供しているサービスを組み合わせることで、サーバーの存在を意識せず開発・サービス提供が可能になる、というような考え方。
今回のハンズオンで登場するAWS Lambdaもサーバレス開発のコアを担うサービスの一つ。
書いた関数を実行してくれるFaaS(Fanction As a Service)というジャンルのサービス。
関数をデプロイし、API経由で呼び出すなどして利用する。
リージョンは東京(ap-northeast-1)に設定する。
1.Create environment を選択
2.Step 1 - Name environment
3.Step 2 - Configure settings
4.Step 3 - Review
正常にCloud9が作成されれば、以下のような画面が表示される。
ハンズオンで利用するWeb画面の資材をダウンロードする。
以下のコマンドを実行。
svn export https://github.com/MarkingCloud/handson-aws-url-shortner/trunk/public
ツリービューに public ディレクトリが追加される。
ディレクトリ構成は以下。
public
├── image
│ └── MC_icon_white.png
├── index.html
├── scripts
│ └── main.js
└── styles
└── main.css
資材をアップロードするバケットを作成する。
以下コマンドを実行。<バケット名>には世界で一意な名前を入れる。
aws s3 mb s3://<バケット名>
次に先ほどダウンロードした資材をバケットにアップロードする。
以下コマンドを実行。
aws s3 sync public s3://<バケット名>
以下の操作を行う。
1.プロパティ > 静的ウェブサイトホスティング > 編集する
2.アクセス許可 > ブロックパブリックアクセス (バケット設定) > 編集する
3.アクセス許可 > バケットポリシー > 編集する
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": "*", "Action": "s3:Get*", "Resource": "arn:aws:s3:::<バケット名>/*" } ] }
プロパティ > 静的ウェブサイトホスティング > バケットウェブサイトエンドポイント
に出力されているURLをクリック。
公開したWebページが表示されればOK。
まだ裏側は作成していないので、動作させても失敗する。
Cloud9の右側のメニューから Create a new Lambda function を選択
リソース作成ダイアログが表示されるので以下の通り選択する。
1.Function名
2.ランタイム
3.トリガー
4.リソース・ロール
5.設定確認
セットアップが完了するとリソースが作成され、表示される。
以下の操作を行う。
1.アクセス権限 > 実行ロール
2.(IAMコンソール) アクセス権限 > ポリシーをアタッチします
Cloud9に戻り、lambda_function.py に以下のコードを張り付ける。
import boto3
import random
import string
import json
BUCKET_NAME = "your-bucket-name"
def generate_random(n):
return "".join(random.SystemRandom().choice(string.ascii_lowercase + string.digits) for _ in range(n))
def get_public_url(bucket):
s3client = boto3.client("s3")
bucket_location = s3client.get_bucket_location(Bucket=bucket)
return "http://{0}.s3-website-{1}.amazonaws.com/".format(
bucket,
bucket_location["LocationConstraint"])
def lambda_handler(event, context):
s3resorce = boto3.resource("s3")
bucket = s3resorce.Bucket(BUCKET_NAME)
short_id = generate_random(5)
short_key = "u/" + short_id
body = event.get("body")
res = bucket.put_object(
Key=short_key,
Body=b"",
WebsiteRedirectLocation=body,
ContentType="text/plain"
)
public_url = get_public_url(BUCKET_NAME)
shorten_url = (public_url + short_key)
return {
"statusCode": 200,
"headers": {
"Access-Control-Allow-Origin": "*"
},
"body": json.dumps(shorten_url)
};
次にL6の BUCKET_NAME を自分が作成したバケット名に書き換える。
BUCKET_NAME = "your-bucket-name" ↓ BUCKET_NAME = "url-shortener-1112" //例
Ctrl + s で忘れずに保存する。
画面右側の Local Functions > 関数名を右クリック > Run > Run Local を選択する。
Payload タブに以下の内容を入力し、 Runボタン を選択するとLambdaがローカルで実行される。
{
"body": "https://markingcloud.github.io/handson-aws-url-shortner/"
}
実行が完了すると、Lambdaのログが画面中央に表示される。
Response の body に出力されているURLにアクセスし、リダイレクトされることを確認する。
画面右側の Local Functions > 関数名を右クリック > Run > Run API Gateway Local を選択する。
以下の操作を行う。
Response に出力されているURLにアクセスし、リダイレクトされることを確認する。
ここまで確認出来たらLambdaをデプロイする。
画面右側の Local Functions > 関数名を選択 > deployボタンを選択
少し待つとデプロイが完了する。
設定 > デザイナー > API Gateway > 詳細 を選択
API エンドポイントに出力されているURLをコピーする。
Cloud9から public/script/main.js を開く。
L20の apiurl をコピーしたAPIエンドポイントのURLに書き換える。
const apiurl = "apigateway URL" ↓ const apiurl = "https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/"
Ctrl + s で忘れずに保存する。
再度、以下のコマンドでS3にデプロイする。
aws s3 sync public s3://<バケット名>
これでWebアプリの完成!
プロパティ > 静的ウェブサイトホスティング > バケットウェブサイトエンドポイント
に出力されているURLをクリック。
公開したWebページが表示されるので、適当なURLを入力して動作確認を行う。
また、オブジェクト > /u にリダイレクトオブジェクトが追加されていることも確認する。
AWSを使ってURL短縮サービスを作成することができました!
複雑そうな処理もAWSを使えば簡単に実装できることが実感できたかと思います。
ここから先は各自思い思いに改良してみてください。
最後にアンケートがありますので、より良い勉強会作りのためにご協力お願い致します。
不要なリソースが残っているとお金がかかるので、要らなければ削除しましょう。
参考に各サービスの料金をまとめる。
Cloud9 は裏で立ち上がるEC2、EBSに対してのみ料金が発生する。
https://aws.amazon.com/jp/cloud9/pricing/
S3 はオブジェクトを置き続けると料金が発生するので注意。
https://aws.amazon.com/jp/s3/pricing/
Lambda はリクエスト数と実行時間ごとに料金が発生する。
https://aws.amazon.com/jp/lambda/pricing/
API Gateway はリクエスト数ごとに料金が発生する。
https://aws.amazon.com/jp/api-gateway/pricing/
より詳細な利用料は