catch-img

AWSトレーニングコースで使用している質問フォームのアーキテクチャ(2019年6月版)

コース中の質問をサーバーレスなアーキテクチャで受けて共有」で掲載しました質問フォームのアーキテクチャを一部変更しましたので、今回は設計を書いておきたいと思います。

動作などは上記リンクをご参照ください。

目次[非表示]

  1. 1. Amazon Route 53
  2. 2. AWS Certificate Manager
  3. 3. Amazon CloudFront
  4. 4. Amazon S3
  5. 5. Amazon API Gateway
  6. 6. 最初のAWS Lambda
  7. 7. Amazon SNS, Amazon SQS
  8. 8. Teamsに投稿するAWS Lambda
  9. 9. Backlogにチケット登録するAWS Lambda
  10. 10. DynamoDBにデータを入れるAWS Lambda

 

Amazon Route 53

個人で所有しているドメインでアクセスできるようにしていますので、Route 53のAレコードのエイリアスで、CloudFrontのドメインを指定しています。

21-3

 

 

AWS Certificate Manager

Certificate Managerでドメインの証明書を発行して、Route 53のCNAMEでドメイン認証をしています。

22-3

 

23-2

 

Amazon CloudFront

CloudFrontにはCertificate Managerで発行した証明書を設定しています。

24-1

オリジンにはS3バケットを指定して、OAIにてバケットへのCloudFrontを介さない直接のアクセスをできないようにしています。

25-1

Amazon S3

S3のバケットポリシー

