koboriakira.com

Week40

2020/10/10

今週のアウトプット

  • Cloud Run + FastAPI ( + Firestore)のテンプレートを作成する
  • みずほ銀行の株価予想プログラム
  • Reactまわりを勉強する -> 実施中
  • 追加
  • 新日本プロレスワールドの検索システムを開発しはじめる

週の前半は旅行に出かけていたので、今週はかるく開発したぐらい。

ReactはReact Hooksを勉強できたことがよかった。useStateuseEffectの基礎を覚えたのが、たぶんもう少し勉強が必要そう。

そしてTypeScriptを完全に忘れていたことに驚いた。CRAをTypeScriptでやるとエラーしか出ないので、ちょっと基礎を復習しないといけない。

2020年10月3日、土曜日

久々に遅い起床。ちょうどBが寝ていたので、一人でコーヒーを淹れていたらBの泣き声。育児マンガみたいな展開だった。

朝のうちに『脱力タイムズ』を見ながら週次レビュー。今週はReactをガッツリやろうと思った。とくにReact HooksとCSSフレームワーク(Material-UI)を勉強しないと、作りたいものは作れなさそう。またCloud Run+FastAPIのテンプレートを作ってみたいなと思った。


昼は新設される保育園の説明会に出席して(予想通り自分以外は女性だった。だから何か意味がある訳ではないけど)、帰宅後はBと遊びながらReact Hooksのことをイメージする(ドキュメントを読む余裕がなかった)。

夜になってすこし時間ができたので、ReduxからContext API with Hooksへを参考にさせてもらいつつ、実験。


パッカーズ関連のニュースをザックリ取得してPACKERSFUNに出したいなと思い、RSSフィードとGoogle翻訳を使って、今日の記事一覧をMarkdownとして書き出せるようにした。

2020年10月4日、日曜日

生活リズムを戻して起床。

Bと遊んだり、うんちを拭いたりしつつ、昨日つくったパッカーズ関連ニュースを読む。RSSフィーダーで取得することもできたのだけれど、自分でつくったものは、

  • Slack通知できる
  • タイトル、サマリをGoogle翻訳してくれる

というメリットがあり、そのおかげで「あ、これは面白そう」という記事にアクセスしやすくなった。

ためしにこれを利用して30分で「今日のパッカーズ」をPACKERSFUNに投稿。


翻訳ツールがある程度完成。そのなかでReact Hooksを理解した。「stateを使うならクラスコンポーネント」と思っていたけれど、関数コンポーネントにstateを”Hook”できるわけね、と理解した。

またCORSについてもなんとなく対応できた。single requestとpreflight requestの違いを知らないといけないのが初心者には結構つらそう。

2020年10月5日、月曜日

起床してBにミルクを飲ませたり、一緒にヒップホップを聴いたりしたあと(遅めのビートに絞って一緒に踊った)、今週のサンデーナイトフットボールを視聴。49ers対イーグルス。イーグルスが勝つとは思ってなかった。49ersはQBガロポロの不在がそのまま影響してる。

翻訳ツールはDEV.TOに対応させる。ReactやVS Codeに関する記事を読んだ

昼から配偶者に代わってもらい箱根へ。

以前から予定していた通り、2日間の休暇をもらって一人で旅行。どこかに出歩く気にもならないので、サウナ併設の旅館に泊まってのんびりする計画。

東海道本線でビールを飲みつつ(最近糖質制限の期間に入ったのでビールは久しぶり。こんなにエビスって美味しかったっけ?)、NFLの他試合のハイライトを見たりしながら移動。

ふと思い立ってiriとeillに関するnoteを書きすすめた。もうちょっと書けたら公開してしまおう。


夕方前に旅館に着。温泉とサウナに入って、しばらくボーっとする。18時に夕食。部屋に戻ってからは買っておいたアルコール類をデタラメに飲んで就寝。

2020年10月6日、火曜日

久しぶりに一人で目覚める。昨晩はたっぷり飲んで、そしてたっぷり寝た。気分がいいのでインスタントコーヒーに久しぶりに砂糖を入れて飲む。コンビニのインスタントコーヒーは、冷めると焼き芋みたいな味と香りがすることを思い出した。

PACKERSFUNの更新をしたあと、チーフス対ペイトリオッツ戦を見ながらKAGOYAに置いていたアプリケーションのCloud Run移行作業をする。ChromeDriverを使っているものがあり移行が大変だったのだが、すこしずつ学習しながらなんとか完了しそうなところまで。

パッカーズ対ファルコンズの時間になったので切り替えて応援。今回は余裕だった。次週はバイウィークなのでちょっとさみしい。


試合が終わるともう13時を過ぎていたので外に出て、ビールを飲みながら(外で歩きながら飲むビールはスーパードライに限る。コーンスターチが入っているのがいいのかしら)箱根まわりを散策。平日なので人が少なくて、すれ違うのは老夫婦か学生が多い。

旅館に戻ってからは、また温泉に行ってサウナと沐浴の往復。

私は基本的に「緊張」が多く、そのぶん「脱力」するのに時間がかかる。だからサウナと沐浴を繰り返しやって、やっと精神に柔軟性が出はじめる。やるたびに「脱力」の大切さだったり、もうちょっと頻度を増やしたほうがいいよなー、など思う。

ちなみにうちのBを見てると、常に脱力できているのがわかる。脱力に関しては彼がいちばんの教師だ。

部屋に戻って、今朝進めていた作業のつづき。またPACKERSFUNの試合結果も更新。

今日やりたいことはすべて終わったので、今日も適当に飲みながら『アメトーーク』を観たり、新日本プロレスワールドを観たりした。ウィダインゼリーみたいな容器に入ったご当地ワインが、パッケージ込みでとても良かった。

そういえば新日本プロレスワールドの検索システムがどうにも使いづらくて困っていることを思い出した。どうにかできないかとメモしたところで酔いが回ってきたので就寝。

2020年10月7日、水曜日

久しぶりに二日酔いに似た感覚を覚えながら起床。すぐ朝ごはんをいただいて、空きがあったので貸切風呂も使わせてもらう。チェックアウトして、お土産を買って帰路につく(箱根てぃらみすを買おうと思っていたら今日は定休日だった。自分のくじ運の良さを忘れてた)。


GoToトラベルの感想。

混まなそうな平日を狙ったこともあり、とても気分よく過ごせた。そもそも出歩く予定でなかったらホテルにほぼいたけれど、温泉がほぼ貸切に近かったので、ゆっくりサウナと沐浴ができた(寝転がってやりたい派なので、人がいないのは本当にありがたい)。

もうホテル側もある程度業務フローが定着したのだろう。こちらは初めての「コロナ禍の旅行」なので変化を感じることは多くあったけれど、とくに違和感はなかった。なんなら夕食に最初からご飯が置かれているので、好きなタイミングでご飯を食べれた(たまたまご飯が食べたくて仕方なかったので嬉しかった)。

割引はされるし、3000円分のクーポンも使えるし(土産代or酒代に消えた)、余裕があるなら使うべきサービスだ。ここで使ったお金が巡ってくれればいいなと思う。Bを連れて行ける近場の旅館も探そう。


帰りの車内でPACKERSFUNの記事を書いて投稿。


帰宅後はBに久しぶりに会えて嬉しかったが、ものの数分で大変な生活が再開したことに気づいた。とはいえ一緒に『内村さまぁ〜ず』の有吉登場回を見直すなど、自分の好きなように一緒に過ごした。

