日々のあれこれφ(..)

もっぱら壁打ち

AWS認定DevOpsエンジニアプロフェッショナル受験した

取りました✌️

f:id:reiichii:20210321120847p:plain

f:id:reiichii:20210321120859p:plain

AWS認定 DevOps エンジニア - プロフェッショナル(DOP)とは

AWS上で動くアプリケーションシステムのプロビジョニング、運用、および管理に関する技術知識を問うもので、以下のような分野の問題が選択式で出ます。

  • SDLC(ソフトウェア開発サイクル)の自動化
    • 例)CodeCommitのmainブランチのコードは自動でECRに公開される。Blue/GreenデプロイでECSにこれをデプロイするには?
  • 構成管理および Infrastructure as Code
    • 例)CodePipelineからCodeDeployでLambdaをデプロイするにあたって、10分間カナリアをデプロイし、クラッシュが多ければ自動ロールバックするには?
  • 監視およびロギング
    • 例)自社が所有している複数アカウントに対してCloudTrailが常に有効になっていることを確認し、万一無効にされた時は自動で回復するには?
  • ポリシーと標準の自動化
    • 例)社内でアーキテクチャとタグ付けのルールを確立している。AWS初心者の社員が非準拠リソースを起動するリスクを最小限にするには?
  • インシデントおよびイベントへの対応
    • 例)ASGに紐づくEC2インスタンス群があり、CodeDeployでローリングアップデートを行うが、5つ中3つのみが更新されており、残りは古いバージョンだった。この問題の原因は?
  • 高可用性、フォールトトレランス、およびディザスタリカバリ
    • 例)Auroraでアメリカにサービスを展開している。これをヨーロッパにも展開したい。商品カタログテーブルにはグローバルにアクセスしたいが、ユーザーテーブルと購入履歴テーブルはリージョナブルにアクセスできるようにするには?

受験の動機

業務と興味関心が近い領域で新しい知識をインプットしたいなと漠然と思っていました。その中でも自社はメインでAWSを使っているので、DevOpsプロフェッショナルで普段触らないサービスとその使い方を知れれば何か業務に活かせるかなという期待感で受験することにしました。

...というのが真面目な理由で、もう一つは評価シートの個人目標に書いてしまったからです。

勉強したこと

基本的な方針としては、問題を解いて不足を感じた部分があればドキュメントやBlackBeltの資料で補う、と行った形です。

問題は以下のものを解きました。

上三つは公式ガイドラインで紹介されている流れに沿ったものです。Udemyのは他の方の受験記で知って良さげだったので購入しました。

最初に解いたサンプル問題の正答率は3/10、模試の正答率は35%となかなか絶望的だったので、Udemyの方もやっておいて良かったです。

受験の時の話

ピアソンVUEで申し込み、テストセンターに行って受けました。本当は自宅で受けたかったのですが、申し込もうとした時には全然空いておらず...。受けたい日の2週間〜1ヵ月前に申し込んでおくべきだったなという反省はあります。

それから地味に結婚による改名手続きにハマりました。こんなところでもクラメソさんの記事にお世話になるとは思いませんでした笑

dev.classmethod.jp

2日後くらいに変更が反映されたので事無きを得ました。

3時間で75問を解かないといけなかったのですが、2時間で75問目までたどり着けたので残りの1時間でたっぷり見直しができました。

感想

今の会社に入社する前、業務経験がほぼない状態でソリューションアーキテクトアソシエイトを勉強して受験した時はギリギリで合格していたので、2年の業務経験が活かされたのかなと思う反面、普段使うサービスは限られているのでやっぱり勉強しないとキツいですね笑

私の場合はECSやASGはよく触っていたので馴染みはありましたが、ElasticBeanstalkとかCloudFormationはそんなに凝った使い方をしたことがなかったので結構苦労しました。

(経費で出るとはいえ)3万掛けて受けて落ちた時のことを考えると憂鬱でたまりませんが、問題解くこと自体は「こういう使い方ができるのか〜」とか「これ自社でやるの良さそうかも」なんて考えながらできて楽しかったです😃

勉強会の時にCodeSandboxを使ってサンプルコードを公開した

今週の社内プチ勉強会は私の発表だったので、Vue.js入門と称して簡単な紹介と単一ファイルコンポーネント×Atomic Designに落とし込んだ構成が触りやすくて良かったよという話をしてきました。

