ソフトウェアの「手の内化」を推し進めるサステナブルな学習環境を内製化してみた

2021-05-02
デベロッパーのためのクラウド活用方法

Author : 濵﨑 智宏 (株式会社デンソー)

こんにちは、株式会社デンソーの濵﨑です。

私はこれまで AWS が主催する、AWS GameDay や AWS Jam に参加し、研鑽を積んできました。初めて、参加したのは 2019 年 6 月に AWS Loft Tokyo で開催された AWS GameDay です。結果はさて置き。AWS Loft Tokyo から新幹線で名古屋に戻り、里帰り中の妻から陣痛が来たと連絡を受け、翌朝、始発で山口に帰りましたが、出産に間に合わなかったことは今でも鮮明に覚えています。その後、2020 年にロシアで開催された技能五輪国際大会にて、クラウドコンピューティング職種の日本代表選手として参加し、銅メダルを獲得することができました。

このような経験を社内の他のメンバーにも共有したいとの思いから、社内で有志を集め、DX 人材強化策の一環として、社内コンテストを企画し、AWS Jam を参考にしたコンテストシステムを開発し、2022 年 2 月 19 日に開催された社内イベントで社員 108 名に提供しました。この記事では、このコンテストシステムについて紹介します。


「手の内化」とは

「手の内化」という言葉をご存じでしょうか ? トヨタグループで使われている言葉です。

「先ずは自らやってみて、原理原則を理解すること、そして現場で改善を繰り返し、競争力を高めること」と紹介されています。私は「手の内化」はトヨタグループの基本姿勢であると理解し、ソフトウェアにおいても、他社に任せっきりになることなく、手の内化を進めるべきと考え、コンテストシステムの内製化に挑戦しました。


コンテストシステム「Minoru」

このシステムは「Minoru」と名付けました。
その由来は初めて自分で作ったシステムであり、今後も育てていく、という思いから息子の「実」の名前を取りました。また、「Minoru」を使って学習した人の努力が「実る」とも掛けています

「Minoru」の今後の展望としては、利用者の方が任意のタイミングで自分用の環境を構築し、公開されている課題にチャレンジすることができ、また、利用者自身でも課題を開発し、それを共有できるようにすることで、自然とバリエーションが増えることを期待しています。これによって「サステナブルな」学習環境を構築していくことができると考えています。


AWS GameDay / AWS Jam とは

皆さん、AWS GameDay や AWS Jam には参加したことがありますか ? それぞれ、AWS のイベントなどで開催されるコンテキスト形式の学習コンテンツです。

コロナ禍の現在、オンラインでの開催になっていますが、私が参加した当時は、AWS Loft などに集まって、初対面の方数人とチームを組んで参加する形でした。リアルタイムに更新されるスコアを見ながら、協力してプレイすることは、エキサイティングで楽しかったです。それぞれ下記のようなコンテンツになっています。

AWS GameDay

与えられたシステムと手順書を元に実際のサービスを AWS 上で運用します。途中で様々な障害などが発生し、チームでそれらに対処し、システムを安定的に高いパフォーマンスで運用できると高得点が取れるようになっています。お題に沿って自ら考えてシステムの構築、障害対応、パフォーマンス改善、自動化などをする必要があり、それらを通して、AWS のベストプラクティスを学ぶことができます。

AWS Jam

様々なユースケースをお題として、小さな課題が複数用意されています。課題を解決することで得点を得ることができ、その得点を競います。使うと獲得できる点数は減ってしまいますが、Hint も用意されています。普段触ることのない AWS サービスに触ったり新しいスキルを身に着けることができます。

私は、AWS GameDay や AWS Jam は AWS やシステム運用のスキルを深めるために非常に有効な学習コンテンツだと思います。しかし、これらは常時開催されているものではなく、経験できるチャンスは年に数回しかありません。この点についても内製化に踏み切る動機になりました。


1. アーキテクチャ概要

「Minoru」の構築に利用するオペレーション環境には AWS Cloud9 を利用しました。
「Minoru」の大半は、AWS Serverless Application Model (AWS SAM) を利用して構築することができます。Cloud9 にソースコードを展開後、sam packagesam deploy を実行することで環境構築が完了するようにしています

次に AWS CLI を利用して Amazon S3 へ課題のドキュメントで参照する画像をアップロードし、AWS SDK for Python (Boto3) を利用して Amazon DynamoDB へ課題のドキュメントや得点などのデータを挿入します。