夜になって新日本プロレスワールドの検索システムの準備をする。データは取得できそう(いまゆっくりスクレイピングをかけている)。

せっかくなら全文検索を導入したいなと思った。費用面がまだ判明していないが、ちょうどElasticSearchの学習にもなるし良いかと思う。

チラ見した感じではFirestoreにドキュメントを溜めて、それを何かしらの方法でElasticSearchに登録できれば、あとはトライ&エラーでなんとかなりそう。これを公開できるかどうかは別の問題。

2020年10月8日、木曜日

Bといっしょの朝が再開した。

新日本プロレスワールドの検索システムは、ElasticSearchを導入してみた。いい感じに検索できている。

これをどう公開しようか考えたが、費用が少ないのはやっぱりCloud Runだろうか。ElasticSearchのサーバと、ElasticSearchを操作するサーバを用意すればいいと仮定して作業を進めてみる。

色々と試行錯誤のすえ、なんとかCloud Run上で上記サーバーたちを動かすことができた。

ただCloud Runではすぐに初期化されてしまう(コンテナが消えてしまう)ため、Google App Engineで同様の構成で公開できないか試す。

そのなかで下記サイトが参考になりそうだったので、見様見真似でやってみる。

Ubuntu 18.04 に Elasticsearch をインストール

上記がうまくいかなかったので(デプロイはできたがアクセスがどうしてもできなかった)、KAGOYAのサーバに直接elasticsearchをインストールしてみる。

https://qiita.com/ekzemplaro/items/acc81bc96fdd56eed587

これもダメだったので、いっそCloud Runに初期データを与えようかと思い立ち実験。

ただこれも上手くいかなかった。スクレイピングを続けながら明日また考える。


PACKERSFUNは、プレイ分析の動画紹介をして投稿。

次作の翻訳ツールを使いながら進めたおかげで、以前より半分くらいの時間で仕上げることができている。

2020年10月9日、金曜日

起床してBと遊びながら、ベアーズ対バッカニアーズ戦を見る。ベアーズが4勝目。こうなるとは思ってなかった。

今日は株価予想プログラムを作ってみた。データの準備は上手くいったのだが、機械学習のところであまりおもしろい結果が得られなかった(どの日も「買うには自信がない」みたいな結果ばかり)。もうちょっと違うアプローチを考えたほうがよさそう。


夜はPACKERSFUNの記事を更新。ルーキーについて少し詳しくなった。

そのあと新日本プロレスの検索システムにめちゃくちゃ時間をつかってしまった。とりあえず動くものはできたが、なぜかローディング画面をつくれずに諦める結果に。


Week39

2020/10/03

今週のアウトプット

  • 予定
  • Google認証を実装する
  • 保育園の見学プランを立てる(残り分)
  • カウントアプリのページ遷移をつくる
  • 子どもの動画編集
  • 追加
  • TOEICテスト受験
  • 株式プログラム作成
  • 英文翻訳アプリ作成
  • コメントアウト翻訳モジュール作成

もともとやろうと思っていたカウントアプリを放って、株式と英語関連のアプリ作成に没頭した。先週GCPを覚えたのがめちゃくちゃデカい。それぞれプロトタイプは出来上がったので、ここからは少しずつ改修をしていこうと思う。

2020年9月26日、土曜日

今日も雨。Bは秋服に衣替えした。

最近22時には寝るので、録画しておいた『脱力タイムズ』を見る。毎週「当たり」の内容だけど、今週は「大当たり」だった。ポケモン風に言えば、「コンプライアンス」タイプの世の中に対して、「有田」タイプの攻撃は2倍の威力になる。つまり「時代に合っている」ということ。

Bを朝寝させたら、簡単な週次レビューを終えて、Google認証に取り組んだ。react-firebaseuiというfirebaseUIをReact用にラッパーされたモジュールがあったのでこれを利用したらサクッといけた。ただページ遷移を考えていないので、めちゃくちゃなログイン後の導線が出来上がってしまった。


13時からはオンラインでTOEIC L&Rテストを受講する。

Zoomにログインしたら他の参加者のフルネームがばんばん飛び出てて、ちょっと動悸がした。おじさんは別にいいけれど、若い娘はちょっとリテラシー上げたほうが安全。それかTOEIC運営側がミーティング参加する前の注意事項として周知するか。

実際のテストは、まったく勉強していない状態でどうなるか不安なまま終わった。700点は超えてると思うけど、最高点ではなさそう。


Bを寝かしつける合間に『キングオブコント2020』を観る。今年はすごい期待していただけに、ちょっと盛り上がりには欠けてしまったか。個人的にはうるとらブギーズが面白かった。

google domainsにドメインを移管したらネームサーバーの設定を誤っていて繋がらない時間帯があった。復旧は解消。

また保育園のお知らせの更新を知りたかったので、早速Cloud Runを使って自動で更新の確認・通知機能を稼働させた(保育園のサーバに迷惑のかからない頻度=1時間に1度チェックする)。1時間もかからずに準備できたので、バックエンドは結構いい感じになってきたかな。Kagoyaで運営していたサービスも移行しようと思う。

2020年9月27日、日曜日

雨が振らないうちにBを連れて散歩に。

有価証券報告書をAPI経由で取得するライブラリが使えなくなっていたので、自分でどうにかすることに。

ものすごし集中してしまい(良いような悪いような気持ち)、一気に分析プログラムをアップデートさせた。具体的には長期保有できる株かどうかを分析できるように、過去の有価証券報告書もFirestoreに保存させるようにしている。

問題はデータ量や読み書きの数が無料範囲を超えそうなところ。月1ドル程度の出費に抑えられるように検討しよう。

2020年9月28日、月曜日

パッカーズ戦があるため、今日はBの散歩を昼に回す。せめてもの償いに家でいっしょに遊ぶ。

試合は最終クォーターまでもつれながらも、最後は無事勝ちきった。セインツのRBカマラが超人すぎて、ほぼパッカーズvsカマラの勝負だった。詳細はPACKERSFUNにて。


昼間はあたたかくなってきたので、Bを連れて散歩。新しいカフェに行ってみる。アイスコーヒーがとても濃かったので、数年ぶりにコーヒーフレッシュを入れる。油の味に変わってしまって反省。もう二度とこんなミスはしない。


夜に株式アプリをすこし改修。データの持ち方を証券コード別にした。

2020年9月29日、火曜日

株式アプリにちょこちょこ手入れ。必要なデータをだいたい取得できたので、分析をしてみる。自分の保有している株が7年後は51円になっていると伝えられショック。

バッチ処理も作成して、その日に発表された有価証券報告書の中にいい銘柄がないかを検索できるようにした。なにかあればSlackに通信して、詳細を調べたければSlackに載せたURLを見ればいい、ということにした。上手くいけばいいなー。


昼のあたたかいうちにBを連れて散歩。ちょっと前までは暑いのを気にしていたのに、今日は寒さを気にするように。「ちょうどいい気候」が毎年ちょっとずつ減っている。仕方がない。

2020年9月30日、水曜日

エアコンの掃除業者が来てくれるので、さきに部屋の掃除。昼ごろに来てくれて、すぐにやってくれた。8000円也。

PACKERSFUNは、Week3のまとめ記事を執筆。ついでにプレイ分析動画の翻訳も済ませた。