せっかくJavaScriptを紹介するのだから、やっぱり動くものベースで見せられた方がいいよなぁとCodeSandboxでサンプルコードを書いて、所々それを用いて話す形にしてみました。

codesandbox.io

CodeSandbox初めて使ったのですが、GitHubに作ったリポジトリをそのまま取り込むこともでき、便利でした😃

せっかくなのでそのSandboxだけブログにも残しておこうと思います。

affectionate-frost-3o69y - CodeSandbox

ブラウザではなく右側のurlフォームに各htmlファイルの名前を入力していただけるとコードの動作確認ができるので、Vue.js興味ある人はドキュメントを参考にしながらいじってみてください。

「データマネジメントが30分でわかる本」を読んだ

www.amazon.co.jp

実際には30分では分かりませんが、だいたい4時間くらいでデータマネジメントをするにあたって出てくる問題や要素などの全体像を見渡せるライトな本でした。

手に取った理由

仕事でデータを扱う部分に携わる機会が多くなり、その中でデータの扱い方に関してこれでいいのかといった言語化できない不安を抱いていました。 この本を見つけたのは偶々だったのですが「データマネジメント」「場当たり対応止めませんか」の文言が刺さりました😅

この本は有志のメンバーが自費出版したものなのですが、以下のような点が良かったので購入を決めました。

  • メインの執筆者がフルスタックエンジニアで、私のようなシステムを管理するレイヤーからデータを利用する側のレイヤーまで網羅的にカバーされている
  • データマネジメントの専門書の内容を元に構成されている
  • ことに加えて、実際に現場でどう実施したかという具体的な事例が合わせて載っている
    • この本をインデックスに、より深く知りたいところをDMBOK本を読んでいけばいいんじゃないかと思ったり

読書メモ

1章:データアーキテクチャ

  • データアーキテクチャとは、データとビジネスのつながりを可視化したもの

    • あるデータがどの業務に貢献しているのか
    • あるビジネスがどんなデータに依存しているのか
  • アーキテクチャ作成時に抑えること

    • どこからデータが取られているか
    • どこに保存しているか
    • どのビジネスで使われているのか
  • データアーキテクチャを作成することで現状を把握し、それを元に理想を描き、理想図から得られるビジネス価値を確認した上で改善策を練っていくことが必要

筆者が経験した具体的事例としてパワポの資料が載せられていた。「部署」「利用用途」「データの種類と利用用途ごとにCRUD必要な操作をまとめたもの」など自分が想像していたよりもざっくりしたものだった。

2章:データストレージとオペレーション

  • DBの選定、管理、運用を行い信頼できるデータを提供することが目的
  • 候補となるDBの特徴が業務要求に合致しているか
  • 業務ニーズを理解してデータの保存、活用、移動などの要件を満たせるようにアプリケーションの開発を行う
  • データの重要性とのバランスを取る
    • 例えば筆者の例の場合、スタートアップ時にはSoEの思想でBigQueryとGASで簡易的なシステムを開発し、スケール時にはSoR思想のWebAPI + RDS構成に移行した
    • SoE:System of Engagement。体験重視。
    • SoR:System of Record。記録重視

3章:データ統合と相互運用性

  • ELTを効率的に管理できるようにする
    • ELT:Extact(抽出)、Transform(変換)、Load(取り込み)
  • 利用者とシステムを仲介するハブになり、アクセス権限を適切にしたり、過剰リクエストやご集計を防ぐなどで双方の負担を軽減する
    • 利用者:シンプルで便利なデータを見たい
    • システム:事業成長によって量と種類が増える。複数のデータソースが分散している状態にある
  • 必要なフォーマットとタイミングで安全に提供できるようにする
  • 共通のモデルとインターフェースを開発し、統合にかかるコストと複雑さを削減する
  • 重要なイベントを検知できるようにアラートとアクションを定義する
  • 業務要件を明確にし、求められる更新頻度によってバッチ、ストリーミング、APIスクレイピングなどどれがいいのか判断する。