私は、シンプルな操作は AWS CLI を、複雑な操作は AWS SDK を利用するようにしています。 AWS CLI は、aws s3 help と打つことで手元でヘルプを見ることができ、さっと目的を達成したいときに向いています。しかし、複雑な処理を行いたい時や失敗する可能性もあるときには、AWS SDK を使うと便利です。AWS SDK は API 呼び出しのリトライ機構が組み込まれており、言語ごとの例外処理機構を使ったエラーハンドリングも実装しやすくなっています。


2. 使用している技術

  • 開発運用環境 : AWS Cloud9、シェルスクリプト、Python スクリプト、Docker、AWS Serverless Application Model (AWS SAM)
  • バックエンド
    • Webアプリケーション : Flask + Jinja2 + AWS SDK for Python (Boto3)
    • REST API : boto3 (Python)
  • フロントエンド : JavaScript、Bootstrap

フロントエンドの開発に経験がなくかなり苦戦し時間をかけてしまいましたが、最終的には、他の方に助けてもらいかっこよくしてもらいました。


3. 工夫したポイント

ここからは、「Minoru」の開発にあたり、工夫したポイントを 3 つ紹介します。

  1. 複数アカウントでのデプロイ管理
  2. 同一 AWS アカウント内に複数の課題を共存させ、権限により分離する
  3. クリーンアップ

3-1. 複数アカウントでのデプロイ管理

AWS Jam は様々な難易度設定がされた小さな課題が複数用意されています。「Minoru」でも同様の構成をとっています。各課題は AWS CloudFormation を利用して初期構成を行いました。

今回は 40 の AWS アカウントにそれぞれ 20 個の課題を用意していたので合計 800 の CloudFormation スタックを作成する必要がありました。1 つのスタックから 800 個のスタックを順番に作っていると日が暮れてしまいます。そこで、Docker を利用した並列デプロイの仕組みを作成しました。1 つの課題用スタックをデプロイするコンテナはメモリーが 70 MB 程度必要でしたが、t3.2xlarge を利用すると 400 個以上のコンテナを同時に実行できるので 800 スタックをデプロイするのに 30 分もかかりませんでした。

AWS Serverless Application Model (AWS SAM)と Docker を利用し、コンテナごとに AWS 認証情報を渡して AWS SAM CLI を実行することで、各課題に利用するソースの可搬性を保ちながら並列デプロイを実現することができました。

テスト時には、EC2 インスタンスの空きメモリーに関係なくコンテナを起動したため、Cloud9 の接続は切れ、コンテナは潰れ、大失敗しました。そこで、メモリーを監視しながらコンテナを管理するようにスクリプトを改善しました。一部抜粋して下記にサンプルコードを記載します。

cmd="""
docker run -v `pwd`/Challenges:/Challenges \
    --env RootUserId={} \
    --env AWS_ACCESS_KEY_ID=`echo {} | cut -d , -f 3` \
    --env AWS_SECRET_ACCESS_KEY=`echo {} | cut -d , -f 4` \
    --env AWS_AccountId=`echo {} | cut -d , -f 5` \
    --env RandomString=`echo {} | cut -d , -f 6 | tr -d '\r'` \
    --env ChallengeTitle=`echo {} | cut -d , -f 1` \
    --env LabId=`echo {} | cut -d , -f 2` \
    --env AWS_DEFAULT_REGION=`echo {} | cut -d , -f 3 | tr -d '\r'` \
    createstack &
"""
while True:
    proc = subprocess.Popen("free -m | grep Mem | awk '{print $4}'", stdout=subprocess.PIPE, shell=True)
    (out, err) = proc.communicate()
    if int(out) > 100:
        break
    else:
        time.sleep(5)
        print("Free Mem:", int(out), "MB")
cmd=(cmd.format(
    RootUserId,
    CredentialsItems_list[CredentialsItemIndex_int]['Access key ID'],
    CredentialsItems_list[CredentialsItemIndex_int]['Secret access key'],
    CredentialsItems_list[CredentialsItemIndex_int]['AWS Account Id'],
    CredentialsItems_list[CredentialsItemIndex_int]['RandomString'],
    ChallengesItems_list[ChallengesItemIndex_int]['Title'],
    ChallengesItems_list[ChallengesItemIndex_int]['ChallengeId'],
    ChallengesItems_list[ChallengesItemIndex_int]['Region']
))
os.system(cmd)