そのなかで英文読解の手助けになるツールをつくりたくて、もう5度目ぐらいではあるがチャレンジ(実務においてはDeepL翻訳でほぼOK。しかしあまりにもブラックボックス化していて、自身の英語スキルはいっさい上がらないことに気づいた)。

最近よく書いているように、“FastAPI + Cloud Run”と”React”で構成はすぐ準備。今回は自然言語処理のモジュールnltkをはじめて使ってみた。それを使って各英単語を次のとおりに分析した。

  • NGSL登録語かどうかの判定* 品詞抽出* 固有名詞かどうかの判定それでこれをフロントに上手く反映させて読解の手助けにしたいと思っているのだが、肝心のフロントをどう表示させるか迷った。

つまりは「英文をどう読めば(把握すれば)いいか」という問題で、結局英語の勉強をしないといけない。

2020年10月1日、木曜日

朝が寒くなってきた。

Bは最近モノで遊ぶようになってきた。ガラガラを振ったり。振っているうちに意図せず投げ捨ててしまっているので、これがいつ自分の意図で捨てるようになるのか観察しよう。


PACKERSFUNは、Week4のプレビューを書く。ファルコンズ戦だが勝てる気がしてきた。

また英文を読むために、昨日つくったツールを少しイジった。いろいろと悩んだ結果、

  • 名詞* 動詞* 接続詞* 前置詞にハイライトをかけ、ほかをグレーアウトしてみたところ、すこし読みやすくなった。ポイントになる単語だけが浮かんできて、かつ文を区切れる感覚。

またNGSLの単語リストを引っ張ってきて、この中に含まれているのに覚えていない単語を抽出するようにした。サンプルとしていろんなテキストを読みながら見つけていく予定。

そのなかでReactアプリケーションを作るときにcreate-react-app通称CRAを使っているのだけれど、これと普通のreactの違いがわからなかった。next.jsの違いも理解してない。

2020年10月2日、金曜日

Bの寝そうなタイミングが身体的に把握できてきた。なんとなく「あ、もう寝るな」というときを感じて、適当に抱っこしていると寝てくれる。いつも思うけど、あくびした直後に寝るなんて本当にすごいと思う。教えてほしいぐらい。

フロントエンドをもう少し鍛えないといけないと感じ、Reactを本格的に学ぶことを決意。あとサボってたLinuCの勉強を復活。今年の終わりには 自分でサービス開発ができて、インフラ(Linux)まわりも喋れる ぐらいになれればいいかなと思う。

今日はCRAで使われているモジュールを確認し、そのうち必須のモジュールだけで最低限のReactアプリを作成した。


上記のReactの学習用に、コメントアウトだけを翻訳するモジュールを作成してみた。

個人的にはかなり便利なツールが作れたと思う。Qiitaにも投稿。

来週のアウトプット

  • Reactまわりを勉強する(3ヶ月ぐらいかかりそう)
  • React
  • React Hooks
  • Next.js
  • webpack
  • babel
  • みずほ銀行の株価予想プログラム
  • 1日/n日平均の上昇率
  • 現在の株価とn日平均の乖離率
  • 【結果】翌日の初値と終値の差(プラスorマイナス)
  • 上記をもとにして機械学習で読ませる
  • Cloud RunからGmailを使う

Week38

2020/09/26

週次レビューを再開したので、ついでにこちらにも書いておく。

今週のアウトプット

PACKERS FUNの更新

今週からスタートしたNFLについて、シーズン全体の記事と試合に関する記事など。先々週とあわせて10記事以上を更新。

AWSチュートリアルを終える

チュートリアルを読みながら、ウェブサイトの構築を行った。

AWSの概要はなんとなく理解したが、CloudFormationのテンプレートを理解していないので実践で使うには勉強が足りなそう。とはいえ人と話すときには困らなくなった。

それよりもAWSは個人で使うにはお金がかかるので、基本無料で使えるGoogle Cloud Platform(GCP)をキャッチアップした。末尾の日記の通り、GCPをつかってアプリを構成することができた。ほぼこれでよさそう。

保育園の見学プランを立てる

大体立てた。ビックリしたのは見学概要がサイトに掲載されてから数時間で予約が埋まってしまったこと。スクレイピングでページ更新を確かめようかどうか迷っている。

子どもの動画を集めなおす

Dropboxと簡単なプログラムを使って、簡単にHDDへ転送するようにした。このうち「使う動画」や「使える時間」をまとめておきたいなと考えている。

いま求められているスキルを調べる

最近の求人情報をちょっと確認。やっぱりAWS系の知識が優遇されている。GCPの知識をつけておいて、クラウド全体の知識として自己紹介できればいいかな。あとはPM経験。

それほど「そんな知識/経験が!」というのはなかったので、いったんはもういいかな。

2020年9月19日、土曜日

Bを連れて散歩。予定通り寝てくれたが、今日は1時間近く寝てくれたことにビックリ。その間に週次レビューを復活させ(上記の通り)、来週の目標を決めた。

そのあとTodoistを自分好みに使うために、簡単なプログラムを作成した。Pythonのライブラリがボランティアで提供されているので、30分もあれば作ることができた。

お昼ころ、はじめて離乳食を食べさせてみた。思ったよりも食べてくれて順調。口の中に入れるだけでも立派だと思う。


これまで撮影した写真や動画の整理について悩む。とりあえず写真や動画を保存するとして、

  • どのようにスマホ(またはデジカメ)の写真をHDDへ移動するか* これをどのように流れ作業にするかというところで色々と考えた。いろいろと試してみた結果、(スマホは)Dropboxに同期させつつ、適当な間隔でこれをゴッソリHDDに移すことにした。

その際、日付ごとに整理したくなったので、Todoist同様にPythonのプログラムをちゃちゃっと書く。これで思いたったときにHDDを接続してプログラムを走らせれば自動的にHDDへ保存ができるようになった。

ここまでいくと、NATを導入して適宜HDDにコピーするようにしたくなってきた。次のセール期間はNAT導入を検討しよう。

みたいなことをやっているうちにもう夜。新日本プロレスG1 CLIMAXの開幕戦を見つつ(オスプレイのヘビー転向は成功したと思う)、パッカーズの直前情報を確認。ブログにして寝る。

2020年9月20日、日曜日

雨を気にして自宅で過ごす。Bはずっと「クマーバチャンネル」を見ている。私の時代とくらべて最近のキッズソングは低音が出ていると思う。

AWSのチュートリアルはDBの追加に進んだ。そのままユーザ認証もチャレンジしてみる。認証メールの本文が味気なくスパムっぽく見えたので、実際に使う場合は修正しないといけなさそう。

配偶者がLINEスタンプを作っているので、「画像をLINEスタンプの形式に変換できれば楽なのにな」と思って調べてみたら、やっぱり既にやっている人がいた。

上記を参考にさせてもらいつつ、クロップ機能も追加してライブラリを作った。スタンプ画像ができあがったら実際に使ってみてもらって上手くいくかテストする予定。

2020年9月21日、月曜日

起床後、Bと一緒にパッカーズの試合を観る。結果は圧勝。最終クォータはBの面倒を見ながら横目で観戦する程度だった。

試合結果のブログも書き終えると昼間だったが、涼しいので散歩に出かける。忘れてたけど今週は4連休で、人出はほとんど元に戻ってきた感じ。休日はふつうに働いている人たちのものだと思うので、なるべく邪魔をしないように散歩して、公園ですこし寝てもらって帰宅。