4章:データモデリングとデザイン

  • データ同士の関係性を図に示すこと

  • データモデルは以下3つの粒度に分けられる

    • 概念モデル:e.g. 学校は学生を在籍させるので、学校一覧と学生一覧のデータが紐付く
    • 論理モデル:e.g. 学校一覧には学校コードと学校名が含まれる。学生一覧には学生番号と在籍している学校コード、学生氏名が含まれる。学校一覧と学生一覧は学校コードを介して紐付く
    • 物理モデル:e.g. 論理モデルをDB上のテーブルとして表現したER図のようなもの
  • 概念モデルを作るとしたら、データアーキテクチャから紐解くのが一番得策

  • メタデータとして保存し、いつ誰がどのように更新するか決める必要もある
  • 作る時の注意点としては、問い合わせや法令遵守など、見えにくい部分を抜かさないようにすること

  • 具体例として、データモデル設計をモデルストーミング手法を用いて行なった話が挙げられていた

    • モデルストーミング手法:ホワイトボードや紙に書き出しながらブレインストーミングの要領で集計用のデータモデルを設計する。Agile Datawarehouse Design本で紹介されているやり方
    • コツ:データの網羅性にこだわらない。最初に全てのテーブルを設計するのはウォーターフォール開発の発想であって、モデルストーミング手法では必要なものから正しく小さく作るべきとされている
  • データモデルのタイプ:スタースキーマ

    • ファクト:関心対象となるイベントの発生を1レコードで表現
    • ディメンション:分析の切り口となる属性値(イベント発生の場所や時間など5W1H + How manyで表せそうなもの)
  • データモデルは継続的に見直すもの

5章:マスターデータ管理

  • マスターデータ:一貫して欠損がない信頼できるデータ。顧客データや都道府県コードの変換表など
  • 複数からの参照に耐えうるマスターデータを管理するには、
    • データ定義の所有者や責任の所在を決める(責任:最新で完全であることに)
    • データの変更プロセスを定義する。
      • 完全で最新であることを担保するために、変更したいデータはどこから取得するか、検証する方法、既存のマスターデータをどのように整形するのか、見直すタイミングはいつか、こういったもののプロセスを決める
    • ELTの一要素として実装する
    • SLAと評価尺度を決める。
    • 鮮度の保証を決める。決めるに当たってどのくらい参照されているのかを計り、需要と照らし合わせて決める
  • 利用を促すガバナンスルールを整備する

6章:ドキュメントとコンテンツ管理

  • 非構造データ:DB外にある否定形なデータ。例えばプロジェクト計画が書かれたword、予算計画が書かれたexcelなど
  • これらを管理することでセキュリティ対策を行う

  • これを行うには以下のようなアクションが必要になる

    • 散らばっているデータがどこにあって、何かを調査する。内容を社内wikiなどで検索しやすい環境に集約する。作業の大半がこれになる
    • 管理のためのモチベーション作り
    • 非構造データを表形式で紐付ける。ドキュメントの用途や属性で検索、抽出を可能にする
      • e.g. 情報システム資産台帳
  • 筆者がやったこと

    • とりあえず社内wikiの個人ページに残し、書いたか関係者に見てもらう
    • 質問を受けて「ここに書いたよ」といったやりとりが3回されたら、個人ページから適切な場所に移す
    • そのドキュメントについて質問を受けることで、閲覧者の視点を把握する
    • 気になる点があったら読み手に修正してもらう
    • 上記のようなことを少数チームで運用して、土台とサンプルができたら全社に広める

7章:データセキュリティ

  • データセキュリティのインシデントのほとんどは、そのデータの危険度が知られていないことから起こる

  • 主なtodo

    • 適切なアクセス権限を設定する
    • 規則とポリシーを理解する
    • 機密に関する全てのステークホルダーの要求が実行され、監視されていることを保証する
  • データセキュリティを守るためにやるべきこと

    • 組織がどんなデータを持っているのか特定する
    • データのセキュリティレベルや規定カテゴリ(PIP、財務データなど)を決める
    • セキュリティレベルをメタデータとして保存し、定期的に見直す
  • セキュリティ要件の担保を開発工程に組み込むなどの取り組みも必要になる

8章:データ品質

  • データ品質とは:使う人の要求を満たせているかどうか
  • データ品質の基準、要件、使用を定義する
  • レベルを測定・監視・報告書を作るプロセスを定義する
  • ニーズに合致するデータを定義する
    • 全部の品質をやみくもに高くするのではなく、優先的に品質が求められるデータをはっきりさせる
    • そのために部署、用途ごとに期待されているサービスレベルを可視化し、参照頻度に合わせて品質を定義する。使っていないデータに時間を使わないようにするため