また、今後は、AWS Step Functions と AWS Lambda を活用して改善するとスタック作成をより迅速にかつコストを削減できそうと考えています。

3-2. AWSアカウント内に複数の課題を共存させ、権限により分離する

AWS Jam のような AWS 上での課題を解決する問題を出すときには、問題ごとにクリーンな環境を用意したくなります。しかし、コンテスト参加者に対して、課題ごとに別の AWS アカウントを用意すると AWS  アカウントの数が膨大になってしまいます。

そこで今回は、1 リージョンにつき 1 課題とし、1 つの AWS アカウントに複数の課題が共存できるようにしました。権限を制限する例として今回利用した課題から抜粋し例を示します。

  LabUserPermissionsBoundary:
    Type: AWS::IAM::Policy
    Properties: 
      PolicyName: LabUserPermissionsBoundary-000ff9fd-b3ddb-s
      Roles: 
        - !Ref LabUserRole
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          # グローバルサービス以外のStackを作成したリージョン以外のアクセスを禁止する
          - Effect: Deny
            NotAction: 
              - a4b:*
              - acm:*
              - aws-marketplace-management:*
              - aws-marketplace:*
              - aws-portal:*
              - budgets:*
              - ce:*
              - chime:*
              - cloudfront:*
              - config:*
              - cur:*
              - directconnect:*
              - ec2:DescribeRegions
              - ec2:DescribeTransitGateways
              - ec2:DescribeVpnGateways
              - fms:*
              - globalaccelerator:*
              - health:*
              - iam:*
              - importexport:*
              - kms:*
              - mobileanalytics:*
              - networkmanager:*
              - organizations:*
              - pricing:*
              - route53:*
              - route53domains:*
              - s3:GetAccountPublic
              - s3:ListAllMyBuckets
              - s3:PutAccountPublic
              - shield:*
              - sts:*
              - support:*
              - trustedadvisor:*
              - waf-regional:*
              - waf:*
              - wafv2:*
              - wellarchitected:*
            Resource: '*'
            Condition:
              StringNotEquals:
                'aws:RequestedRegion':
                  - !Sub '${AWS::Region}'
          # LabUserPermissionsBoundary に対するアクセスを禁止する
          - Effect: Deny
            Action:
              - iam:RemoveUserFromGroup
              - iam:DeleteGroup
              - iam:UpdateGroup
              - iam:DeletePolicy
              - iam:DetachGroupPolicy
              - iam:DeleteUserPermissionsBoundary
              - iam:DeleteGroupPolicy
            Resource:
              - !Sub 'arn:aws:iam::${AWS::AccountId}:policy/*LabUserPermissionsBoundary*'
  LabUserRole:
    Type: AWS::IAM::Role
    Properties:
      MaxSessionDuration: 43200
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Sub 'arn:aws:iam::${RootUserId}:root'
            Action: sts:AssumeRole
      Path: /
      Policies:
        # 課題を進めるために必要な許可する
        - PolicyName: labuserpolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - s3:ListAllMyBuckets
                Resource: '*'
              - Effect: Allow
                Action:
                  - s3:*
                Resource:
                  - !Sub 'arn:aws:s3:::${ProductBucket}/*'
                  - !Sub 'arn:aws:s3:::${ProductBucket}'
        # 課題を壊すアクセスを禁止する
        - PolicyName: labbasepolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Deny
                Action:
                  - lambda:*
                Resource:
                  !GetAtt 'CopyFilesFunction.Arn'
              - Effect: Deny
                Action:
                  - logs:*
                Resource:
                  - !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*:*'
              # このStackに対するアクセスを禁止する
              - Effect: Deny
                Action:
                  - cloudformation:DescribeStackEvents
                  - cloudformation:GetTemplate
                  - cloudformation:DescribeStackResource
                  - cloudformation:ListStackResources
                Resource:
                  - !Sub '${AWS::StackId}'
              PolicySimulatorへのアクセス許可
              - Effect: Allow
                Action:
                  - iam:GetRole
                  - iam:GetRolePolicy
                  - iam:ListRolePolicies
                  - iam:ListAttachedRolePolicies
                Resource: 
                  - !Sub 'arn:aws:iam::${AWS::AccountId}:role/*LabUserRole*'
              - Effect: Allow
                Action:
                  - iam:ListRoles
                  - iam:GetPolicy
                  - iam:GetPolicyVersion
                Resource: '*'

3-3. クリーンアップ