配偶者がNetflixで江原啓之MCのスピリチュアル番組を見つけた。出演者の中に澤穂希がいて驚いたが、それよりもアシスタントが住吉美紀だったことに震える。

ふと最近の転職事情を知りたくなって、いくつか求人情報を確認してみた。やっぱりAWSが求められてるんだなと実感。あとはリーダー経験とか。そろそろ「経験」でご飯を食べるフェーズに入ってきている。

2020年9月22日、火曜日

起床後、AWSチュートリアルをやる。とりあえず終わった。各サービスのイメージを掴めたかな、という程度。請求がすごいきて驚いた(1日4ドルぐらい)。

感覚はつかんだので、GCPでもやってみようと思う。個人用のPythonのテンプレートを準備したあと、ためしにCloud Functionsを使ってみた。

最初の関数: Python  |  Google Cloud Functions に関するドキュメント

gcloud経由で操作するにはCloud Build APIを利用する必要があるみたいなので、APIを有効にした。

時間があったので、Cloud Firestore を使ってみる  |  FirebaseでFirestoreとの連携も試してみる。とりあえず上手くいった。

わからないのはGCPとFirebaseの関連性について。GCPがFirebaseを包括しているようなイメージだけど、勘違いしていそう。困ったときにちゃんと調べるか。

夜はCloud Runを触ってみる。Cloud Build、Container Repositoryあたりを使ってDockerイメージからCloud Runのサービスを起動できた。いい感じ。

明日以降にCloud RunからCloud Firestoreを触ることができれば(今日作成したコレクションを利用しよう)、簡単にAPIをつくることができそう。フロントエンドはFirebaseかNetlifyでいこうか。

2020年9月23日、水曜日

雨が降るそうだったのでBの散歩は諦める。

一緒に『ロンドンハーツ』を見ていたら、炎上騒ぎのあったシュウペイに対して有吉から「間違った意見に屈するな」の一言。ちょっといいシーンだったし、世代の断絶にも気づくシーンだった。


GCPはCloud RunからFirestoreに接続させることもできた。せっかくなのでFastApiを使ったテンプレートプロジェクトを作ろうと思う。

Firestoreについて調べていたら、「FirebaseのCloud Firestoreを発展させて、最近GCPのCloud Firestoreができた」という旨の記事を読んだ。少し納得。ドキュメントの位置がわからなくなるので、こっちにリンクを張っておこう。

Firestoreのドキュメント

ちなみに現在はDatastoreでなく、Firesotreを利用しているはず。この差もいずれ重要になるかもしれないが、いまは無視しておく。

認証情報まわりでミスった(誤ってキーをレポジトリにアップしてしまっていた)ので、その解決策を検討。

どうやら同じプロジェクト(正確にはサービスアカウントだと思う)なら認証情報の受け渡しが不要みたい。そのため開発環境ではキーを利用して、本番環境はGoogleに任せるようにした。


テレワークが進んだおかげで、育休中も会社の情報が追いやすくなった。

気持ちを切り替えるためにまったく見ないようにしていたが、大きな全社イベントがあったので、その映像を見る。


今日一日でGCPについては割と詳しくなった気がする。明日は時間をつくってAPIサーバの公開をドキュメント化・テンプレート化しよう。

またpackersfun.comをGoogleDomainに移管した。このkoboriakira.comも移管する予定。

2020年9月24日、木曜日

珍しくBが大泣きした。散歩に連れていけれないからだろうか。どちらにせよ活動時間がオーバーしていたので頑張って寝てもらった。

GCPを使ったAPIサーバは、最終的に下の技術を使うことにした* FastAPI: PythonのAPIサーバ* Docker: コンテナ* git: リビジョン管理* Google Cloud Run: コンテナのデプロイサービス* Google Cloud Builder: CD/CIサービス* Google Container Respository: Dockerイメージ管理サービス* Google Cloud Firestore: データベースとりあえずメモ。

0. 前提

Docker、gcloudはインストールしておいてもらう。

bash $ docker --version Docker version 19.03.12, build 48a66213fe $ docker-compose --version docker-compose version 1.26.2, build eefe0d31 ``````bash $ gcloud --version Google Cloud SDK 311.0.0 bq 2.0.60 core 2020.09.18 gsutil 4.53 ### 1. プロジェクトを作成するmy-awesome-apiという名前でプロジェクトを作成した。次のキーを混同しないように。

  • プロジェクト名: my-awesome-api * プロジェクトID: my-awesome-api-290501 * プロジェクト番号: 359948014733 ### 2. gitリポジトリを作成、クローンするawesomeapiという名前でgitリポジトリを作成した。

bash mkdir ~/git cd ~/git git clone git@github.com:koboriakira/awesomeapi.git cd awesomeapi ### 3. Dockerコンテナ内でFastAPIサーバを立てるDockerfileをつくって、イメージをbuildして、コンテナをrunする。

```Dockerfile FROM python:3.8.5-slim WORKDIR work ADD awesomeapi /work/awesomeapi ``````bash docker build -t awesomeapi-image .

docker run -v $(pwd)/awesomeapi/:/work/awesomeapi -p 7777:8000 -it —rm —name awesomeapi-container awesomeapi-image /bin/bash ```ファイルを作成して、Dockerコンテナ内にもファイルが共有されていることを確認する。

ローカル上にawesomeapi/main.pyを作成。


├── Dockerfile ├── README.md └── awesomeapi └── main.py ``````python main.py from typing import Optional from fastapi import FastAPI app = FastAPI()

@app.get("/")

def read_root():return {"Hello": "World"}@app.get("/items/{item_id}")

def read_item(item_id: int, q: Optional[str] = None):return {"item_id": item_id, "q": q}```Dockerコンテナ内で、ファイルを確認。

```bash # pwd work # ls awesomeapi main.pu ```Dockerコンテナ内で、必要なPythonライブラリをインストール。

```bash # 先にpip自体のバージョンを最新化$ pip install --upgrade pip $ pip install fastapi uvicorn ```Dockerコンテナ内で、FastAPIサーバを起動。

```bash $ uvicorn awesomeapi.main:app --host 0.0.0.0 --reload ````http://localhost:7777/`にアクセスして、Docker内の`localhost:8000`に立てられたFastAPIサーバと疎通できていることを確認。

具体的にはブラウザに`{"Hello":"World"}`と表示されるはず。これがレスポンス。

ためしに`main.py`の`read_root`メソッドにある`{"Hello":"World"}`を編集してブラウザをリロードしてみる。するとレスポンスも変わるはず。

### 4. Docker ComposeでFastAPIサーバを起動する

コンテナ内に入らずに開発できるようにする。

まず必要なPythonライブラリを`requirements.txt`にまとめる。

```bash .

├── Dockerfile ├── README.md ├── awesomeapi │   ├── __pycache__ (以降は省略)

│   └── main.py └── requirements.txt ``````requirements.txt fastapi uvicorn ```次にrequirements.txtをDockerイメージ内に追加してライブラリをインストールするように、Dockerfileに追記する。

```Dockerfile FROM python:3.8.5-slim WORKDIR work ADD awesomeapi /work/awesomeapi ADD requirements.txt /work/requirements.txt RUN pip install --upgrade pip && \pip install --no-cache-dir -r requirements.txt ```さらにDockerコンテナを起動したときにFastAPIが起動されるように追記する。