9章:DWHとBI

  • 業務分析と意思決定を支えるデータを提供するためのもの
    • ツールを導入しレポーティングの自動化を行なったり
  • そのためにやること

    • 支援対象となる業務分析案件を理解する
      • 誰がどんな目的でどんなデータを見たいのか
    • 提供に必要な技術環境と業務プロセスを構築する
      • データソース選定とシステム開発
      • 運用チームを作ってアラートやデータ検証の自動化をする
    • 利用者が効果的な分析と意思決定をおこなるように支援する
  • CIF:Corperation、Information、Factory

  • データの活用促進をする7ステップ

    1. どのチーム・担当者がどのくらい活用しているのかアクセスログを取る
    2. チームごとのデータ利用状況をマッピングする
    3. ↑を元にターゲットの優先度を決める
    4. 対象チームが行なった施策の効果を測定する
    5. 結果を踏まえて次のアクションを行う
    6. 地道なハンズオン
    7. 業務フローに分析工程を組み込む

多くの場合、データ活用よりも経営と現場業務を立て直すことが急務だったりする (刺さる...)

10章:メタデータの管理

  • 利用者がデータを見つけやすくするためのもの
  • 業務用語とその利用法に関する組織の理解を提供
  • 様々なソースのメタデータを収集し、統合する
  • メタデータにアクセスするための標準的な方法を提供する

  • メタデータの分離

    • ビジネス:内容と状態・入力規則と測定結果
    • テクニカル:技術的詳細やシステムに重点。テーブル名・カラム名・アクセス権
    • オペレーショナル:処理・アクセスの詳細・最終更新時間・エラーログなど
  • メタデータの管理はほとんど挫折しているとの記述があった

    • 開発が追いつかなかったり、ビジネスに直接貢献しにくい分野だから景気などで耐性変動のあおりを受け易かったりと
    • 筆者曰く、結局はドキュメントでカバーする問題なのではという結論になっていた

11章:データガバナンス

  • 組織の中でデータマネジメントを強化していくにあたって、組織、案件、プロセス、システムにガバナンスを効かせる必要がある

おわりに

業務のモチベーションとはまた別に、少し前に話題になっていたワークマンのエクセル経営の記事が印象に残っていて、数字ベースで自組織をちゃんと見れるようになりたいなと思うようになったのも読書のモチベーションの一つだったかもしれません。

今の状態だと机上の空論になりかねないので自分でできる範囲で何かしらのアウトプットを出したい...(データアーキテクチャの概要図まとめるくらいだったらできそう?)

Pydantic モデルのクラス変数に参照して加工した値を定義したい

Pydantic使っていた時に行き当たったちょっとした悩みをネットの海に放っておくといった趣旨の記事です。

やりたかったこと

やりたいことは以下でした。(うまい例は思い浮かばなかった)

  • 商品名(name)、金額(amount)、保存先ファイル名(destination)をjson形式でファイルとログに出力する
  • 商品名(name)、金額(amount)はリクエストで受け取ったものを入れる
  • ファイル名は商品名_日付を入れる(e.g. keyboard_20210211)

そこでPydanticで出力したい値をクラス変数にもったBaseModel: Purchaseクラスを作っていました。

悩んだこととしては、ファイル名をどうやって持たせるかでした。

最悪model.dict()で出力した後に追加するを考えていましたが、せっかくModelを用意したのにこれでは綺麗じゃないから避けたかったです。

import datetime

from typing import Any, Dict, Optional

from pydantic import BaseModel, Field


class Purchase(BaseModel):
    name: str = Field(..., min_length=1)
    amount: int = Field(..., ge=0)
    destination: Optional[int] = None

    def filename(self) -> str:
        d = datetime.date.today()
        return self.name + '_' + d.strftime('%Y%m%d')


def main() -> Dict[str, Any]:
    # リクエストボディの値を渡す
    purchase = Purchase(
        name="keyboard",
        amount=5000,
    )

    # purchaseインスタンスを生成するタイミングでdestinationも入って欲しい
    output = purchase.dict()
    output['destination'] = purchase.filename()

    return output


if __name__ == '__main__':
    print(main())

実現方法

root_validatorsを使えばやりたいことできるかもよと教えてもらいました。

pydanticのvalidator

インスタンスが生成されるタイミングでデコレータで指定した変数のチェックを行える。