コンテスト後に無駄な課金が発生しないためにも、クリーアップが必要でした。誰もが一度は、リソース全削除ボタンを切望したのではないでしょうか。しかし、現実にはそんな機能はありません。また、課題の初期構成を行った CloudFormation のスタックを削除するだけでは、参加者が競技中に追加で作成したリソースの削除はできませんし、S3 にファイルを追加した場合など、操作によってはスタックの削除自体が失敗します。そこで 2 Step に分けて削除する方法をとりました。

  • Step 1 : AWS CLI から AWS CloudFormation スタックを削除
  • Step 2 : aws-nuke の実行

Step 1 を必要とした理由は、Step 2 だけを実行した場合に比べると削除所要時間の短縮と成功率の向上が図れると想定したためです。Step 1 は「3-1. 複数アカウントでのデプロイ管理」で実行した方法と同じ手法を用いています。ここからは、Step 2 の aws-nuke  についてご紹介します。

3-3-1. aws-nuke について

aws-nuke は、AWS アカウントのリソースを全て削除する OSS のツールです。今回は、Docker イメージのビルド時に GitHub からダウンロードしてバイナリを使用しています。

aws-nuke は非常に強力なツールですので試す際は気を付けてください。コンテナ作成に利用した、Dockerfile と実行スクリプト、aws-nuke の設定ファイルのサンプルを記載します。

aws-nukeDockerfile : Dockerfile

FROM amazonlinux:2

ENV LANG=en_US.SJIS
ENV PYTHONIOENCODING=utf-8
WORKDIR /

# aws cli install
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" \
    && yum install -y unzip \
    && unzip awscliv2.zip \
    && ./aws/install \
    && amazon-linux-extras install python3.8 -y \
    && python3.8 -m pip install pillow==8.3.2 \
    && yum install -y less
    
RUN yum install -y wget tar gzip expect

# aws-nuke のダウンロード
RUN wget https://github.com/rebuy-de/aws-nuke/releases/download/v2.16.0/aws-nuke-v2.16.0-linux-amd64.tar.gz \
    && tar -zxvf aws-nuke-v2.16.0-linux-amd64.tar.gz

# nuke-config.yaml と実行スクリプトをコンテナに配置する
COPY nuke-config.yaml /
COPY Run-nuke.sh /

RUN chmod +x Run-nuke.sh

CMD ["/bin/sh", "Run-nuke.sh"]

AllDelete.sh :

AWS セキュリティ認証情報を登録したファイル (conf.ini, Credentials.csv) を読み込み、空きメモリーを監視しながら aws-nuke イメージを実行する

#!/bin/bash -ex
INI_FILE=conf.ini
INI_SECTION=Organizer_Account

# ini parser
eval `sed -e 's/[[:space:]]*\=[[:space:]]*/=/g' \
    -e 's/;.*$//' \
    -e 's/[[:space:]]*$//' \
    -e 's/^[[:space:]]*//' \
    -e "s/^\(.*\)=\([^\"']*\)$/\1=\"\2\"/" \
   < $INI_FILE \
    | sed -n -e "/^\[$INI_SECTION\]/,/^\s*\[/{/^[^;].*\=.*/p;}"`
    
OrganizationAccountId=${AccountId}

CREDENTIALS_FILE_NAME='Credentials.csv'
WORK_CREDENTIALS_FILE_NAME='./w_'$CREDENTIALS_FILE_NAME
cp $CREDENTIALS_FILE_NAME $WORK_CREDENTIALS_FILE_NAME
HEADER=`head -n 1 $WORK_CREDENTIALS_FILE_NAME`
sed -i -e '1d' $WORK_CREDENTIALS_FILE_NAME

while read credential; do
    echo "AWS_AccountId:" `echo ${credential} | cut -d , -f 5`
    
    while true; do
        FreeMemMB=`free -m | grep Mem | awk '{print $4}'`
        if [ $FreeMemMB -gt 100 ]; then
            break
        else
            echo "FreeMemMB" $FreeMemMB
            sleep 5
        fi
    done
    
    docker run -v `pwd`/AllDelete:/AllDelete \
        --env RootUserId=${OrganizationAccountId} \
        --env AWS_ACCESS_KEY_ID=`echo ${credential} | cut -d , -f 3` \
        --env AWS_SECRET_ACCESS_KEY=`echo ${credential} | cut -d , -f 4` \
        --env AWS_AccountId=`echo ${credential} | cut -d , -f 5` \
        nuke &
done < $WORK_CREDENTIALS_FILE_NAME