```Dockerfile FROM python:3.8.5-slim WORKDIR work ADD awesomeapi /work/awesomeapi ADD requirements.txt /work/requirements.txt RUN pip install --upgrade pip && \pip install --no-cache-dir -r requirements.txt CMD ["uvicorn","awesomeapi.main:app","--host","0.0.0.0","--reload"]```新しいDockerイメージをbuildして、そのイメージからコンテナをrunする。`docker run`の末尾の`/bin/bash`がなくなったことに注意```bash docker build -t awesomeapi-image .

docker run -v $(pwd)/awesomeapi/:/work/awesomeapi -p 7777:8000 --rm --name awesomeapi-container awesomeapi-image ```最後に、これらのDockerイメージのbuild・コンテナのrunを簡単にするためにDocker Composeを使う。

次のようなdocker-compose.ymlを作成して、`docker-compose up`で起動```bash .

├── Dockerfile ├── README.md ├── awesomeapi │   └── main.py ├── docker-compose.yml └── requirements.txt ``````docker-compose.yml version: '3'services:app:build: .

ports:- '7777:8000'volumes:- ./awesomeapi:/work/awesomeapi ``````bash docker-compose up ```同じく`localhost:7777`にアクセスでき、`main.py`を編集すれば反映されることを確認。

ここまでで、(データベースを使わない)APIサーバの開発環境を作成することができた。いったんgitリポジトリにコミット。

```bash git add .

git commit -m "Initial Commit"git push origin master ```### 4. Google Cloud Runにデプロイしてサービスを公開するCloud Runに移動して、「サービスを作成」をクリック。

* リージョン: asia-northeast1 * サービス名: awesomeapi * 「未認証の呼び出しを許可」

「次へ」をクリックしたあと、「コンテナイメージのURL」でawesomeapi-imageのlatestを選択。

すると自動でGoogle Cloud Buildをつくってビルド、デプロイをしてくれる。

しかしこの状態では失敗する。Cloud RunでDockerを使う場合は8080ポートで通信を待つ必要があるからだ。

そのためDockerfileを修正して、gitにpush。

```Dockerfile FROM python:3.8.5-slim WORKDIR work ADD awesomeapi /work/awesomeapi ADD requirements.txt /work/requirements.txt RUN pip install --upgrade pip && \pip install --no-cache-dir -r requirements.txt CMD ["uvicorn","awesomeapi.main:app","--host","0.0.0.0","--port","8080"]```ビルドが自動開始するのを確認。完了したらCloud Runに戻って、Cloud RunのURLに飛ぶと、同様のレスポンスを取得できる。これでサービスが公開された。

## 5. FirestoreをつかってNoSQLを利用できるようにする

Google Cloud Firestoreに移動。「ネイティブモードを選択」をクリック。リージョンはasia-northeast1にして「データベースを作成」をクリック。

先にコレクションを作ってしまう。テストで次のようにした。

* コレクションID: users * ドキュメントID: 自動割り当て* フィールド:* name: koboriakira (フィールドタイプ string)

* age: 31(フィールドタイプ number)

つぎにFirestoreのデータを読み取れるように実装を進める。

```requirements.txt fastapi uvicorn google-cloud-firestore ``````main.py from typing import Optional from fastapi import FastAPI from google.cloud import firestore app = FastAPI()

db = firestore.Client()

@app.get("/")

def read_root():docs = db.collection(u'users').stream()

result = {}for doc in docs:result[doc.id] = doc.to_dict()

return result @app.get("/items/{item_id}")

def read_item(item_id: int, q: Optional[str] = None):return {"item_id": item_id, "q": q}```いったんローカルのテストは無視して、`git commit`そして`git push`する。Cloud Buildが自動的にスタートする。

ビルドが成功してCloud Runのコンテナが最新化したことを確認したら、サービスのURLに飛ぶ。

レスポンスが`{"4Ja4sXQ6DiIDX3N0kYmW":{"age":31,"name":"koboriakira"}}`のようになっていれば、データベースを利用できていることがわかる。

### 6. Firestoreをつかった開発環境をつくる

さきにdocker-compose.ymlのportsも8080に修正しておく。

```docker-compose.yml version: '3'services:app:build: .

ports:- '7777:8080'volumes:- ./awesomeapi:/work/awesomeapi ```つぎにこのFirestoreを扱えるように認証まわりの設定をする。

「IAMと管理」 > 「サービスアカウント」に移動。`<プロジェクトID>@appspot.gserviceaccount.com`というアカウントがあるはずなので、クリックしてアカウント詳細画面へ。

画面下の「キー」で「鍵を追加」をクリック。JSONでキーを作成すると、jsonファイルがローカルに自動でダウンロードされる。

このファイルを内に配置し、誤ってpushしないように.gitignoreを編集する```bash .

├── Dockerfile ├── README.md ├── awesomeapi │   ├── __pycache__ │   │   └── main.cpython-38.pyc │   └── main.py ├── docker-compose.yml ├── my-awesome-api-290501-9b5ca70ce0e8.json └── requirements.txt ``````.gitignore # credentials my-awesome-api-290501-9b5ca70ce0e8.json (以下省略)

```念のため`git status`でjsonファイルがgit管理対象でないことを確認しておく。

このjsonファイルをDockerコンテナに入れたいので、docker-compose.ymlを編集する。

```docker-compose.yml version: '3'services:app:build: .

ports:- '7777:8080'volumes:- ./awesomeapi:/work/awesomeapi - ./my-awesome-api-290501-9b5ca70ce0e8.json:/work/credentials.json environment:- GOOGLE_APPLICATION_CREDENTIALS=/work/credentials.json ```※Dockerfileにjsonファイルを含めるような編集をすると、のちの自動ビルド時にjsonファイルが見つからないためエラーになる。

`docker-compose up`でコンテナを開始して、`localhost:7777`にアクセスして、同様にデータベースを使っていることを確認する。

## 7. ビルド構成をファイル管理する

Google Cloud Buildの「トリガー」に移動して、作成されたトリガーの詳細に移る。

`cloudbuild.yaml`を作成し、詳細内にある「インライン」で定義されている設定ファイルの記述をコピペする。

```bash .

├── Dockerfile ├── README.md ├── awesomeapi │   └── main.py ├── cloudbuild.yaml ├── docker-compose.yml ├── my-awesome-api-290501-9b5ca70ce0e8.json └── requirements.txt ``````cloudbuild.yaml steps:- name: gcr.io/cloud-builders/docker args:- build - '--no-cache'- '-t'
- '$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA'
- .
- '-f'
- Dockerfile
id: Build - name: gcr.io/cloud-builders/docker args:- push - '$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA'id: Push - name: gcr.io/google.com/cloudsdktool/cloud-sdk args:- run - services - update
- $_SERVICE_NAME
- '--platform=managed'
- '--image=$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA'
- >-
--labels=managed-by=gcp-cloud-build-deploy-cloud-run,commit-sha=$COMMIT_SHA,gcb-build-id=$BUILD_ID,gcb-trigger-id=$_TRIGGER_ID,$_LABELS
- '--region=$_DEPLOY_REGION'
- '--quiet'
id: Deploy entrypoint: gcloud images:- '$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA'options:substitutionOption: ALLOW_LOOSE substitutions:_TRIGGER_ID: 33942bf8-952d-4bf8-8bf0-52dd2d45409d _SERVICE_NAME: awesomeapi _DEPLOY_REGION: asia-northeast1 _GCR_HOSTNAME: asia.gcr.io _PLATFORM: managed _LABELS: gcb-trigger-id=33942bf8-952d-4bf8-8bf0-52dd2d45409d - gcp-cloud-build-deploy-cloud-run - gcp-cloud-build-deploy-cloud-run-managed - awesomeapi
```Google Cloud Buildのビルド構成を「インライン」から「Cloud Build構成ファイル」に変えて「保存」をクリック。