class Purchase(BaseModel):
    name: str = Field(..., min_length=1)
    amount: int = Field(..., ge=0)
    destination: Optional[int] = None

    @validator('*')
    def hoge(cls, v):
        print(f'hoge: {v}')
        return v


# 実行結果
# hoge: keyboard
# hoge: 5000
# {'name': 'keyboard', 'amount': 5000, 'destination': 'keyboard_20210211'}

root_validator

root_validatorを使うと全クラス変数を参照できるようになります。

class Purchase(BaseModel):
    name: str = Field(..., min_length=1)
    amount: int = Field(..., ge=0)
    destination: Optional[int] = None

    @root_validator()
    def fuga(cls, values):
        print(f'fuga: {values}')
        return values

# 実行結果
# fuga: {'name': 'keyboard', 'amount': 5000, 'destination': None}
# {'name': 'keyboard', 'amount': 5000, 'destination': 'keyboard_20210211'}

今回やったこと

filename()をroot_validatorの中で実装させるようにしました。

import datetime

from typing import Any, Dict, Optional

from pydantic import BaseModel, Field, root_validator


class Purchase(BaseModel):
    name: str = Field(..., min_length=1)
    amount: int = Field(..., ge=0)
    destination: Optional[int] = None

    @root_validator() # 追記
    def filename(cls, values: dict) -> Dict[Any, Any]:
        d = datetime.date.today()
        values['destination'] = values['name'] + '_' + d.strftime('%Y%m%d')
        return values


def main() -> Dict[str, Any]:
    # リクエストボディの値を渡す
    purchase = Purchase(
        name="keyboard",
        amount=5000,
    )

    return purchase.dict()


if __name__ == '__main__':
    print(main())

おわりに

ひとまず微妙な書き方をせずには済みました。

ただ検証を行うところでこういうのをやってしまってよかったのか🤔

Python Context Managerを調べた時のメモ

完全に理解できた自信はないのですが、整理のため一旦調べたことをまとめます。

Python 3.8.1

きっかけ

@contextlib.contextmanagerを使ってDBへの接続の処理を実装しているメソッドがありました。この書き方は初めて見たので、今後自分でも必要に応じて使えるようにするために調べました。

コンテキストマネージャーとは

そもそもコンテキストマネージャーって何だという所から始まったのですが、コンテキストマネージャーだけでぐぐるとコンピュータ関係の他の用語としての説明も出てきます。Pythonでも同じ意味で使われているのか判断しかねたのですが、Pythonの場合そういった用語の定義もPEPで確認できました。

PEP0343

このPEPは、__ enter __()メソッドと__exit __()メソッドで構成されるプロトコルを「コンテキスト管理プロトコル」と呼び、そのプロトコルを実装するオブジェクトを「コンテキストマネージャー」と呼ぶことを提案しています。

3. データモデル — Python 3.9.1 ドキュメント

コードブロックを実行するために必要な入り口および出口の処理を扱います。コンテキストマネージャは通常、 with 文( with 文 の章を参照)により起動されますが、これらのメソッドを直接呼び出すことで起動することもできます。

通称with文から起動される。

代表的な使い方としては、様々なグローバル情報の保存および更新、リソースのロックとアンロック、ファイルのオープンとクローズなどが挙げられます。

Python入門などで、ファイルを扱うに必要な以下の処理をwithを使って描くとシンプルに描けると習いましたが、try,finallyで行なっているものをwith文ではコンテキストマネージャーの__ enter __() __exit __()で実現しています。

try:
    f = open('test.txt')
    print(f.read())
finally:
    f.close()
with open('test.txt') as f:
    print(f.read())

open()のようなある処理の前後に何かを行わせるようにしたい処理を実装するにはクラスに__enter__()__exit__()メソッドを使って挙動を定義する必要がありますが、 @contextlib.contextmanagerデコレータを使うとデコレートされたメソッドでこれを実現することができます。

▼普通に実装した時

class MyContextManager:

    def __enter__(self):
        print('ENTER!')
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        print('EXIT!')

with MyContextManager() as cm:
    print(cm)
ENTER!
<__main__.MyContextManager object at 0x102f91f70>
EXIT!

▼@contextlib.contextmanagerデコレータを使った時

from contextlib import contextmanager, closing


@contextmanager
def mycontextmanager():
    print('ENTER!')
    yield 'yield'
    print('EXIT!')

