Blogaomu

WEBアプリケーション開発とその周辺のメモをゆるふわに書いていきます。

Kanazawa.rb meetup #74 に参加しました #kzrb

kzrb.doorkeeper.jp

今回は和室での開催。入り口からして開発合宿感が漂っていました(合宿ではない)。金沢勤労者プラザというところが会場だったのですがインターネットが無いのだけ除けば満足できる施設でしたよ!

ブログ記事を書いた

前日に参加していたJAWS-UG金沢もくもく会の記事を書きました。とりあえず進捗出せた。

www.blogaomu.com

プログラミングElixir 20章

「マクロとコードの評価」というテーマの章でした。

  • 関数が使えるなら、マクロは使ってはならない、という教訓
  • defmacro quote unquote
  • あるモジュールでマクロを定義して、使う側ではそのモジュールを requrie する
  • マクロに渡されたパラメータは評価されない
  • quote に渡されたもの(ブロック)は評価されずに内部表現を返してくれる
  • unquoteしたコードは quote ブロックが実行されてコードが生成されたときに実行される
  • unquote_splicing はリストを展開してくれる
Code.eval_quoted(quote do: [1, 2, unquote([3, 4])])
#=> {[1, 2, [3, 4]], []}
Code.eval_quoted(quote do: [1, 2, unquote_splicing([3, 4])])
#=> {[1, 2, 3, 4], []}

if をマクロで実装してみようという例でしたが、まだしっくり理解できず。練習問題もやりながら理解していきたいですね。。

プログラミングElixir

プログラミングElixir

懇親会

居酒屋 さかなや道場 金沢駅店
〒920-0031 石川県金沢市広岡1-9-25 アクロスキューブ金沢駅西口2F
3,000円(平均)850円(ランチ平均)
r.gnavi.co.jp

retty.me

2件目は安くて程よく雑な雰囲気で穴場開拓した感がありましたね。「本日の男汁」というメニューがあったのが印象的でした。

JAWS-UG金沢 #35 に参加しました(Terraform独習メモ4日目) #jawsug

jawsug-kanazawa.doorkeeper.jp

今回はもくもく会で6人参加でした。私はTerraform独習の続きを、その傍ら次回の発表ネタ出しなどをみんなで行いました。

www.blogaomu.com

2018-10-19

  • 今回はALBを作ってみようと思う
  • 久しぶりなのでいろいろ忘れている
    • terraform version したらprovider.awsのバージョンも出てきたので、そもそもどうやってインストールしたんだっけ?となった
$ terraform version
Terraform v0.11.8
+ provider.aws v1.6.0
resource "aws_lb" "memo_lb" {
  name               = "memo-lb"
  internal           = false
  load_balancer_type = "application"
  subnets            = ["${aws_subnet.public-a.id}", "${aws_subnet.public-b.id}"]

  enable_deletion_protection = true
}
  • ALB用のセキュリティグループを作る
  • 現状一つのtfファイルで管理しているのでごちゃっとしてきた
    • まとまり毎にファイル分割したいなあ
  • 〆のグラフ
    • terraform graph > graph/$(git rev-list --max-count 1 HEAD).dot && dot -T png graph/$(git rev-list --max-count 1 HEAD).dot -o graph/$(git rev-list --max-count 1 HEAD).png
    • 中央付近にlbが増えている f:id:TAKAyuki_atkwsk:20181020135808p:plain

その他

@_kentaro_m さんのLT練習(AWS運用周りの話)をみんなで聞いていて、サービスや組織の規模によってこういう構成をとるのかーと新たな発見があって面白かった。小規模ならそれに適した構成も取れるし、なんだかんだ言うてAWSサービス全体としても柔軟なんだなあと思いました。

懇親会

【閉店】がブリチキン。 金沢武蔵店 - 北鉄金沢/居酒屋 [食べログ]

3人でDB設計やらコンテナやらの話をしていました。コンテナを使ったアプリケーション運用の話を聞きたいということだったので、そのうち喋ることになりそうです。唐揚げ美味しかった。

次回

2018-11-23(金・祝)にOpsJAWSとの共同イベントを行います(私は参加できない)。みんな悩みがちな運用周りの話がいろいろ出てくるようなのでぜひご参加くださいませ〜〜。

jawsug-kanazawa.doorkeeper.jp

Kanazawa.rb meetup #73 に参加しました #kzrb

kzrb.doorkeeper.jp

7年目に突入して最初のもくもく会です。今回はいつものElixir本ではなく、違うことをしていました。

告知用文言生成のスクリプト