nuke-config.yaml : aws-nuke の設定ファイルのテンプレート

全てのリージョンを対象に、IAM 以外のリソースを削除する。

regions:
- us-west-1
- us-west-2
- us-east-2
- ap-south-1
- ap-northeast-1
- ap-northeast-2
- ap-northeast-3
- ap-southeast-1
- ap-southeast-2
- ca-central-1
- eu-central-1
- eu-north-1
- eu-west-1
- eu-west-2
- eu-west-3
- sa-east-1
- me-south-1
- ap-southeast-3
- af-south-1
- ap-east-1
- global

account-blocklist:
- "BlockID" # production

resource-types:
  excludes:
  - IAMRole
  - IAMRolePolicy
  - IAMRolePolicyAttachment
  - IAMUser
  - IAMUserAccessKey
  - IAMUserGroupAttachment
  - IAMLoginProfile
  - IAMGroup
  - IAMGroupPolicyAttachment
 
accounts:
  "TargetID": {} # aws-nuke-example

Run-nuke.sh : nuke-config.yaml を更新して対話型の aws-nuke を自動実行する。

#!/bin/bash -eu

mkdir -p AllDelete/${AWS_AccountId}

# 運営用アカウントを削除しないよう、nuke-config.yaml にaccount-blocklist を設定する
echo ${RootUserId}
sed -i -e "s/BlockID/${RootUserId}/" nuke-config.yaml
sed -i -e "s/TargetID/${AWS_AccountId}/" nuke-config.yaml

aws iam create-account-alias --account-alias ${AWS_AccountId}-test

script="""
    set timeout -1
    spawn bash -c \"./aws-nuke-v2.16.0-linux-amd64 -c ./nuke-config.yaml --access-key-id ${AWS_ACCESS_KEY_ID} --secret-access-key ${AWS_SECRET_ACCESS_KEY} --no-dry-run\"
    expect \"Do you want to continue? Enter account alias to continue.\"
    send -- \"${AWS_AccountId}-test\r\"
    expect \"Do you want to continue? Enter account alias to continue.\"
    send -- \"${AWS_AccountId}-test\r\"
    expect \"Nuke complete\"
    exit 0
"""

expect -c "$script" 2>&1 | tee /AllDelete/${AWS_AccountId}-log.txt

イベント実行後、コストが無事に 0 になっていることが確認できて一安心しました。
ちなみにコスト取得 API を開発し、日ごとのコストを取得できるようにしていました。


4. コストについて

今回のイベントのコストについて、108 名で 3 時間半実施してどのくらいの費用が掛かったと思いますか ? ずばり、723.85 USD です。1 チーム当たり 17.42 USD、初めてということで前日に準備しましたので、時間あたりに換算すると 0.67 USD / 時になりました。

運営に利用した「Minoru」のコストは、26.906 USD でした。この金額をどう考えますか?弊社としては、コンテストの予算として、数百万規模を想定していましたので、破格でした。特に EC2 インスタンス以外サービスのコストの安さには驚きました。


5. パフォーマンスと監視について

ここからは、サービスの提供にあたってユーザー体験に大きな影響を与えるパフォーマンスについて開発中に得た学びを 2 つご紹介したいと思います。

  • オブザーバビリティを活用したボトルネックの発見
  • Amazon API Gateway のレスポンスレイテンシーの改善について

5-1. オブザーバビリティを活用したボトルネックの発見

コンテスト本番中のエラーを把握するために Amazon CloudWatch と AWS X-Ray を使って、各サービスの連携を可視化してみたところ、アプリケーションの設計の見直しに繋がった気づきがありました。

まず、下図の Amazon CloudWatch のメトリクスから Lambda 関数 Properties-Function の実行時間が 2.5 秒を超えていて、他の関数より明らかに時間がかかっていることが分かりました。

そのため AWS X-Ray のトレースを確認してみたところ、AWS CloudFormation へのリクエストに時間が掛かっていることが分かりました。ソースコードを確認したところ、この AWS CloudFormation へのアクセスは AWS アカウント、リージョンを跨ぐもので、そのため、大きく遅延が発生しているものと推測しました。

また AWS CloudFormation のスタックから取得する出力セクションのデータはリアルタイム性を必要としないため、データベースに保存するなどの改善策を考えることができました。

クリックすると拡大します

5-2. Amazon API Gateway のレスポンスレイテンシーの改善について

次に、AWS X-Ray のサービスマップとトレースビューを利用してのパフォーマンス改善について紹介します。