## 8. テストを作成して、CIを整える

テスト用に適当なメソッドをつくる。

```bash .

├── Dockerfile ├── README.md ├── awesomeapi │   ├── calculate.py │   └── main.py ├── cloudbuild.yaml ├── docker-compose.yml ├── my-awesome-api-290501-9b5ca70ce0e8.json ├── requirements.txt └── tests └── test_calculate.py ``````calculate.py def add(a: int, b: int) -> int:return a + b ``````test_calculate.py from awesomeapi import calculate def test_add():assert calculate.add(2, 3), 5 ```ローカルでpytestを実行。

```bash $ python -m pytest ========================== test session starts ===========================platform darwin -- Python 3.8.2, pytest-6.0.1, py-1.9.0, pluggy-0.13.1 rootdir: /Users/canary/git/awesomeapi collected 1 item tests/test_calculate.py .                                          [100%]=========================== 1 passed in 0.02s ============================```Docker上でもテストが行えるように、pytestをライブラリに追加し、testsフォルダをDockerイメージに追加する。

```requirements.txt fastapi uvicorn google-cloud-firestore pytest ``````Dockerfile FROM python:3.8.5-slim WORKDIR work ADD awesomeapi /work/awesomeapi ADD tests /work/tests ADD requirements.txt /work/requirements.txt RUN pip install --upgrade pip && \pip install --no-cache-dir -r requirements.txt CMD ["uvicorn","awesomeapi.main:app","--host","0.0.0.0","--port","8080"]```cloudbuild.yamlを編集して、テストを追加する。

```cloudbuild.yaml steps:- name: gcr.io/cloud-builders/docker args:- build - '--no-cache'- '-t'
- '$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA'
- .
- '-f'
- Dockerfile
id: Build - name: gcr.io/cloud-builders/docker args:- run - '$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA'- python
- -m
- pytest
id: Test (以下略)

```gitにコミットして、Cloud Buildを走らせる。ビルドが通ればテストの自動実行設定もできた。

### 9. このあとやりたいこと

* ビルド結果をSlack等に通知* そのアプリをつくる?

* またはPubSubを勉強する必要がありそう* ストレージに保存したい* 保存はできた。バゲットを示す環境変数はCloud Runにも必要* svgを作成して保存したりしたい* svgは別途勉強しないといけない
---

パッカーズ対セインツのプレビューを書いて(あまり深い内容にならなくて反省)、とりあえず今日は終わり。明日以降はフロントエンドをやりなおして、APIサーバを利用したサイトを作ってみて終わり。

## 2020年9月25日、金曜日

今日も雨でBと散歩には行けなさそう。

ドルフィンズ対ジャガーズの試合をチラ見しながらReactとCircleCIの導入にチャレンジ。またkoboriakira.comをGoogle Domainsに移行した。サブドメインを使ったアプリ公開が楽になりそうなので嬉しい。

---

個人開発に関して、すこしまとめておこうと思う。

* 管理* masterブランチとfeatureブランチで運用する* masterブランチにコミットしないようpre-commitを利用する* masterブランチにはPRでマージする* CircleCIを利用して、各コミットごと(PRごと)にテストを回す* フロントエンド* React + TypeScriptで開発* masterブランチをNetlifyにデプロイして公開する* バックエンド* Google Cloud Runを利用して、REST APIでサービス公開する* Cloud Runには、Google Cloud Build(Google Container Repository)を利用して自動デプロイを整える* データベースはGoogle Cloud Firestore、ファイル管理はGoogle Cloud Storageを利用する* 今後のチャレンジ* フロントの認証機能をつける* ネットワークやロギングについて改善できることがないか調べる* CIにおいて、テスト結果をSlackなどに連携させる* 上記のプロジェクトのテンプレートを用意する* Firestore、NoSQLを使ったモデリングのベストプラクティスを学ぶ* 他のGPCのサービスを利用する* gRPCを学ぶこの数週間で個人でアプリケーション開発ができる状態にはなってきた。一方で運用フェーズでは必ず問題点が発生しそうな気がしている。なのでさまざまなことを出来るようにしつつ、公開後に必要となる知識もすこしずつ触れてみようかなと考えている。

とりあえずFirebase Authenticationを使って会員登録/ログイン機能を実装してみて(以前にやったけどもう忘れていた)、いよいよアプリケーション開発にとりかかる。シンプルなカウンターのアプリにするつもり。

## 来週のアウトプット

- Google認証を実装する
- カウントアプリのページ遷移をつくる
- 保育園の見学プランを立てる(残り分)
- 初日と2日目のパートをつくる
- 試合に関する情報を集める
バックエンドはなんとか最初のステージを突破したので、フロントエンドを再学習しながらアウトプットに努める。

はじめに

Amazonが提供する現代的なウェブアプリケーションの構築を読み進めることにした。

なお実践はCloud9ではなくローカル端末で試すことにした。

また請求が発生する可能性があるため、早めに済ませること。EC2でめちゃくちゃお金がかかった。

モジュール1「静的ウェブサイトの構築」

(前提)AWS CLIの設定

AWS CLIを使う必要があるのでaws configureでAWSの設定ファイル(.aws)を作成した。アクセスキーが古くなってきたので新しくした。

(前提)S3とは

S3 は、保存されたオブジェクトをHTTP経由で直接提供できる、耐久性と可用性に優れた、低コストのオブジェクトストレージサービスです。

「ファイルをHTTPで転送できる」というのがポイント。つまりWebサイトにもなりうる。

S3バケットの作成

aws s3 mbコマンドでS3バケットを作成した。バケット名はaws-modern-application-workshop-koboriにしたので、具体的には次のコマンドを打つ。

bash aws s3 mb s3://aws-modern-application-workshop-kobori ### S3バケットの設定静的ウェブサイトのホスティングができるように、「ウェブサイトとして利用」と「外部からのアクセスを許可」の設定をする。

ホスティング

aws s3 websiteコマンドで静的Webサイトのホスティング設定をする。--index-documentオプションはindex.htmlを指定。

外部からのアクセスを許可

バケットを作成した時点ではプライベート(外部からはアクセスできない)ため、S3バケットポリシーを変更する必要がある。

バケットポリシーは一般的にはJSONファイルを定義して、これをaws s3api put-bucket-policyコマンドで送るのがいいみたい。そのためJSONファイルを次のように送ったbash aws s3api put-bucket-policy --bucket aws-modern-application-workshop-kobori --policy file://JSONファイルJSONファイルの中身は下記の通り。

json {"Id": "MyPolicy","Version": "2012-10-17","Statement": [{"Sid": "PublicReadForGetBucketObjects","Effect": "Allow","Principal": "*","Action": "s3:GetObject","Resource": "arn:aws:s3:::aws-modern-application-workshop-kobori/*"}]}### index.htmlをデプロイ最後に実際に利用されるindex.htmlをS3バケットに配置する。これはaws s3 cpコマンドで設定。