with mycontextmanager() as cm:
    print(cm)
ENTER!
yield
EXIT!

@contextmanagerが実装されたクラスは、必ずイテレーターかジェネレーターを返す必要があります。

見ての通り、def mycontextmanager()のyieldが呼ばれたらdef mycontextmanager()の処理は中断され、with文内の処理が走ります。それが終わったら中断されていたdef mycontextmanager()内の処理が再開するといった形です。

おわりに

with open()はよく書いていましたが、内部の処理については調べたことなかったので勉強になりました。

ブログのcssにちょこっと手を入れた

今年の目標の一つが、放置しっぱなしだったブログを愛着の持てるブログに育てることが目標です。

それをするにあたってデザインで少し気になっていた部分に手を加えることにしました。

今使っているデザインについて

一つの項目を作って説明するほどのものはないのですが、はてなブログ公式テーマのNeutralを使っています。(昨日まではSmoothを使っていました...w これも公式のやつです)

飽きっぽいのでシンプルなものにしたい、方向性が自分の中で固まっていない、といった理由で上記のテーマを設定しており、なんだかんだで気に入っているので使い続けているのですが、使い続けている内に「ここもう少しこうならないかな」みたいな欲が出てきました。

記事表示部分の横幅をもう少し広くしたい

↓いつも使っている23.8インチのモニターで表示した時

f:id:reiichii:20210117133349p:plain

↓いつも使っているMacBook Pro 13インチで表示した時

f:id:reiichii:20210117134649p:plain

もう少し横幅が欲しいなというところで、以下のように設定しました

#content-inner #main {
    width: 800px;
}

元が620pxで定義されていたので、+180された形になります。

なぜ800pxにしのかというと、PC版ウェブサイトの横幅が標準どのくらい設定されているのか複数のサイトを参考にしたところ1000px前後で設定されていることが多いみたいでした。サイドバーが268pxほどだったのでもう少し広くてもいいはずと思い、この値にした形です。

というか単位pxでいいのか、vw/vhとかに変えたほうがいいんじゃないかとも思ったのですが、このテンプレートの場合他もpx単位になっていたりするので一旦既存のやり方に乗っかることにします...。問題が生じたら対策を考えよう...。

h2に下線を付けたい

f:id:reiichii:20210117140101p:plain

記事のタイトルにh1が使われるので、ブログ本文の中ではh2、h3をよく使います。しかし記事の途中で単体で出ると「これはどちらなんだろう」と分からなくなることが多々あります。記事を読むときは少なからず全体の構成を頭の片隅に入れておきたいのでh2に下線などあると嬉しい人です。(右側にtable contentsを付けておくなど表現方法は他にも色々ありますが)

そんなわけで以下の設定を追加しました。

.entry-content h2 {
  padding-bottom: 10px;
  border-bottom: 5px solid #ddd;
}

インラインコードの背景を黒ではなくグレーにしたい

f:id:reiichii:20210117140332p:plain

コード挿入時の背景が黒なんだから同じ色でいいじゃないという気もするのですが、私のブログは背景白ベースで行く予定なので、インラインコードまで黒だと主張がいささか強過ぎる気もしました。なのでSmoothテーマで使っていた時と同じグレーにします

.entry .entry-inner p code {
  background-color: rgba(0,0,0,.03);
  color: #3d4245;
}

おわりに

cssはもともとあまり得意ではないのですが、Google developper toolを触れるようになってからは調査や調整がすごくやりやすくなって本当に有り難い限りです。

今のデザインも気に入っているのですが、今後はもう少し個人の色とかも出していきたいと思っているので、またアイデアが生まれたらどんどんカスタマイズしていきたいと思います。

CloudFormationでLambdaをデプロイする

AWS認定 DevOpsエンジニア - プロフェッショナルを受験しようかなと考えていて、サンプル問題を解きました。

AWS-Certified-DevOps-Engineer-Professional_Sample-Questions.pdf

成績は3/10問、解説を読みながら「いやこの問題解けたな」と思ったものが2問だったので合格にはそれなりに勉強が必要そうです🙂

そのサンプル問題の(5)を実際に手を動かして確認したいなと思ったので簡単にコードを書きました。

reiichii/sample-lambda-cfn

以下復習した時のメモです。

問題