こちらの図は Lambda 関数 Load-Function のサービスマップです。これをみると処理に 1 秒も掛かっていることが分かり、ユーザー体験に影響があったため、改善に取り組みました。

クリックすると拡大します

案 1. Lambda 関数のメモリーをスケールアップする

ログを確認すると下記のようにそもそもメモリを使いきれていなかったので効果が薄いのではないかと思いましたが、Lambda は割り当てるメモリーに比例して割り当てられる CPU も強化されます。

今回は、512 MB から 5120 MB にスケールアップして評価しました。しかし、メモリ割り当てを増やすとコストも上がってしまいます。この関数の場合は、処理時間 (Duration) が 1.0S から 737ms に改善されました。改善される処理時間と単位時間あたりのコスト増加は比較してコスト効率を検討する必要があります。

REPORT RequestId: c518157a-0c9c-4f77-a087-f9f0593bbbea Duration: 913.43 ms Billed Duration: 914 ms Memory Size: 512 MB Max Memory Used: 71 MB

XRAY TraceId: 1-61b2acad-5422ef6d7eed5deb52e3d981 SegmentId: 6ccf50315b9740a5 Sampled: true

参考: AWS Lambda よくある質問「Q: コンピューティングリソースはどのように AWS Lambda 関数に割り当てられるのですか?」 の項目

案 2. Amazon API Gateway を REST API から HTTP API へ変更する

下記のブログでは「HTTP API はレイテンシーを最大 60 % 削減します。」とありますが、現在、HTTP API は X-Ray との連携がサポートされていないので今回は選択肢から外しました。

高速、低コストで、より良いAPIの構築 – HTTP APIが利用可能(GA)になりました »

案 3. リージョン選定の見直し

開発中は us-east-1 米国東部 (バージニア北部) を利用していました。

なぜ us-east-1 米国東部 (バージニア北部) を利用していたかというと、安い、早い、うまいが 3 拍子揃っているからです。

  • 安いは、t2.micro のコストを比較すると
    us-east-1 米国東部 (バージニア北部) : 0.0116 USD / 時間
    ap-northeast-1 アジアパシフィック (東京) : 0.0152 USD / 時間
  • 早いは、対応サービス数
    us-east-1 米国東部 (バージニア北部) : 190
    ap-northeast-1 アジアパシフィック (東京) : 168
  • うまいは、ちょっと無理やりですが、us-east-1 だと、IAM Polilcy の制限をリージョン指定でかけてもグローバルサービスに影響しない権限の設計がしやすいです。

しかし、今回のケースでは「早い」は、レスポンスのレイテンシーで考えるべきです。
サービス設置先のリージョン選定のポイントとして物理的な距離は重要なポイントです。

参考までに計測した東京リージョンとのレスポンスタイムの比較は、

  • ap-northeast-2 アジアパシフィック (ソウル) : 39.32 ms
  • us-east-1 米国東部 (バージニア北部) : 160.83 ms

でした。

そして、東京リージョンに「Minoru」を移すと処理全体のレイテンシーが 613 ms にまで改善されました。そのため、今回はリージョンを東京リージョンに移動することで、レイテンシーを改善しました。

効果としてはクライアントから見たレスポンスタイムが 47 % に改善されました。

改善前
(クリックすると拡大します)

改善後
(クリックすると拡大します)


まとめ

今回、初めて設計から開発、検証、運用を行い、改めてこれまで学んできた知識が腹落ちしました。私の場合は、技能五輪の参加を目的として AWS の学習をはじめましたが、Web アプリケーションを自分自身で作り切るというのは貴重な経験と沢山の学びを得ることができ、これを作ること自体が「手の内化」につながる活動となったと考えています。まだまだ未熟ですが、これからも慢心せず、精進します。

この記事が「新しい挑戦をしてみよう !」と思うきっかけになっていただければ幸いです。


builders.flash メールメンバーへ登録することで
AWS のベストプラクティスを毎月無料でお試しいただけます


筆者プロフィール

濵﨑 智宏
株式会社デンソー コアスキル開発部 

WorldSkills Kazan 2019 に出場後、後進育成をしています。有志活動として社内のクラウドエンジニア育成にも取り組んでします。

AWS を無料でお試しいただけます

AWS 無料利用枠の詳細はこちら ≫
5 ステップでアカウント作成できます
無料サインアップ ≫
ご不明な点がおありですか?
日本担当チームへ相談する