Kanazawa.rb では meetup を開催するときに予め各種 SNS で告知を行うのですが、毎回手で文言を作成するという話をメンバーから聞いたので、ある程度自動的にできればいいなあと思いスクリプト化の検討を行いました。文言の構成は毎回同じようなのでテンプレートを作成して変数を流し込むという処理で良い感じにできそうです。rbの名が付いているので erb 使う?と思ったのですが、そこまで複雑なことは行わないので logic-less と謳っている mustache を使ってプロトタイプを作ることにしました。一通りのプログラミング言語に対応しています。まずは手っ取り早くシェルでお試し。

github.com

macOSなら以下のようにインストール可能です。

curl -sSL https://git.io/get-mo -o mo
chmod +x mo
mv mo /usr/local/bin/

以下のようなテンプレートを用意して

Kanazawa.rb meetup {{SERIES_NO}} を{{DATE}}に開催します。内容は「{{TITLE}}」。{{DESCRIPTION}}場所は{{PLACE}}。詳細はこちら。

https://kzrb.org/meetup/{{SERIES_NO}}/

#kzrb

環境変数を渡して実行すると以下のように出力されました。

$ SERIES_NO=73 DATE=2018-09-15 TITLE=意識高いもくもく会 DESCRIPTION=各自で目標を設定する自主勉強会です。 PLACE="ITビジネスプラザ武蔵 研修室2" mo template.txt

Kanazawa.rb meetup 73 を2018-09-15に開催します。内容は「意識高いもくもく会」。各自で目標を設定する自主勉強会です。場所はITビジネスプラザ武蔵 研修室2。詳細はこちら。

https://kzrb.org/meetup/73/

#kzrb

まあ、なんか良さそう。今後は実用化に向けて、GitHub Issueと絡めて上手くmeetup準備フローに組み込めないかなと考えております。以下当日書いていたメモ。

LTした

以下の内容で話しました。今回は Dropbox Paper でばーっと書いてプレゼンテーションモードで見せる、という発表方法にしたのですがブログに載せるときにはスライドとして作るという作業が必要そうですね...


batコマンドのご紹介

https://github.com/sharkdp/bat

A cat(1) clone with wings.


  • catコマンドのクローン
    • バッチファイルの類いではない
    • Rustで実装されている
  • チームメイトから教えてもらって良さげだと思ったので紹介
    • brew install bat

  • bat README.md


  • catにない特徴
    • シンタックスハイライト
    • gitとの連携(差分表示)
    • ページング
    • デフォルトで行番号表示(catには行番号表示オプションあり)

  • ヘルプがカラー対応、ナウい
    • bat --help

  • シンタックスハイライトは多くの言語、ファイルタイプに対応
    • bat --list-languages

  • テーマを変えることができる
    • bat --list-themes

  • プレーンな表示だと見づらいファイルを見ながら作業したいとき
    • 例えばREADME, JSON, yaml, Dockerfile
    • 今まではvimを開いて見ていた
    • batで十分な場面がほとんどなので役立ちそう

懇親会

www.hotpepper.jp

retty.me

5人でこじんまりとわいわい飲みました。今回初めて参加した方は、東京の会社に属して金沢でリモートワークしているとのこと。リモートワーク事例じわじわ増えてきてますね。二次会ではガリ酎飲んでガリ〆鯖を食べるというガリ三昧を体験してきました。

ScalaTest の OptionValues が良さげ

ScalaTestを使っていて便利な機能があったので小ネタとして紹介してみます。

OptionValues

Option 型の値を検証したいときに、 OptionValues を使うとOption値が定義されているかとその値についての検証を同時に行うことができます。

http://www.scalatest.org/user_guide/using_OptionValues

// やりがちな例
opt.get should be > 9 // opt が Noneの場合 NoSuchElementException が起きてテストが失敗する(後述)