(5) DevOps エンジニアが、AWS Lambda 関数を記述し、この Lambda 関数を AWS CloudFormation テンプレートスニペット内で指定し (下記参照)、このテンプレートを Amazon S3 バケットに格納しました。

MyLambdaFunctionV1:
  Type:"AWS::Lambda::Function"
  Properties:
    Handler:"index.handler"
    Role:"arn:aws:iam::515290864834:role/AccountScanner"
    Code:
      S3Bucket:"johndoe-com-lambda-source"
      S3Key:"AccountScanner.zip"
    Runtime:"dotnetcore2.1"
    Timeout:60

CloudFormation スタックが作成され、Lambda 関数が想定どおりに動作しています。DevOps エンジニアは、関数コードの新バージョンを入手したので、スタック更新後すぐに新バージョンが実行されるようにしたいと考えています。

この要件を満たすには、どのように展開すればよいですか (3 つ選択してください)。

A) CloudFormation テンプレート内の Lambda 関数の論理名を MyLambdaFunctionV1 か ら MyLambdaFunctionV2 に変更し、CloudFormation スタックを更新する。

B) 既存の S3 バケットにおいてバージョニングを有効化する。新しいコードを既存の S3 バケットにアップ ロードする。CloudFormation テンプレート内の Lambda 関数の S3ObjectVersion プロパティで、S3 オ ブジェクトのバージョン ID を指定し、その後 CloudFormation スタックを更新する。

C) AWS SAM を使用して、sam deploy コマンドを CloudFormation テンプレートに対して発行し、Lambda 関 数のバージョンを更新する。

D) CloudFormation テンプレート内の Lambda 関数の S3 バケットプロパティ値を、別のバケット場所を指すよ う変更する。新しいコードを新しい S3 バケット場所にアップロードする。CloudFormation スタックを更新 する。

E) CloudFormation テンプレート内の Lambda 関数の S3Key プロパティ値を、別の場所および名前の .zip ファイルを指すよう変更する。新しいコードを新しい S3 バケット場所にアップロードする。その際、.zip ファイルの場所と名前を変更したことに留意する。その後、CloudFormation スタックを更新する。

F) サーバーレスフレームワークを使用して、serverless deploy function -f MyLambdaFunctionV1 コマンドを発行し、既存の Lambda 関数を更新する。

復習

正解

正解はB、D、E

B.以下のようにtemplate.ymlを変更します

      Code:
        S3Bucket: "{S3Bucket}"
        S3Key: "SampleLambda.zip"
        S3ObjectVersion: "{S3ObjectVersion}" # 追記

こうすることでソースコードの変更が検知され、該当部分の更新が行われるようになります。(cfnの変更セットのプレビューで以下のように確認できる)

f:id:reiichii:20210113092616p:plain

アクションがModifyになっていて、変更リソースはLambda function、置換がfalseとリソースの削除が伴わない変更なので「スタック更新後すぐに新バージョンが実行される」状態になっています。

D.上記のコードの S3Bucket 値を変更した形になります。このテンプレートに置き換えることによって上記の変更プレビューと同じような結果が得られます。

E.上記のコードの S3Key 値を変更した形になります。この変更でも上記の変更プレビューと同じような結果が得られます。

不正解

A.このやり方でスタックの更新を行うと、MyLambdaFunctionV1が削除されたのちMyLambdaFunctionV2が作成され、リソースの作り直しが行われます。(依存関係にあるリソースが削除されたりなど)

C.AWS SAMとはServerless Application Modelの略です。 AWSが提供しているサーバーレスアプリケーションのテンプレートのようなものだそうです。AWS SAMにはcliが提供されていて、コマンド2つほどでAPI Gateway × Lambdaの構成のアプリケーションがデプロイできるようでした。

私は全然知らなかったのですが、AWS SAMは他の問題文や解凍群の中にもちらほら登場していました。

今回の場合、AWS SAMで作られたものではないので、sam deploy コマンドでデプロイできるようにするためには作り直す必要がでてきます。

F.もCと同じく、serverlessを用いたものに作り直す必要があります。

おわりに

cfnもLambdaも触ったことはあったので、実際にものを作って動かしたらそんなに難しい問題ではなかったですね😅 自分なりに理解は深められたので良しとします。

実際に本番環境をこの組み合わせで管理することになったら、S3のバージョニングで管理するのが良さそうだなと思ったり。ソースコードはGitで管理することになると思うので。