cpコマンドと同じなので、具体的には次のようにした。

bash aws s3 cp ローカルのindex.html s3://aws-modern-application-workshop-kobori/index.html これでウェブサイトが構築できた。というかこんなに簡単なのか。心配なのは金額だけ。

調子がよかったので「モジュール 2: ウェブサーバーでのアプリケーションのホスト」もちょっと読んでみよう。実際のメモは明日以降に。

モジュール2「静的ウェブサイトの構築」

(前提)各サービス、用語の概要

  • AWS CloudFormation: Amazon Web Servicesリソースのモデル化およびセットアップのサービス。インフラストラクチャ管理を簡略化する。

  • NLB: Network Load Balancer * Amazon ECR: Elastic Container Registry、完全マネージド型のDockerコンテナレジストリです。このレジストリを使うと、開発者はDockerコンテナイメージを簡単に保存、管理、デプロイできます。

  • Amazon ECS: Elastic Container Service、フルマネージド型のコンテナオーケストレーションサービスです。

  • AWS CodeCommit: Gitベースのリポジトリをセキュアにホストする完全マネージド型のソース管理サービスです。

  • AWS CodeBuild: ソースコードをコンパイルし、テストを実行し、デプロイ可能なソフトウェアパッケージを作成できる完全マネージド型のビルドサービスです。

  • AWS CodePipeline: 完全マネージド型の継続的デリバリーサービスで、素早く確実性のあるアプリケーションとインフラストラクチャのアップデートのための、パイプラインのリリースを自動化します### モジュール2A: CloudFormationのテンプレートをデプロイするaws cloudformation create-stackコマンドで、ローカルにあるテンプレートのymlとIAMリソースをつかってスタックを作成する。

bash aws cloudformation create-stack --stack-name MythicalMysfitsCoreStack --capabilities CAPABILITY_NAMED_IAM --template-body file://module-2/cfn/core.yml スタックとは、

スタックは、単一のユニットとして管理できる AWS リソースのコレクションです。 つまり、スタックを作成、更新、削除することで、リソースのコレクションを作成、更新、削除できます。 … リソースが作成できない場合、AWS CloudFormation はスタックをロールバックし、作成されたリソースを自動的に削除します。

ちなみにスタックをつくるときにIAMロール(ポリシー)でつまづいた。EC2とIAMに関してフルアクセスの権限を付与して解決したが、ベストプラクティスがわからない。このあたりを勉強すべきか迷う。

モジュール2B: サービスをNLB経由でデプロイ・公開する

aws ecr create-repositoryコマンドでリポジトリを作成する。AmazonEC2ContainerRegistryFullAccessの権限を付与して実行した(FullAccessがベストではない気がするのだが、コマンドとポリシー、パーミッションの関係が見つけられない)。

このあとDockerログインをするのだが、aws ecr get-loginコマンドはセキュリティの関係から(コマンド履歴にパスワードが残る)使えなくなっていた。そのためこちらを参考にして、aws ecr get-login-passwordコマンドでdocker loginを進めた。IssueかPRを出せるといいな。

つぎにECRにプッシュしたイメージをECSにデプロイする。

aws ecs create-clusterでサーバのクラスター、aws logs create-log-groupでロググループをそれぞれ作成する。

与えられたテンプレートを使って、aws ecs register-task-definitionコマンドでECSタスク定義を登録する。

つぎにサービススタックに必要なインフラストラクチャをプロビジョニングする。

プロビジョニングとは、必要に応じてネットワークやコンピューターの設備などのリソースを提供できるよう予測し、準備しておくことです
https://www.idcf.jp/words/provisioning.html

ただ単純に公開するのではなくNLBをかませることで、実際のサービスのスケールイン/スケールアウトを容易にできる。

というわけでaws elbv2 create-load-balancerコマンドでロードバランサーを作成する。サブネットはCloudFormationで作成したスタックから利用。

次にaws elbv2 create-target-groupコマンドでNLBターゲットグループ、aws elbv2 create-listenerコマンドでNLBロードバランサーのリスナーをそれぞれ作成。これで80番ポートが受信したリクエストをターゲットグループに登録されているターゲットに転送することをロードバランサーに知らせる。あまり意味はわかっていないけど、とりあえず書いておこう。

よくわからないけど、はじめてECSを利用する場合はaws iam create-service-linked-role --aws-service-name ecs.amazonaws.comが必要なよう。

ECSで実際のサービスを作成するため、aws ecs create-serviceコマンドを実行するaws ecs create-service --cli-input-json file://service-definition.json これで実際のサービス(Flask)にNLBを介してアクセスできるようになった。NLBのDNSでcurlを飛ばしてみると、実際にレスポンスが帰ってくる。

ちなみに最初に時間がかかったのはコンテナを作成・起動しているからか。2度目は一瞬だったので。

このサービスを利用するようにフロントエンドのindex.htmlを修正して、モジュールBは終了。

モジュール2C: CD/CIの設定

上記のまま開発を続けると、デプロイする際にはイメージを更新、プッシュして、またタスク定義を更新しないといけなさそう(その方法はチュートリアルにない)。

そのためCD/CIを設定する。

まずCI/CDアーティファクト用のS3バケットをつくる。バケットポリシーはチュートリアル側で用意してくれたものを使う。GETとPUTを許可しているみたい。

つぎにaws codecommit create-repositoryでCodeCommitリポジトリ、aws codebuild create-projectでCodeBuildプロジェクトを作成。いろんな値をコピペするので忘れても調べられるようにしないといけないな。

最後に、CodeBuildプロジェクトを使用してCodeCommitリポジトリを継続的に統合することと、新しくビルドされたアーティファクトをECSのサービスに継続的に提供するサービスとして、AWS CodePipelineをつくる。

aws codepipeline create-pipelineコマンドで、CodePipelineのパイプラインを作成。

そしてCodeBuildがECRリポジトリにアクセスできるよう設定する。具体的にはaws ecr set-repository-policyコマンドでECRリポジトリのポリシーを設定する。

これで使えるようになったのでテストをする。gitの認証まわりに関する設定を行った後、codecommitの空リポジトリをクローンして、今回のアプリケーションのソースをcommitしてpush。

CodePipelineのコンソールで自動ビルドが行われていることを確認して完了。

モジュール3「情報の保存」

テーブル、データの追加

aws dynamodb create-tableコマンドでデータベースを作成。aws dynamodb scanコマンドでテーブルの中身が見れる(見れるということは作成に成功している証拠)。

aws dynamodb batch-write-itemコマンドでレコードを追加する。scanして追加されたことを確認。

ウェブサイトの更新

つぎにこのDBを使うようにアプリを直してcommit, pushしたのだが、403エラーで失敗してしまった。

どうやらHTTPSでやるとMacのキーチェーンの問題があるようなので、SSHを使って回避するようにした。具体的には、

  1. IAMユーザの「AWS CodeCommit の SSH キー」に公開鍵を設定する
  2. SSHキーIDが発行されるので、これを使った~/.ssh/configを設定(下記参照)
  3. ssh git-codecommit.ap-northeast-1.amazonaws.comで疎通確認

~/.ssh/config Host git-codecommit.*.amazonaws.com User <SSHキーID>IdentityFile ~/.ssh/id_rsa またフロントのindex.htmlも更新。

パイプラインが成功したらサイトを確認。API、DBを使ってリストを描画していることを確認して終了。

