この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
サーバーレスなURL短縮サービスを Python 版 AWS CDK で作るウェビナーを見つけたので、動かしてみました。
最終的には下図のようなサーバーレスなインフラを構築します。
構築された URL 短縮サービスを触ってみます。
targetUrl
に URL を渡し、短縮 URL を生成します。
$ curl https://go.example.info?targetUrl=https://aws.amazon.com/cdk/
Created URL: https://go.example.info/4692efec
短縮 URL でアクセスすると、元の URL にリダイレクトされます。
$ curl -I https://go.example.info/4692efec
HTTP/2 301
date: Wed, 09 Oct 2019 10:03:35 GMT
content-type: application/json
content-length: 0
location: https://aws.amazon.com/cdk/
x-amzn-requestid: 939ce6c8-ddcf-48b7-a758-e244bd42d12c
x-amz-apigw-id: BSiCsGQ-liAFgmA=
x-amzn-trace-id: Root=1-5d9db077-c89a4731411fa428e4c1b245;Sampled=0
301 ステータスと location から期待通りリダイレクトされていることがわかりますね。
本ブログでは、ウェビナーに従い、ミニマムな CDK アプリケーションから始めて、インクリメンタルに機能拡張・デプロイし、短縮URLサービスを構築します。
チュートリアルの流れ
- AWS CDK のインストール
- CDK アプリケーションの作成
- パッケージのインストール
- DynamoDB のモデリング
- Lambda 関数の作成
- Lambda の権限設定
- API Gateway の構築
- DNS 設定
- 後片付け
1. AWS CDK のインストール
まずは AWS CDK をインストールします。
$ npm install -g aws-cdk
...
$ cdk --version
1.12.0 (build 923055e)
利用リージョンでまだ一度も AWS CDK を利用したことがない場合、$ cdk bootstrap
で初期化します。
CDKToolkit
という CloudFormation スタックが作成され、CDK の実行に必要な S3 バケットなどが作成されます。
この処理をスキップすると、以下のようなエラーが発生します。
$ cdk deploy
...
❌ cdk-app-name failed: Error: This stack uses assets, so the toolkit stack must be deployed to the environment (Run "cdk bootstrap aws://unknown-account/unknown-region")
This stack uses assets, so the toolkit stack must be deployed to the environment (Run "cdk bootstrap aws://unknown-account/unknown-region")
2. CDK アプリケーションの作成
url-shortener という名前の新規アプリケーションを作成します。
[~]$ mkdir url-shortener
[~]$ cd url-shortener
[~/url-shortener]$ cdk init --language python
ファイル構成を確認します。
[~/url-shortener]$ tree
.
├── README.md
├── app.py
├── cdk.json
├── requirements.txt
├── setup.py
└── url_shortener
├── __init__.py
└── url_shortener_stack.py
1 directory, 7 files
主要ファイルに絞って解説します。
ファイル名 | 概要 |
---|---|
app.py | CDKで呼び出されるメインプログラムです。 |
requirements.txt | setup.pyを参照するようになっているため、直接は編集しません。 |
setup.py | 依存パッケージを管理します。 |
url_shortener/url_shorteneer_stack.py | Constructs/Stacksを定義します。今回はこのファイルを主に編集します。 |
CDK 初期化直後の app.py
と url_shortener_stack.py
を確認します。
app.py
アプリケーションを定義している app.py
を確認します。
app.py
#!/usr/bin/env python3
from aws_cdk import core
from url_shortener.url_shortener_stack import UrlShortenerStack # UrlShortenerStack スタックをインポート
app = core.App() # CDK App の作成
UrlShortenerStack(app, "url-shortener") # App と Stack の紐付け
app.synth()
url_shortener_stack.py
スタックを定義している url_shortener_stack.py
を確認します。
初期状態では Construct は何も定義されていません。
url_shortener/url_shortener_stack.py
#!/usr/bin/env python3
from aws_cdk import core
from url_shortener.url_shortener_stack import UrlShortenerStack
app = core.App()
UrlShortenerStack(app, "url-shortener")
app.synth()
以降では
- Construct
- Stack
を追加・編集して機能拡張します。
3. パッケージのインストール
アプリケーションに必要なパッケージをインストールします。
requirements.txt
の中身は -e .
となっていて、インストールするパッケージは同じ階層にある setup.py
を参照するようになっています。
setup.py
の install_requires
にインストールするパッケージを追加します。
setup.py
...
install_requires=[
"aws-cdk.core",
"aws-cdk.aws-dynamodb",
"aws-cdk.aws-events",
"aws-cdk.aws-events-targets",
"aws-cdk.aws-lambda",
"aws-cdk.aws-s3",
"aws-cdk.aws-ec2",
"aws-cdk.aws-ecs-patterns",
"aws-cdk.aws-certificatemanager",
"aws-cdk.aws-apigateway",
"aws-cdk.aws-cloudwatch",
"cdk-watchful",
"boto3"
],
...
※ Tech Talk のデモ全体で利用するモジュールを含めています。
次に venv
で仮想環境を作成し、パッケージをインストールします。
[~/url-shortener]$ python3 -m venv .env
[~/url-shortener]$ source .env/bin/activate
(.env) [~/url-shortener]$ pip install -r requirements.txt
4. DynamoDB のモデリング
URL と短縮 URL のマッピングを行う DynamoDB のモデルを定義します。
- 論理テーブル名 : mapping-table
- パーティションキー : id(STRING 型)
キーが短縮 URL、バリューが元の URL というシンプルなデータモデルです。
url_shortener/url_shortener_stack.py
を更新します。
url_shortener/url_shortener_stack.py
from aws_cdk import core
from aws_cdk import aws_dynamodb
class UrlShortenerStack(core.Stack):
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
table = aws_dynamodb.Table(self, "mapping-table",
partition_key=aws_dynamodb.Attribute(
name="id",
type=aws_dynamodb.AttributeType.STRING))
$ cdk deploy
コマンドでデプロイします。
$ cdk deploy
url-shortener: deploying...
url-shortener: creating CloudFormation changeset...
0/3 | 18:23:41 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata
0/3 | 18:23:41 | CREATE_IN_PROGRESS | AWS::DynamoDB::Table | mapping-table (mappingtable5416B587)
0/3 | 18:23:41 | CREATE_IN_PROGRESS | AWS::DynamoDB::Table | mapping-table (mappingtable5416B587) Resource creation Initiated
0/3 | 18:23:42 | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata Resource creation Initiated
1/3 | 18:23:42 | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata
2/3 | 18:24:12 | CREATE_COMPLETE | AWS::DynamoDB::Table | mapping-table (mappingtable5416B587)
3/3 | 18:24:13 | CREATE_COMPLETE | AWS::CloudFormation::Stack | url-shortener
✅ url-shortener
Stack ARN:
arn:aws:cloudformation:eu-central-1:12345:stack/url-shortener/xxx
コンソールの DynamoDB を確認すると、新規テーブルが作成されています。
また、CloudFormation を確認すると、 url-shortener というスタックが作成されています。 以降では、このスタックを差分更新します。
5 :Lambda 関数の作成
短縮 URL サービスは API Gateway と Lambda でサーバーレスに構築します。 URL の登録とリダイレクトを行う Lambda 関数を作成します。
まず、Lambda 関数用ディレクトリ・ファイルを作成します
[~/url-shortener]$ mkdir lambda
[~/url-shortener]$ touch lambda/handler.py
Lambda 関数lambda/handler.py
では以下の関数を定義します。
create_short_url
関数 : クエリーストリングtargetUrl
から短縮 URL を生成し、DynamoDB に登録read_short_url
関数 : 短縮 URL から本来の URL を DynamoDB から取得し、HTTP ステータス 301 でリダイレクト
lambda/handler.py
import json
import os
import uuid
import logging
import boto3
LOG = logging.getLogger()
LOG.setLevel(logging.INFO)
def main(event, context):
LOG.info("EVENT: " + json.dumps(event))
query_string_params = event["queryStringParameters"]
if query_string_params is not None:
target_url = query_string_params['targetUrl']
if target_url is not None:
return create_short_url(event)
path_parameters = event['pathParameters']
if path_parameters is not None:
if path_parameters['proxy'] is not None:
return read_short_url(event)
return {
'statusCode': 200,
'body': 'usage: ?targetUrl=URL'
}
def create_short_url(event):
# Pull out the DynamoDB table name from environment
table_name = os.environ.get('TABLE_NAME')
# Parse targetUrl
target_url = event["queryStringParameters"]['targetUrl']
# Create a unique id (take first 8 chars)
id = str(uuid.uuid4())[0:8]
# Create item in DynamoDB
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table(table_name)
table.put_item(Item={
'id': id,
'target_url': target_url
})
# Create the redirect URL
url = "https://" \
+ event["requestContext"]["domainName"] \
+ event["requestContext"]["path"] \
+ id
return {
'statusCode': 200,
'headers': {'Content-Type': 'text/plain'},
'body': "Created URL: %s" % url
}
def read_short_url(event):
# Parse redirect ID from path
id = event['pathParameters']['proxy']
# Pull out the DynamoDB table name from the environment
table_name = os.environ.get('TABLE_NAME')
# Load redirect target from DynamoDB
ddb = boto3.resource('dynamodb')
table = ddb.Table(table_name)
response = table.get_item(Key={'id': id})
LOG.debug("RESPONSE: " + json.dumps(response))
item = response.get('Item', None)
if item is None:
return {
'statusCode': 400,
'headers': {'Content-Type': 'text/plain'},
'body': 'No redirect found for ' + id
}
# Respond with a redirect
return {
'statusCode': 301,
'headers': {
'Location': item.get('target_url')
}
}
デプロイ対象に Lambda 関数を含めるよう、url_shortener/url_shortener_stack.py
を更新します。
url_shortener/url_shortener_stack.py
from aws_cdk import core
from aws_cdk import aws_dynamodb, aws_lambda
class UrlShortenerStack(core.Stack):
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
table = aws_dynamodb.Table(self, "mapping-table",
partition_key=aws_dynamodb.Attribute(
name="id",
type=aws_dynamodb.AttributeType.STRING))
handler = aws_lambda.Function(self, "backend",
runtime=aws_lambda.Runtime.PYTHON_3_7,
handler="handler.main",
code=aws_lambda.AssetCode(path="./lambda"))
aws_lambda.Function
の code
引数で Lambda 関数のソースパスを指定します。
aws_cdk.aws_lambda.AssetCode
で Lambda 関数のソースコードのパスを指定します。
デモでは aws_cdk.aws_lambda.Code が利用されていますが、現在は非推奨のため、使わないようにしてください。
$ cdk deploy
でデプロイします。
6:Lambda の権限設定
Lambda 関数が DynamoDB を読み書きできるように IAM 設定します。
DynamoDB Table のハイレベル API の grantReadWriteData(grantee)
メソッドを利用すると、必要なポリシーを付与できます。JSON で複雑なポリシーを定義する必要はありません。
メソッド名からどのような権限が自明であり、可読性にも優れています。
grantReadWriteData(grantee)
以外にも
grantFullAccess(grantee)
grantReadData
など、ユースケースごとに権限が用意されています。
次に、書き込み先の DynamoDB テーブルを 環境変数 TABLE_NAME
から取得するようにします。
この変数はプロビジョニング時に解決されます。
lambda/handler.py
from aws_cdk import core
from aws_cdk import aws_dynamodb, aws_lambda
class UrlShortenerStack(core.Stack):
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
table = aws_dynamodb.Table(self, "mapping-table",
partition_key=aws_dynamodb.Attribute(
name="id",
type=aws_dynamodb.AttributeType.STRING))
handler = aws_lambda.Function(self, "backend",
runtime=aws_lambda.Runtime.PYTHON_3_7,
handler="handler.main",
code=aws_lambda.AssetCode(path="./lambda"))
table.grant_read_write_data(handler)
handler.add_environment('TABLE_NAME', table.table_name)
更新差分を確認
$ cdk diff
コマンドで dry run します。
[~/url-shortener]$ cdk diff
Stack url-shortener
The url-shortener stack uses assets, which are currently not accounted for in the diff output! See https://github.com/aws/aws-cdk/issues/395
IAM Statement Changes
┌───┬────────────────────────────────┬────────┬────────────────────────────────┬─────────────────────────────────┬───────────┐
│ │ Resource │ Effect │ Action │ Principal │ Condition │
├───┼────────────────────────────────┼────────┼────────────────────────────────┼─────────────────────────────────┼───────────┤
│ + │ ${mapping-table.Arn} │ Allow │ dynamodb:BatchGetItem │ AWS:${backend/ServiceRole} │ │
│ │ │ │ dynamodb:BatchWriteItem │ │ │
│ │ │ │ dynamodb:DeleteItem │ │ │
│ │ │ │ dynamodb:GetItem │ │ │
│ │ │ │ dynamodb:GetRecords │ │ │
│ │ │ │ dynamodb:GetShardIterator │ │ │
│ │ │ │ dynamodb:PutItem │ │ │
│ │ │ │ dynamodb:Query │ │ │
│ │ │ │ dynamodb:Scan │ │ │
│ │ │ │ dynamodb:UpdateItem │ │ │
└───┴────────────────────────────────┴────────┴────────────────────────────────┴─────────────────────────────────┴───────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)
Resources
[+] AWS::IAM::Policy backend/ServiceRole/DefaultPolicy backendServiceRoleDefaultPolicy78BAA8F9
[~] AWS::Lambda::Function backend backendCBA98286
├─ [+] Environment
│ └─ {"Variables":{"TABLE_NAME":{"Ref":"mappingtable5416B587"}}}
└─ [~] DependsOn
└─ @@ -1,3 +1,4 @@
[ ] [
[+] "backendServiceRoleDefaultPolicy78BAA8F9",
[ ] "backendServiceRole77A15DC8"
[ ] ]
[~/url-shortener]$
問題がなければデプロイします。
$ cde deploy
7 :API Gateway の構築
次に、Lambda 関数を呼び出す API Gateway を定義します。
aws_apigateway.LambdaRestApi メソッドで、 Lambda をバックエンドとした API Gateway を作成します。
url_shortener/url_shortener_stack.py
from aws_cdk import core
from aws_cdk import aws_dynamodb, aws_lambda, aws_apigateway
class UrlShortenerStack(core.Stack):
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
table = aws_dynamodb.Table(self, "mapping-table",
partition_key=aws_dynamodb.Attribute(
name="id",
type=aws_dynamodb.AttributeType.STRING))
handler = aws_lambda.Function(self, "backend",
runtime=aws_lambda.Runtime.PYTHON_3_7,
handler="handler.main",
code=aws_lambda.AssetCode(path="./lambda"))
table.grant_read_write_data(handler)
handler.add_environment('TABLE_NAME', table.table_name)
# define the API endpoint and associate the handler
api = aws_apigateway.LambdaRestApi(self, "UrlShortenerApi", handler=handler)
デプロイします。
$ cdk deploy
...
✅ url-shortener
Outputs:
url-shortener.UrlShortenerApiEndpoint23405F0E = https://XXX.execute-api.eu-central-1.amazonaws.com/prod/
Stack ARN:
arn:aws:cloudformation:eu-central-1:1234:stack/url-shortener/5ea22370-e851-11e9-ab5a-025adfcb1154
デプロイが完了すると、最後に API Gateway のエンドポイントが出力されます。 このエンドポイントに対して、短縮 URL サービスを試してみましょう。
GET パラメーター targetUrl
に短縮したい URL を渡します。
$ URL=https://XXX.execute-api.eu-central-1.amazonaws.com/prod/
$ curl $URL?targetUrl=https://aws.amazon.com/cdk/
Created URL: https://XXX.execute-api.eu-central-1.amazonaws.com/prod/d4e23681
生成された短縮 URL を GET します。
$ curl -I https://XXX.execute-api.eu-central-1.amazonaws.com/prod/d4e23681
HTTP/2 301
content-type: application/json
content-length: 0
location: https://aws.amazon.com/cdk/
date: Wed, 09 Oct 2019 09:47:52 GMT
x-amzn-requestid: e44cbbf8-048e-4b1e-b061-6aa886c65e64
x-amz-apigw-id: BSfvSFyVliAFWOA=
x-amzn-trace-id: Root=1-5d9dacc8-786515e42454443a25f9e8aa;Sampled=0
x-cache: Miss from cloudfront
via: 1.1 6eea7c9b83576b73ff12f8e9ff2ad318.cloudfront.net (CloudFront)
x-amz-cf-pop: TXL51
x-amz-cf-id: H9_Jb03zbCpGtrb0GwS0gThJaFlgTOzZb0iisD-LuOx_FcrSg711yA==
レスポンスヘッダーの Location
から、短縮元の URL にリダイレクトされていることがわかります。
8 :DNS 設定
最後に、API Gateway をカスタムドメイン名、かつ、HTTPS で公開するため、Amazon Route 53 と AWS Certificate Manager(ACM) の 設定を行います。
ホストゾーンを複数のアプリケーションで共有することを想定し、別スタックで定義します。
実運用では、このようなスタックはライブラリー化し、他の CDK プロジェクトからも利用できるようにしたいところですが、今回は簡略化して単に別ディレクトリで管理します。
デモでは 架空企業"Walters co." 向けにサイト構築しているため、waltersco_common
という名前のディレクトリを作成します。
$ mkdir waltersco_common
$ touch waltersco_common/__init__.py
スタックにドメイン情報を含めます。
waltersco_common/__init__.py
import os
from aws_cdk.core import Stack, Construct # , Environment
from aws_cdk import aws_apigateway, aws_route53, aws_route53_targets, aws_certificatemanager
# we need default values here since aws-cdk-examples build synthesizes the app
ZONE_NAME = os.environ.get('WALTERSCO_ZONE_NAME', 'example.info')
ZONE_ID = os.environ.get('WALTERSCO_ZONE_ID', 'XXXX')
ZONE_CERT = os.environ.get('WALTERSCO_ZONE_CERT', 'arn:aws:acm:eu-central-1:1234:certificate/1-2-3-4')
class WaltersCoStack(Stack):
"""
A base CDK stack class for all stacks defined in our fun little company.
"""
def __init__(self, scope: Construct, id: str, **kwargs):
super().__init__(scope, id, **kwargs)
def map_waltersco_subdomain(self, subdomain: str, api: aws_apigateway.RestApi) -> str:
"""
Maps a sub-domain of waltersco.co to an API gateway
:param subdomain: The sub-domain (e.g. "www")
:param api: The API gateway endpoint
:return: The base url (e.g. "https://www.waltersco.co")
"""
domain_name = subdomain + '.' + ZONE_NAME
url = 'https://' + domain_name
cert = aws_certificatemanager.Certificate.from_certificate_arn(self, 'DomainCertificate', ZONE_CERT)
hosted_zone = aws_route53.HostedZone.from_hosted_zone_attributes(self, 'HostedZone',
hosted_zone_id=ZONE_ID,
zone_name=ZONE_NAME)
# add the domain name to the api and the A record to our hosted zone
domain = api.add_domain_name('Domain', certificate=cert, domain_name=domain_name)
aws_route53.ARecord(
self, 'UrlShortenerDomain',
record_name=subdomain,
zone=hosted_zone,
target=aws_route53.RecordTarget.from_alias(aws_route53_targets.ApiGatewayDomain(domain)))
return url
__all__ = ["WaltersCoStack"]
URL 短縮サービスのスタックもこのスタックを継承し、go
のサブドメインで API Gateway を公開するようにします。
url_shortener_stack.py
from aws_cdk import core
from aws_cdk import aws_dynamodb, aws_lambda, aws_apigateway
from waltersco_common import WaltersCoStack
class UrlShortenerStack(WaltersCoStack):
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
table = aws_dynamodb.Table(self, "mapping-table",
partition_key=aws_dynamodb.Attribute(
name="id",
type=aws_dynamodb.AttributeType.STRING))
handler = aws_lambda.Function(self, "backend",
runtime=aws_lambda.Runtime.PYTHON_3_7,
handler="handler.main",
code=aws_lambda.AssetCode(path="./lambda"))
table.grant_read_write_data(handler)
handler.add_environment('TABLE_NAME', table.table_name)
# define the API endpoint and associate the handler
api = aws_apigateway.LambdaRestApi(self, "UrlShortenerApi", handler=handler)
self.map_waltersco_subdomain('go', api)
デプロイします。
[~/url-shortener]$ cdk deploy
url-shortener: deploying...
url-shortener: creating CloudFormation changeset...
0/5 | 11:52:16 | CREATE_IN_PROGRESS | AWS::ApiGateway::DomainName | UrlShortenerApi/Domain (UrlShortenerApiDomain85D0CE65)
0/5 | 11:52:16 | UPDATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata
1/5 | 11:52:17 | UPDATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata
1/5 | 11:52:18 | CREATE_IN_PROGRESS | AWS::ApiGateway::DomainName | UrlShortenerApi/Domain (UrlShortenerApiDomain85D0CE65) Resource creation Initiated
2/5 | 11:52:18 | CREATE_COMPLETE | AWS::ApiGateway::DomainName | UrlShortenerApi/Domain (UrlShortenerApiDomain85D0CE65)
2/5 | 11:52:20 | CREATE_IN_PROGRESS | AWS::ApiGateway::BasePathMapping | UrlShortenerApi/Domain/Map:--=>urlshortenerUrlShortenerApi41983DFF (UrlShortenerApiDomainMapurlshortenerUrlShortenerApi41983DFF17DD9E30)
2/5 | 11:52:20 | CREATE_IN_PROGRESS | AWS::Route53::RecordSet | UrlShortenerDomain (UrlShortenerDomain9F16453F)
2/5 | 11:52:20 | CREATE_IN_PROGRESS | AWS::ApiGateway::BasePathMapping | UrlShortenerApi/Domain/Map:--=>urlshortenerUrlShortenerApi41983DFF (UrlShortenerApiDomainMapurlshortenerUrlShortenerApi41983DFF17DD9E30) Resource creation Initiated
3/5 | 11:52:20 | CREATE_COMPLETE | AWS::ApiGateway::BasePathMapping | UrlShortenerApi/Domain/Map:--=>urlshortenerUrlShortenerApi41983DFF (UrlShortenerApiDomainMapurlshortenerUrlShortenerApi41983DFF17DD9E30)
3/5 | 11:52:21 | CREATE_IN_PROGRESS | AWS::Route53::RecordSet | UrlShortenerDomain (UrlShortenerDomain9F16453F) Resource creation Initiated
4/5 | 11:52:53 | CREATE_COMPLETE | AWS::Route53::RecordSet | UrlShortenerDomain (UrlShortenerDomain9F16453F)
✅ url-shortener
Outputs:
url-shortener.UrlShortenerApiEndpoint23405F0E = https://0m59dyay05.execute-api.eu-central-1.amazonaws.com/prod/
Stack ARN:
arn:aws:cloudformation:eu-central-1:1234:stack/url-shortener/c3b74840-ea76-11e9-8004-0ac843449136
DNS の確認
Route 53 の ホストゾーンにレコードが追加されていることを確認します。
コマンドラインからも DNS レコードを確認します。
$ dig go.example.info
; <<>> DiG 9.10.6 <<>> go.example.info
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34240
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;go.example.info. IN A
;; ANSWER SECTION:
go.example.info. 60 IN A 3.123.86.188
go.example.info. 60 IN A 3.120.53.211
;; Query time: 77 msec
;; SERVER: 192.168.178.1#53(192.168.178.1)
;; WHEN: Wed Oct 09 12:02:02 CEST 2019
;; MSG SIZE rcvd: 88
このカスタムドメインに対して、短縮URLサービスを試します。
targetUrl に URL を渡し、短縮 URL を生成します。
$ curl https://go.example.info?targetUrl=https://aws.amazon.com/cdk/
Created URL: https://go.example.info/4692efec
短縮 URL でアクセスします。
$ curl -I https://go.example.info/4692efec
HTTP/2 301
date: Wed, 09 Oct 2019 10:03:35 GMT
content-type: application/json
content-length: 0
location: https://aws.amazon.com/cdk/
x-amzn-requestid: 939ce6c8-ddcf-48b7-a758-e244bd42d12c
x-amz-apigw-id: BSiCsGQ-liAFgmA=
x-amzn-trace-id: Root=1-5d9db077-c89a4731411fa428e4c1b245;Sampled=0
301 ステータスと location から期待通りリダイレクトされていることがわかりますね。
9 後片付け
最後に、作成した AWS リソースをスを cdk destroy
で削除しましょう。
$ cdk destroy
Are you sure you want to delete: url-shortener (y/n)? y
url-shortener: destroying...
0 | 12:04:28 | DELETE_IN_PROGRESS | AWS::CloudFormation::Stack | url-shortener User Initiated
...
✅ url-shortener: destroyed
裏では、CloudFormation のスタックが削除されます。
DynamoDB は CloudFormation の DeletionPolicy
を Retain
にして作成されているため、スタックを削除しても、テーブルは削除されません。
手動で削除してください。
最後に
Python 版 AWS CDK で短縮 URL サービスを作りました。
CDK アプリケーションの開発スタイル・サイクルの雰囲気が何となく伝わったのではないかと思います。
繰り返しとなりますが、本ブログは次の AWS Online Tech Talks が元になっています。
このウェビナーは
- 前半:(DynamoDB/Lambda/API Gateway/Route 53/ACM)アプリケーションの構築
- 後半:(Fargate/CloudWatch)負荷ツール、テスト、監視
の2本立てで、最終的には下図のようなシステムを構築し、ブログではその前半に焦点をあてています。
CDK を試してみたいアプリケーションエンジニアは、ドキュメントを読むよりも、この動画を見たほうがとっつきやすいのではないかと思います。
CDK に興味を持たれた方は、CDK Workshop を参考に手を動かすと、理解が進むと思います。
なお、ウェビナーに付随するソースコードは GitHub で公開されています。
aws-cdk-examples/python/url-shortener at master · aws-samples/aws-cdk-examples · GitHub
それでは。