{    "Version": "2008-10-17",    "Id": "PolicyForCloudFrontPrivateContent",    "Statement": [        {            "Sid": "1",            "Effect": "Allow",            "Principal": {                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXXX"            },            "Action": "s3:GetObject",            "Resource": "arn:aws:s3:::qa.trainocate/*"        }    ]}

 

S3バケットにはHTML, CSS, JavaScriptを配置して入力フォームをCloudFront経由で配信しています。

2-1

 

 

Amazon API Gateway

[質問]ボタンが押されると質問内容がURLパラメータとしてAPI GatewayでデプロイしたAPIにPOSTされます。

26-1

API GatewayではURlパラメータをJSONに変換してLambdaにEventデータとして渡しています。

27-1

29-1

 

最初のAWS Lambda

最初のLambdaはメッセージを受け取って、SNSトピックへ発行します。

28-1


import loggingimport boto3import tracebackimport jsonlogger = logging.getLogger()logger.setLevel(logging.INFO)
def lambda_handler
(event, context):    logger.info(event)    try:        sns = boto3.client('sns')        qa_topic = 'Qa'        snsTopicArn = [t['TopicArn'] for t in sns.list_topics()['Topics'] if t['TopicArn'].endswith(':' + qa_topic)][0]        sns.publish(            TopicArn=snsTopicArn,            Message=json.dumps(event),            Subject='question'        )    except:        logger.error(traceback.format_exc())

 

 

Amazon SNS, Amazon SQS

SNSトピックは3つのSQSキューへメッセージをファンアウトします。

 

Teamsに投稿するAWS Lambda

1つ目のSQSキューからメッセージを受信したLambdaはTeamsに通知します。


import logging, boto3, json, traceback, osfrom teams import Teamslogger = logging.getLogger()logger.setLevel(logging.INFO)
def lambda_handler
(event, context):    teams = Teams()    try:        for record in event['Records']:            message_body = json.loads(record['body'])            message = json.loads(message_body['Message'])                        project_id = message['project_id']            description = message['contact_detail'].replace(                'newline',                '\n'            )            teams.send_message(                '受講者からの質問',                '{description}  {project_id}'.format(                    description=description,                    project_id=project_id                )            )    except:        logger.error(traceback.format_exc())        raise Exception(traceback.format_exc())

 

Backlogにチケット登録するAWS Lambda

2つ目のSQSキューからメッセージを受信したLambdaはBacklog APIにPOSTしてチケット登録を行います。


import logging, boto3, json, traceback, os, requestslogger = logging.getLogger()logger.setLevel(logging.INFO)
def lambda_handler
(event, context):    try:        backlog_key = os.environ.get('BACKLOG_KEY', '')        project_id = os.environ.get('PROJECT_ID', '')        issue_type_id = os.environ.get('ISSUE_TYPE_ID', '')        priority_id = os.environ.get('PRIORITY_ID', '')        assignee_id = os.environ.get('ASSIGNEE_ID', '')        backlog_url =os.environ.get('BACKLOG_URL', '')        mile_stone_id = os.environ.get('MILE_STONE_ID', '')                for record in event['Records']:            message_body = json.loads(record['body'])            logger.info(message_body)            logger.info(message_body['Message'])            message = json.loads(message_body['Message'])                        summary =  message['contact_detail'].replace(                'newline',                ''            )[:50]            description = message['contact_detail'].replace(                'newline',                '\n'            )                        payload_dic = {                'projectId': project_id,                'issueTypeId': issue_type_id,                'priorityId': priority_id,                'assigneeId': assignee_id,                'milestoneId': [mile_stone_id],                'summary': summary,                'description': description            }                        headers = {                'Content-Type': 'application/json'            }            response = requests.post(                backlog_url + backlog_key,                data=json.dumps(                    payload_dic                ),                headers = headers            )            if response.text:                logger.info(response.text)            else:                logger.info(response)    except:        logger.error(traceback.format_exc())        raise Exception(traceback.format_exc())

 

DynamoDBにデータを入れるAWS Lambda

3つ目のSQSキューからメッセージを受信したLamndaはリクエスト内容と時間、送信元IPアドレスなどの情報とともにDynamoDBへ書きます。


import traceback, json, os, logging, boto3from datetime import datetimelogger = logging.getLogger()logger.setLevel(logging.INFO)
def lambda_handler
(event, context):    logger.info(event)    try:        dynamodb = boto3.resource('dynamodb')      table = dynamodb.Table('qa')        with table.batch_writer() as batch:            for record in event['Records']:                message_body = json.loads(record['body'])                message = json.loads(message_body['Message'])                message['submit_datetime'] = datetime.now().strftime('%Y%m%d%H%M%S%f')                batch.put_item(Item=message)    except:        logger.error(traceback.format_exc())

 

トレノケートのAWS研修(AWS認定トレーニング)

トレノケートのAWS認定トレーニングでは、AWS社の厳格なテクニカルスキル及びティーチングスキルチェックに合格した認定トレーナーがコースを担当します。AWS初心者向けの研修や、AWS認定資格を目指す人向けの研修をご提供し、皆様のAWS知識修得のサポートをいたします。
トレノケートのAWS研修(AWS認定トレーニング)はこちら


▼AWS初心者の方は、 AWS Cloud Practitioner Essentialsから!
座学中心の研修で、AWSを初めて学ぶ方や、営業などで提案に関わる方におすすめです。
「AWS Certified Cloud Practitioner」資格取得を目指す方の基礎知識修得にも最適です。
AWS Cloud Practitioner Essentials 詳細・日程はこちらから

 

山下 光洋(やました みつひろ)

トレノケート株式会社 講師。AWS Authorized Instructor Champion / AWS認定インストラクター(AAI) / AWS 認定ソリューションアーキテクト - プロフェッショナル /AWS認定DevOpsエンジニア - プロフェッショナル / AWS 認定デベロッパー - アソシエイト / AWS 認定 SysOps アドミニストレーター - アソシエイト / AWS 認定クラウドプラクティショナー / kintone認定 カスタマイズスペシャリスト他。AWS認定インストラクターとしてAWS認定コースを実施。毎年1,500名以上に受講いただいている。AWS 認定インストラクターアワード2018, 2019を日本で唯一受賞。著書『AWSではじめるLinux入門ガイド』(マイナビ出版社)。共著書『AWS認定試験対策 AWS クラウドプラクティショナー』(SBクリエイティブ社)。前職では2016年にAWS Summitにパネラーとして参加。その前はLotus Technical Award 2009 for Best Architectとして表彰されている。また、各コミュニティの運営にも個人的に関わり、勉強会にてスピーカーや参加をしている。

無料ダウンロード

オススメコンテンツ

オススメ記事

AWS プロジェクトマネジメント PMP 人材育成 田中淳子 Microsoft ビジネススキル PMBOKⓇ IT資格 ITスキル 山下光洋 人材育成応援ラジオ クラウド AMA コミュニケーション Azure 人材開発用語集 PMBOK®ガイド入門 新入社員 横山哲也 AWS認定トレーニング DX re:Invent セキュリティ AI(人工知能) PMP試験問題に挑戦 Cisco PMBOKⓇガイド 第6版 イベント・セミナー 試験体験記 キャリア PMBOK®ガイド第6版の変更点 人材開発 CCIE CCNA 生成AI 研修 AI人材 DX人材育成 IT人材 スキルアップ テレワーク ネットワーク リモートワーク 人材トレンド GCP PMP(R)試験問題 第6版対応 PMP合格体験記 Windows Server voicy リーダーシップ AWS_Q&A Active Directory IT資格解説 アセスメント デジタルビジネス ヒューマンスキル 人気コースランキング 大喜利 部下の育成 PMの心得 reinvent2023 グローバル人材 リスキリング 新入社員研修といえば IoT OJT reinvent2022 プログラミング 1on1 AWS_DiscoveryDay CCNP Security Windows PowerShell クリエイティビティ コーチング AWSトレーニングイベント Google Cloud ITインフラ ITエンジニア PMP試験対策一問一答 ダイバーシティ プロジェクト プロトタイプビルダー 試験対策問題 GCP無料セミナー Google Cloud Platform G検定 Linux Power Platform oVice アワード クリティカルシンキング サンプル問題 ステークホルダー ディープラーニング リーダー ワーケーション 女性活躍 新入社員研修