モジュール4「ユーザ登録の設定」

(前提)Amazon Cognitoとは

ウェブアプリケーションおよびモバイルアプリに素早く簡単にユーザーのサインアップ/サインインおよびアクセスコントロールの機能を追加する。

ユーザプールの作成

aws cognito-idp create-user-poolコマンドで、Cognitoユーザープールを作成する。オプションも入れると次の通り。

bash aws cognito-idp create-user-pool --pool-name MysfitsUserPool --auto-verified-attributes email またユーザプールとセットで、aws cognito-idp create-user-pool-clientコマンドで、ユーザープールクライアントも作成する。

bash aws cognito-idp create-user-pool-client --user-pool-id <ユーザプールのID> --client-name MysfitsUserPoolClient “Id”: “ap-northeast-1_RoHXOwkFB”,“Arn”: “arn:aws:cognito-idp:ap-northeast-1:365487138721:userpool/ap-northeast-1_RoHXOwkFB”{“UserPoolClient”: {“UserPoolId”: “ap-northeast-1_RoHXOwkFB”,“ClientName”: “MysfitsUserPoolClient”,“ClientId”: “71gov86tiiphs9amjmd6kjopje”,“LastModifiedDate”: “2020-09-20T09:36:05.872000+09:00”,“CreationDate”: “2020-09-20T09:36:05.872000+09:00”,“RefreshTokenValidity”: 30,“AllowedOAuthFlowsUserPoolClient”: false }}### REST APIとAmazon API Gatewayの設定NLBの前にAmazon API Gatewayをはさんで、GatewayがCognitoを利用するようにする。またGatewayがNLBとプライベートで疎通するように、API Gateway VPCリンクも必要となる。

まずaws apigateway create-vpc-linkコマンドでNLBへのVPCリンクを作成。


2020年9月18日、金曜日。

強風注意報が出ていたことやベビーベッドの回収がいつ来るかわからないこともあり、今朝の散歩は諦めた。

AWSのチュートリアルは、モジュール2「静的ウェブサイトの構築」に進む。フロントエンドとバックエンドのサービス公開までできた。またCD/CIも準備。設定ファイルをAmazonで準備してくれているのでチュートリアルはスムーズに進むが(それでも難しい)、このファイルを用意するのが大変なのだろうと感じた。一通りやったら設定ファイルを見直す時間を設けないと。

保育園の見学申込を調べたあと、パッカーズ公式サイトのプレイ分析を翻訳。公式サイトなだけに反省点はなく、ぜんぶ気持ちよくなるコンテンツでよかった。

また家族で相談して、すこし一人旅行に出かけさせてもらうことになった。以前から気になっていた箱根のホテルを予約。GoToトラベルの割引が適用されるはずで、2泊で15,000円を切るから驚き。この期間でアプリ開発を一気にできるように、AWSのチュートリアルを進めておこう。


ふと思ったことだが、localhost内で開発しているだけではあまり技術が伸びないことに気づいた。どんなものでもいいから「外部へ公開すること」が重要、という意味だ。

たとえばlocalhostまたはDocker内で動かすことができたいたサービスを実際に誰かに使ってもらおうとすると、そのためのノウハウやスキルがないことに気がつく。これの専門性が高まれば「インフラ」という領域になってくるが、アジャイル・DevOpsの時代においては、ある程度はデプロイまでできないと意味がないだろう。個人開発が好きならなおさらだ。

ということもあって、昨日からAWSのことを再学習しているんだと把握した。つまるところ「アウトプット=開発」というのは「開かれた」状態でないかぎり、それと見なされない。チュートリアルそのままでもいいから、とにかく誰かが使える状態にまで作業を完了させよう。今後の(ITにおける)目標設定はこれを意識しようと思った。ITだけでなくて何でもそうかもな。


2020年9月12日、日曜日。

朝から大変な一日だった。Bがうんちを漏らして、それを洗おうとちょっと目を離したすきにBがベビーベッドから転落した。ギリギリ落ちる前のところで救えたのだが、配偶者が起きてくるまで気が気でなく過ごした(一応、半日経っても異常は見られなかったので安心している)。

そんな感じで昼までは放心状態のような感じだったので、時間をもらって外出。まだ落ち着いたとは言えないが、すこしだけ日常に戻ってきた。昨日書いていたQiitaの記事を完成させたので明日朝にポストしようと思う。

ApacheのSSL化を学習するにあたって、せっかくならAnsibleも使ってみたいなと思った。Ansible トレイルブックという面白いチュートリアルを公式が出しているので、これを明日読んでみようと思う。

2020年9月13日、月曜日。

Bを連れて散歩は継続。今日は涼しかったので、久しぶりに昼間に出かけた。通りがかりの人に話しかけられ、比較的大きめの赤ん坊だと教えてもらう。

2020年9月14日、火曜日。

なんとなく気分が乗っていたので、家族で東京港野鳥公園に出かけてみる。コロナ禍のためかほとんど人がおらず、気楽に散策できた。楽しかった訳ではないけれど。

結構歩いたので帰ってきてBをお風呂に入れたあとは、ほとんどエネルギー切れ。やらないといけないこと/やりたいことが増えてきたので、そろそろタスク整理をちゃんと導入しようかと思う。

2020年9月15日、水曜日。

Bを連れて散歩。今日もおばあさんが話しかけてきた。「迷惑にならないように(喋りかけるのは控えよう)」という気持ちを、「かわいい」という気持ちが少し上回っているようによく感じる。

帰宅してからは、お昼頃までBと遊びながらライオンズvsベアーズ戦を視聴。「去年のほうがちゃんとプレーを観戦、分析できてたな」と思い、どんなふうにプレイを見てたかを書き出してみた。これもブログにする予定。

試合鑑賞後は、すこし時間をもらってライオンズについてブログを書いた。2時間ぐらいあればとりあえず執筆はできそう。

夜になってBを寝かしてからは、保育園の入園応募の準備をはじめた。とりあえずおおまかなスケジュールを組みたかったので、いくつかサイトを検索。自宅まわりの保育園をGoogleマップに配置して、とりあえず候補をしぼった。各保育園の情報をまとめるのは明日やろう。

2020年9月16日、木曜日。

7時頃に起きて、バターコーヒーを飲んで、Bにもミルクをあげる。Bのおかげで、人生ではじめて「正しい生活リズム」で暮らしている。どうせいずれ(10年後ぐらいには)元に戻るだろうけど、10年間ぐらいは真人間で暮らせるのかもしれない。Bはすでに家庭に貢献していると言える。

Plantuml用にJavaをインストールしたあとは、マイナンバーカード取得のための準備をした。暗証番号が4種類もあるので、だいたいの人は忘れるだろうなと思った(実際それでマイナポイントは進んでないと聞いたことがある)。1Passwordがなければ自分も忘れる確信がある。

マイナンバーカードとは別に、入園手続きのための質問と必要な書類の準備がしたかったので、Bの散歩がてら区役所へ。育休期間と入園タイミングについて質問して、解決した。これもnote行きかな。

帰宅してからは昨日まとめた保育園の通園時間や保育時間、見学申し込みなどを調べた。往復はがきでないと申し込めない施設もあることにちょっと驚く。とりあえず10ヶ所の候補を集めて、本命2つ、対抗4つにしぼった。住民税額も再確認。

昼食後は、現代的なウェブアプリケーションの構築を読み進めることにした。