// より安全な方法
opt should be ('defined) // opt が None の場合 TestFailedException が発生。どこで失敗したかの情報が得られる
opt.get should be > 9

// OptionValuesを使う
import org.scalatest.OptionValues._

opt.value should be > 9 // Option型の値に対して `value` メソッドを使えるようになる
// opt が None の場合 TestFailedException が発生

// テストクラスに対しては OptionValues trait を mix-in するとよい
class ExampleSpec extends WordSpec with Matchers with OptionValues {
  // この中のテストコードで `value` メソッドを使えるようになる
}

実際やってみるとこんな感じです。

import org.scalatest.{Matchers, OptionValues, WordSpec}

class ExampleSpec extends WordSpec with Matchers with OptionValues {

  "Option value is defined" in {
    val opt: Option[Int] = Some(10)
    opt.value should be > 9
  }

  "Option value is defined but is not match condition" in {
    val opt: Option[Int] = Some(1)
    opt.value should be > 9
  }

  "Option value is not defined" in {
    val opt: Option[Int] = None
    opt.value should be > 9
  }

  "Option value is not defined and access with get" in {
    val opt: Option[Int] = None
    opt.get should be > 9
  }
}

以下はテスト実行時の出力。注目してほしい点は3番目と4番目のテストの違いで、 value を使った場合はテストの失敗内容が簡潔にまとめられて出力されていますが、 get を使った場合は通常の例外における出力(Exceptionのメッセージ + スタックトレース)となっています。

[info] ExampleSpec:
[info] - Option value is defined
[info] - Option value is defined but is not match condition *** FAILED ***
[info]   1 was not greater than 9 (ExampleSpec.scala:12)
[info] - Option value is not defined *** FAILED ***
[info]   The Option on which value was invoked was not defined. (ExampleSpec.scala:17)
[info] - Option value is not defined and access with get *** FAILED ***
[info]   java.util.NoSuchElementException: None.get
[info]   at scala.None$.get(Option.scala:349)
[info]   at scala.None$.get(Option.scala:347)
[info]   at ExampleSpec.$anonfun$new$4(ExampleSpec.scala:22)
[info]   at ExampleSpec$$Lambda$5658/224979600.apply(Unknown Source)
[info]   at org.scalatest.OutcomeOf.outcomeOf(OutcomeOf.scala:85)
[info]   at org.scalatest.OutcomeOf.outcomeOf$(OutcomeOf.scala:83)
[info]   at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
[info]   at org.scalatest.Transformer.apply(Transformer.scala:22)
[info]   at org.scalatest.Transformer.apply(Transformer.scala:20)
[info]   at org.scalatest.WordSpecLike$$anon$1.apply(WordSpecLike.scala:1078)
[info]   ...
[info] ScalaTest
[info] Run completed in 436 milliseconds.
[info] Total number of tests run: 4
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 1, failed 3, canceled 0, ignored 0, pending 0
[info] *** 3 TESTS FAILED ***
[error] Failed: Total 4, Failed 3, Errors 0, Passed 1
[error] Failed tests:
[error]     ExampleSpec
[error] (Test / testOnly) sbt.TestsFailedException: Tests unsuccessful
[error] Total time: 2 s, completed 2018/08/26 11:35:09

EitherValues, TryValues, PartialFunctionValues

OptionValues と同じような働きをするtraitは他にもあって EitherValues TryValues PartialFunctionValues というものがあります。これも中の値の定義と検証を同時に行い、失敗した場合は TestFailedException を起こしてくれます。

http://www.scalatest.org/user_guide/using_EitherValues

http://www.scalatest.org/user_guide/using_PartialFunctionValues

(なぜかTryValuesについてのページは存在しない😅)

// TryValues
import org.scalatest.TryValues._

val try1: Try[Int] = Try { 100 / 10 }
val try2: Try[Int] = Try { 1 / 0 }
// enable `success` and `failure`
try1.success.value should be > 9
try2.failure.exception should have message "/ by zero"

// EitherValues
import org.scalatest.EitherValues._

val either1: Either[String, Int] = Right(10)
val either2: Either[String, Int] = Left("Muchas problems")
// enable `value`
either1.right.value should be > 9
either2.left.value should be ("Muchas problemas")

// PartialFunctionValues
import org.scalatest.PartialFunctionValues._

val pf: PartialFunction[String, Int] = Map("I" -> 1, "II" -> 2, "III" -> 3, "IV" -> 4)
// enable `valueAt`
pf.valueAt("IV") should equal (4)

Kanazawa.rb meetup #72 に参加しました #kzrb #ふくもく会

kzrb.doorkeeper.jp

fukumoku.connpass.com

今回はKanazawa.rb 6周年記念回ということで恒例のLT大会が行われました。また、同時刻にふくもく会も開催されており拠点をzoomで繋いで発表し合うというスタイルでした。

6周年記念のカラビナ。普段使いにも良さそう。(雑に接続した模様です...)

話したこと

Webアプリケーションを開発するに当たって意識していることを雑に発表しました。チーム内で言われていることだったり、meetupで聞いたことだったり影響を受けているものは結構あります。

初めの2つに関しては前々から言われていることではありますが、チーム内でフォーカスが当たることが多かったので採り上げてみました。そういえばリーダブルコードでそんな話あったなと思い調べてみたらやっぱり書いてありました。テストコードの話については、異常系のテストケースは完全になることはなくて漏れることは多々あるので生じたバグに対して積み上げていくのがいいんじゃないかなと最近思ってます。発表では触れてませんがProperty Based Testingについても調べてみたいなと思ってます。

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

拾いきれなかった質問というかツイートがあったので補足すると、私は『The RSpec Book』を読んでこんな感じでテスト書いてけばいいのかーというのをきっかけにした感じです。実際はBDDのお話がメインにはなってくるのですが。あとは『Everyday Rails - RSpecによるRailsテスト入門』という電子書籍が出ていて、こちらは最新の環境に追随していてかつ実践的な内容なのでRailsを使っている|使おうとしているならばオススメです。実践の話で言うと、自分の実装部分からテストを書いてみるという手法があって、最初は最低限のもの(自分の触る単一のメソッドに対して等)だけ書いてって少しづつサイクルを回していくということは過去に経験しました。そのときは、プロジェクト自体にほとんどテストコードが無かったのでちょうど勉強してたし書いてみるかーと手を付けた流れでした。

カバレッジに関しては最初から数字を目的にするのは相応しくないなーと思ってまして、設計の元になる、ドキュメントになるというのが本質的にあって結果としてこのくらいカバーしてますよと。それと並行して、品質を担保するのにユニットテストをもっとやるのか、E2Eテストをやるのか、方法はいろいろあると思いますけどもどのようにしていくかというのを決めて、ユニットテストカバレッジはこれくらいあればいいよねと言う話になるのかなと思っています。あまりうまくまとまってませんが、こんな感じです。

The RSpec Book (Professional Ruby Series)

The RSpec Book (Professional Ruby Series)

leanpub.com

懇親会

www.hotpepper.jp

1次会はビアガーデン!こちらも毎年恒例になってますね😊 2次会は新天地のディラン、北dev勢にはおなじみのお店。運営の話や、地方でこの先生きのこるにはといったような話題が。また来月もやっていきましょう。

JAWS-UG金沢 #34 に参加しました #jawsug

jawsug-kanazawa.doorkeeper.jp

AWS Summit Tokyo 2018で開催された、AWSクラウド上のマネージド・サービスをサーバレスアーキテクチャで組み合わせたアプリケーションの開発方法を学ぶ、開発者向けのハンズオンイベント Dev AWSome Day で利用された教材を使ってサーバレスアプリケーションを開発するもくもく会が行われました。

流れ

先ほどのDev AWSome Dayリンクのタイムテーブルに添って開発を進めていきました。画像をアップロードして画像認識処理によってラベルを取得し保存。保存した画像とラベルデータを一覧で表示する。というWebアプリケーションを開発するというテーマでした。

  • 開発用IAMユーザーの作成、IAMロールの作成・割り当て
  • AWS Cloud9(IDE)を使った開発
    • 開発に使うのはPython(Lambda), node.js(Lambda), React(Frontend)
  • Amazon Cognitoユーザープールの作成、フェデレーティッドアイデンティティの利用
  • Amazon S3への画像データアップロード
  • アップロードされた画像をRekognitionに処理させる
    • S3にPutされたイベントによりLambdaでの処理がキックされる
  • DynamoDBへのラベルデータの保存
  • API Gatewayを利用しDynamoDBからデータを一覧取得
  • Extra 1. Rekognitionの有名人検出機能を使って有名人のラベルを取得する
  • Extra 2. 画像の削除機能

感想など

私が特に気になっていたのはAmazon Cognitoを使う部分で、調査で少しだけ触った程度なので実際のアプリケーションと合わせて使うとどう便利になるんだろうという観点でした。流れとしては、まずユーザープールを作成します。これによってユーザーのサインアップとサインイン、プロフィール(属性)の管理ができるようになります(大まかな機能)。次にフェデレーティッドアイデンティティを作成します。これは、AWSサービスに対する認可、すなわちアクセスの制御機能を提供します。この2つを組み合わせることによって、サインしたユーザーはS3とAPI Gatewayにアクセスできて、ゲストユーザーはS3 GETだけアクセスできるというような制御を行うことができます。

docs.aws.amazon.com

良さげだなと思ったのは、AWS Amplify というJavaScriptのライブラリでReactで利用できる認証コンポーネントが提供されてることです。詳しくは AWSの次世代JavaScriptライブラリ「AWS Amplify」の概要とReactアプリに導入する手順 #serverless #adventcalendar | Developers.IO で書かれていますが、Authenticator というコンポーネントを使うだけでサインアップ、サインイン処理が一発で使えるようになる、さらにサインアップ時の認証コードまで利用できる(これはCognitoユーザープールの機能かと思う)というのはアプリケーション開発者観点で驚きました。

また、S3やAPI Gatewayへのリクエスト時(AmplifyのAPIを使う)にフェデレーティッドアイデンティティによって払い出される認証情報が自動的に付与され、アプリケーション開発者としては認可についてもあまり意識しないでいい作りになっていました。

今回DynamoDBには一意のユーザー名をキーにデータを登録していましたが、ユーザーが作成する他のデータとどう結びつけるかというのは設計において悩みそうだなと思いました。あと、ローカルで開発するときはCognitoにアクセスしないといけないのかなー、そもそもCloud9で開発すればええやろ?みたいな思想なのかな、というのも気になりました。

その他の感想としては、

  • RekognitionはAPIで手軽に使えて良い(たしかGoogle Cloud Vison APIもお手軽だった)
  • CORSの対応について少し理解が進んだ
  • Lambdaデプロイいくつか方法がある(CLI, SAM(CloudFormation))
  • DynamoDB Stream初めて使った
  • ReactでDOMを削除するのよく分からなかった(結局イベントが起きたときに非表示にするというので逃げた)

複数のAWSサービスを触ることができたので復習にもなったし、実際動くものができてくるとやっぱり楽しいですね。 ここ数年サーバーサイド(API)の開発ばかりやっているので、ReactやVue.jsを使ったフロントエンドの開発もやりたいなーと思いました(実戦できるかは置いといて)。

JAWS-UG金沢 #33 に参加しました #jawsug

jawsug-kanazawa.doorkeeper.jp

今回は6月に行われたAWS Summit Tokyoの報告会ということで、AWS Summitに数年行ってない身としては雰囲気つかんでおこうと思い参加しました。(たしか2013年に行ったきり。)

発表

加藤さん(@PharaohKJ)「AWS Summit Tokyo 行ってきた」

(写真は最初の挨拶のときのもの)

  • Well-Architected framework を読もう
  • 公式にホワイトペーパーが出ていて以下のリンクからダウンロードできます。英語版は2018年6月版で、日本語版は2016年11月版でした(記事掲載時点)。
  • PDF(English)
  • PDF(日本語)
  • Windows系のアプリケーションを使ったり検証したりするときは、手元のMacWindows VM立ち上げるよりWorkSpaces使った方が快適とのこと
    • 最近 AppStream 2.0 がリリースされてこっちも場合によってはいいかもしれない

相羽さん(@aibax)「AWS Cloud9 を使ってサーバレスアプリケーションを作ってみた」

  • デモを交えながらCloud9というWebブラウザから操作できるIDEを使って、サーバレスアプリケーションを作る一連の流れを紹介
  • AWS Lambda用のコードをその場でデバッグできるのはすごく良いなあと思いました。

でむらさん「今時のEC2事情」

  • 最近C5系のインスタンスタイプが登場したので、C4.largeとC5.largeの性能比較を行った
  • まだ大量に調達するのは厳しいように思われる
  • Amazon Linux2について

沼口さん「成長するコミュニティとの付き合い方」

  • JAWS-UGのこれまでの成長について
  • スケールアップ型成長とスケールアウト型の成長
  • 自走できるコミュニティ + AWS社員のサポート

松下さん 各社の開発ブログ記事を集めて取得するバックエンドサービスをサーバーレスで作った話

(写真撮りわすれてました。すいません)

  • 飛び入りでLTしてくれた
  • SAMを使って簡単に環境を構築できた
    • template.yamlは100行未満
  • 定期処理の実行はCloudWatch Eventsをトリガーに使っている
  • 以下リポジトリで詳細見れます

github.com

フリーディスカッションタイム

懇親会に行けない人もいるため、会の途中に名刺交換したりあれこれ話したりという時間が設けられました。こういうトピックについて知りたい・知見がある、じゃあそういう会やりましょう、という流れになって中々熱かったです!

沼口さんよりAWSノベルティがいろいろと提供されたんですが、じゃんけんに勝ってJAWS-UG re:MIX Tシャツを頂きました。ありがとうございます!!!

懇親会

www.jyu-ninotsuki.com

美味しい魚と日本酒を頂きましたー。認定ソリューションアーキテクト取るときがやってきそうだって言う話をしていた覚え。

www.hotpepper.jp

二次会はビールとドイツ料理。k8sの良さについて、DynamoDBについてなどなど語ってました。