AWS Cloud Development Kit(CDK)でURL短縮サービスを作ってみた
サーバーレスな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
を確認します。
#!/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 は何も定義されていません。
#!/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
にインストールするパッケージを追加します。
... 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
を更新します。
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 でリダイレクト
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
を更新します。
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
から取得するようにします。
この変数はプロビジョニング時に解決されます。
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 を作成します。
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
スタックにドメイン情報を含めます。
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 を公開するようにします。
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
それでは。