Shogo's Blog

Dec 6, 2019 - 1 minute read - go github

CloudFormationのテンプレートのLinter actions-cfn-lint のご紹介

この記事はフラーAdvent Calendar 2019の6日目の記事です。 5日目は@shogo82148 さんで「GitHub Goveralls Action を公開しました」でした。 さて、最近 GitHub Actions を作るのにハマっているので、今日も GitHub Actions の紹介です。 GitHub Action for CloudFormation Linter with reviewdog shogo82148/actions-cfn-lint Amazon CloudFormation Infrastructure as Code の盛り上がりも一段落し、今では当たり前のように使っている人も多いと思います。 フラー共創スタジオはAWSがメインなので、CloudFormationをメインに使っています。 色々とクセは強いですが、少なくともtfstateが行方不明になったりはしないので、まあまあ仲良くやっています。 CloudFormation Linter テンプレートを書いている上で地味にややこしいのが、プロパティーの名前や型の統一感が微妙にない、ということです。 例を挙げると、AWS::ApplicationAutoScaling::ScalableTarget の MaxCapacity は整数型です。 これはまあ、納得できますね。 ところが AWS::AutoScaling::AutoScalingGroup の MaxSize は 文字列型 なんです。説明文には「Auto Scaling グループの Amazon EC2 インスタンスの最大数」とあるのに! オートスケールという似たような機能を持っていて、どちらもスケーリンググループの最大数を表しているの、名前も違えば型が全く違う。 この手のミスは aws cli に付属している テンプレートの validation 機能では見つけられす、実際に反映してみるしかありません。 すぐに失敗してくれればいいんですが、失敗するまでにも十数分かかったりしてかなり面倒です。 そこでおすすめなのが CloudFormation Linter。 この手の名前のミスや型のミスを指摘してくれるコマンドラインツールです。 各種エディタ用の拡張もあり、VSCodeでも使える ので、ぼくはいつもこれを使っています。 CloudFormation Linter については Classmethod さんの紹介記事もどうぞ。

Dec 5, 2019 - 2 minute read - go github

GitHub Goveralls Action を公開しました

この記事はフラーAdvent Calendar 2019の5日目の記事です。 4日目はふるふる先生の「GoでJSONを良い感じに使おうと思ってハマった話」でした。 さて、首を長くして待っていた GitHub Actions がついにGAになりましたね。 (日本語版ヘルプだとまだbetaになってますが) さっそくActionを自作してちょっと前に公開してたんですが、この機会に紹介しようと思います。 actions-goveralls - Actions GitHub Marketplace shogo82148/actions-goveralls 使い方 coveralls.io はコードカバレッジの可視化サービスです。 実は公式でGitHub Actionsを提供しており、Coveralls GitHub Action を使うと 「JavaScriptのプロジェクトであれば」簡単にカバレッジを送信することができます。 しかし、Goが出力するカバレッジはJavaScriptと形式が違うので、そのままは使えません。 他のCIではmattn/goverallsにお世話になっていたので、 これを GitHub Actions として簡単に使えるようにしました。 最小限の設定はこれだけです。 # ここらへんにテストとかの設定ば別途描く # coveralls.io に送信 - uses: shogo82148/actions-goveralls@v1 with: github-token: ${{ secrets.GITHUB_TOKEN }} path-to-profile: profile.cov 簡単ですね。 マトリックスビルド され、後発なだけあって GitHub Actions では他のCIの便利な機能を簡単に使えます。 その中でも最も便利(偏見)なのがマトリックスビルドです。 例えば以下のように設定するだけで、Linux, macOS, Windows で同じテストを実行できます。 strategy: fail-fast: false matrix: os: - ubuntu-latest - macos-latest - windows-latest runs-on: ${{ matrix.

Sep 18, 2019 - 2 minute read - perl github

Setup Perl GitHub Action を公開しました

GitHub Actions の公式レポジトリには Perl のセットアップアクションが無いぞ! ということで三連休+αで書きました。 actions-setup-perl on GitHub Marketplace 使い方 Marketplaceの設定例は間違えているので以下を参照。(これ書いていて気がついた) 必要な Perl のバージョンを渡すだけです。簡単! steps: - uses: actions/checkout@master - uses: shogo82148/actions-setup-perl@v1 with: perl-version: '5.30' - run: cpanm --installdeps . - run: prove -lv t Ubuntu, macOS, Windows 各種OSにも対応しています。 jobs: build: runs-on: ${{ matrix.os }} strategy: matrix: os: ['ubuntu-18.04', 'macOS-10.14', 'windows-2019'] perl: [ '5.30', '5.28' ] name: Perl ${{ matrix.perl }} on ${{ matrix.os }} steps: - uses: actions/checkout@v1 - name: Setup perl uses: shogo82148/actions-setup-perl@v1 with: perl-version: ${{ matrix.

Aug 21, 2019 - 1 minute read - perl lambda

AWS Lambda Perl Runtime で AWS X-Ray を使えるようになりました

AWS Lambda 上で Perl を動かす AWS::Lambda で、 AWSの分散アプリケーションの分析サービスである AWS X-Ray をサポートしました! AWS X-Ray って何? Perl からどう使うの? という人は @fujiwara さんの記事とYAPC::Tokyo 2019での発表スライドをどうぞ。 第56回 AWS X-Rayによる分散トレーシング―マイクロサービスのボトルネック,障害箇所の特定(1) 第56回 AWS X-Rayによる分散トレーシング―マイクロサービスのボトルネック,障害箇所の特定(2) 第56回 AWS X-Rayによる分散トレーシング―マイクロサービスのボトルネック,障害箇所の特定(3) 使ってみる Perl Runtime だけでなくX-Ray SDK 側でも対応が必要だったので、プルリクエストを送って取り込んでもらいました。 このプルリクエストがマージされた最新の AWS::XRay を Perl Runtime Layer にプリインストールしたので、あなたのアプリケーションですぐに使えます。 例えばこんな感じのコードを書いて、 use utf8; use warnings; use strict; use AWS::XRay qw/ capture /; sub handle { my ($payload, $context) = @_; capture "myApp" => sub { capture "hogehoge" => sub { sleep 1; }; capture "fugafura" => sub { my $segment = shift; $segment->{metadata} = $payload; }; }; return +{"hello" => "lambda"}; } 1; Layer に X-Rayに対応した最新の Perl Runtime arn:aws:lambda:ap-northeast-1:445285296882:layer:perl-5-30-runtime:3 を追加、 マネージドコンソールの「Debugging and error handling」セクションにある「Enable AWS X-Ray」を有効化し、実行してみます。

Jul 24, 2019 - 2 minute read - go golang

Goのバイナリに静的ファイルを埋め込むツール assets-life を書いた

日本語の Go コミュニティだと go-bindata (なんか乗っ取り騒動とか色々あってメンテナンスされてない), go-assets (最近メンテナンス滞りがち) が有名(要出典)なやつです。 これらのライブラリに関してたくさん日本語記事が書かれて、今もたくさん検索に引っかかるのですが、残念ながら最近はメンテナンスが滞っています。 最近は statik の名前もよく見るようになりました。 その他は Resource Embedding - Awesome Go からどうぞ。 で、まあ、今回も完全に車輪の再発明なんですが、他の実装には色々と思うところがあり書いてみました。 shogo82148/assets-life USAGE なにはともあれ、まずは go get してきます。 $ go get github.com/shogo82148/assets-life assets-life というコマンドがインストールされるので、 バイナリに組み込みたいディレクトリと出力先を指定します。 $ assets-life /path/to/your/project/public public 出力先のディレクトリは Go のパッケージとしてインポートできるようになってます。 Root という変数のなかにファイルが埋め込まれており、http.FileSystem インターフェースを介してアクセスできます。 import ( "net/http" "example.com/your/project/public" ) func main() { http.Handle("/", http.FileServer(public.Root)) http.ListenAndServe(":8080", nil) } 特長 コードの再生成にコマンドのインストールが不要 これが一番の特長です。 バイナリにファイルを埋め込む都合上、静的ファイルを修正した場合にコードの再生成が必要です。 assets-life は go:generate ディレクティブを埋め込んだコードを出力するので、コードの再生成は go generate でできます。 # /path/to/your/project/public に修正を加える # コードの再生を行う $ go generate example.

Jul 22, 2019 - 3 minute read - go golang

Goで指数的バックオフをやってくれるgo-retryを書いた

完全に車輪の再発明なんですが、他の実装には色々と思うところがあり書いてみました。 shogo82148/go-retry MOTIVATION カッコいいインターフェースが欲しい インターフェースは lestrrat さんのこの資料を参考にしています。 GoらしいAPIを求める旅路 (Go Conference 2018 Spring) from lestrrat 「これ、Loop Condition だ」のあたりで、なるほど!と思ってインターフェースを真似てみました。 このインターフェースに沿って、lestrratさん自身が実装した lestrrat-go/backoff があります。 しかし、個人的にちょっと実装が複雑だなと感じたので、もうちょっとシンプルに書けないかとやってみました。 Context サポート 先行実装たちは Context がGoに取り込まれる前からあるので、 Contextに対応したインターフェースが後付だったり、 そもそもContextに対応していなかったりします。 Context未対応の Go 1.5 はすでにサポート対象外なので、もう Context が存在しない実行環境は考えなくてよいはずです。 SYNOPSIS Loop Condition Interface 使い方は lestrrat-go/backoff と大体一緒。 指数的バックオフに必要な各種パラメーターをポリシーとして与え、リトライのためのループを回します。 // 指数的バックオフの各種パラメーターをポリシーとして定義 var policy = retry.Policy{ // 初回待ち時間 MinDelay: 100 * time.Millisecond, // 最大待ち時間 MaxDelay: time.Second, // 最大試行回数 MaxCount: 10, } func DoSomethingWithRetry(ctx context.Context) (Result, error) { retrier := policy.

Jul 16, 2019 - 2 minute read - perl aws lambda

AWS SDK for Perl Lambda Layerを公開しました

ハイラルからこんにちは。 AWS LambdaでCGIを蘇らせる で作成した Perl Custom Runtime 用の AWS Lambda Layer ですが、 中でイベントのハンドリングをしているモジュールを AWS::Lambda として CPAN で公開したところ、 AWS SDKを入れて欲しい との要望が来ました。 完全にネタとして作成したモジュールですが、いるんですね使う人。 というわけで AWS SDK を含んだ AWS Lambda Layer を公開しました。 使い方 公開レイヤーを使う AWS公式ではPerl用のSDKは提供していないので、Pawsという非公式SDKを使いました。 何も考えずにテキトウにインストールしてみたらSDKだけで121MBありました。 Perl本体が85MBなのでSDKのほうがでかい。 AWS Lambdaで作成できる関数は250MBが上限なので、流石に半分SDKに持っていかれるのはつらかろうと、Perl本体とは別のレイヤーに分けてあります。 レイヤーは最大5つまで登録できるので、Perl本体(例: arn:aws:lambda:ap-northeast-1:445285296882:layer:perl-5-30-runtime:2 )に加えて 以下のレイヤーを追加することで、Paws を呼び出すことができるようになります。 arn:aws:lambda:ap-east-1:445285296882:layer:perl-5-30-paws:1 arn:aws:lambda:ap-northeast-1:445285296882:layer:perl-5-30-paws:1 arn:aws:lambda:ap-northeast-2:445285296882:layer:perl-5-30-paws:1 arn:aws:lambda:ap-south-1:445285296882:layer:perl-5-30-paws:1 arn:aws:lambda:ap-southeast-1:445285296882:layer:perl-5-30-paws:1 arn:aws:lambda:ap-southeast-2:445285296882:layer:perl-5-30-paws:1 arn:aws:lambda:ca-central-1:445285296882:layer:perl-5-30-paws:1 arn:aws:lambda:eu-central-1:445285296882:layer:perl-5-30-paws:1 arn:aws:lambda:eu-west-1:445285296882:layer:perl-5-30-paws:1 arn:aws:lambda:eu-west-2:445285296882:layer:perl-5-30-paws:1 arn:aws:lambda:eu-west-3:445285296882:layer:perl-5-30-paws:1 arn:aws:lambda:sa-east-1:445285296882:layer:perl-5-30-paws:1 arn:aws:lambda:us-east-1:445285296882:layer:perl-5-30-paws:1 arn:aws:lambda:us-east-2:445285296882:layer:perl-5-30-paws:1 arn:aws:lambda:us-west-1:445285296882:layer:perl-5-30-paws:1 arn:aws:lambda:us-west-2:445285296882:layer:perl-5-30-paws:1 いつの間にかマネージドコンソールから編集ができるようになっていたので、開発がはかどりますね。 カスタムランタイムでもAWS Lambdaのマネージドコンソールから内容の編集ができる・・・? Perl も編集できるぞ・・・ pic.twitter.com/4228rG0hca — Ichinose Shogo (@shogo82148) July 16, 2019 ZIP アーカイブを使う ビルド済みのZIPアーカイブも公開しています。 以下のURLを指定して新規レイヤーを作成することで利用できます。

Jul 2, 2019 - 1 minute read - polyglot go golang perl php ruby

GoのバイナリをRubyスクリプトとしても扱う

$ ruby --help Usage: ruby [switches] [--] [programfile] [arguments] (中略) -x[directory] strip off text before #!ruby line and perhaps cd to directory (後略) なんか Ruby にも -x あるらしいので。 package main import ( "fmt" "runtime" ) const script = ` #!ruby puts "Hello Ruby World!!\n" __END__ ` func init() { runtime.KeepAlive([]byte(script)) } func main() { fmt.Println("This is Go world!!") } はい。 $ go build -o main main.go $ ./main This is Go world!

May 27, 2019 - 1 minute read - go golang time

サーバーの時刻を伝える time wellknown uri を実装してみた

インターネットをさまよっていたら、 /.well-known/time の存在を知ったので、雑に実装してみました。 使い方 うまいこと共存できそうだったので、HTTP/WebSocketで時刻同期するWebNTPを書いた で作成した WebNTP の一部として実装してあります。 shogo82148/go-webntp $ go get github.com/shogo82148/go-webntp/cmd/webntp $ webntp -serve :8080 $ curl -I localhost:8080/.well-known/time HTTP/1.1 204 No Content X-Httpstime: 1558915632.285965 Date: Mon, 27 May 2019 00:07:12 GMT 仕様 HTTPには「予約済みのURI」というものが定義されています。(RFC5785)。 Well-Known URIs Let’s Encrypt でドメインの所有権確認に使用される ACMEプロトコル(RFC8555) や、 Mastodon のユーザーディスカバリーに使用する WebFinger(RFC7033)等々、 近年話題になったサービスの裏方で使われています。 /.well-known/acme-challenge ACMEプロトコル(RFC8555) /.well-known/webfinger WebFinger(RFC7033) Time over HTTPS も Well-Known URIs を利用するプロトコルのひとつです。 /.well-known/time Time over HTTPS specification 仕様としては非常に単純で、サーバー側は HTTP の HEAD に対して、 Date ヘッダーをつけたリクエストを返すだけ。 より高精度な時刻を得るために X-HTTPSTIME ヘッダーに秒未満の情報を入れた Unix タイムスタンプ を返すこともできます。

Apr 17, 2019 - 3 minute read - go golang aws cloudformation mackerelio

CloudFormationのMackerel用インテグレーションを作ってる話

Mackerel は mkr コマンドを用いて cli から操作ができます。 mkr コマンドを用いると 監視ルールを GitHub で管理 したり、 カスタムダッシュボードを管理したり、といったことができます。 しかし、個人的に以下のような不満があります。 サービス、ロール、ホスト、新ダッシュボード等々、監視設定以外のリソースに対応していない 旧ダッシュボードは対応しているんだけど、新ダッシュボード対応がまだ 新ダッシュボードのUIは使いやすくてすごくいいんだけど、コピペや一斉置換ができないので、テキストで管理したい 出力がJSONなのつらい JSON手で書くの難しくないですか? メトリックスの送信設定と監視設定の管理が別になってしまう カスタムメトリックス送っているのに監視設定を忘れた、みたいなことが起こる メトリックスの送信設定については、以前 サーバーレスでCloudWatchメトリクスをMackerelに転送する で CloudFormation上での管理を実現しました。 ここにさらに Mackerel の監視設定を追加できれば、最強なのでは?とやってみました。 例 あれこれ説明する前に例を見てもらったほうがわかりやすいと思うので、こんなことができますよ、という設定例から。 例1: レスポンスタイムの99%パーセンタイルを監視する Mackerel の AWSインテグレーション は ALB に対応していますが、 レスポンスタイムのメトリックスは平均レスポンスタイムだけです。 「平均」は代表的な統計値ですが、全体としては速いんだけど一部のリクエストだけ遅い、という状況を見逃してしまいます。 レスポンスタイムの大まかな分布をパーセンタイルで把握したい、ということはよくありますよね? (K社でZabbixを使って監視していたときによくお世話になった) 今回作ったインテグレーションを使えば、以下のように「Mackerelのサービス定義」「メトリックスの転送設定」「監視設定」が CloudFormation のテンプレートとして表現できます。 AWSTemplateFormatVersion: 2010-09-09 # Type: Mackerel::* を使うためのおまじない Transform: - AWS::Serverless-2016-10-31 - Mackerel - JSONString Resources: MackerelService: Type: Mackerel::Service Properties: Name: "awesome-service" # メトリックスを転送する Lambda 関数 MetricsForwarder: Type: AWS::Serverless::Application Properties: Location: ApplicationId: arn:aws:serverlessrepo:us-east-1:445285296882:applications/mackerel-cloudwatch-forwarder SemanticVersion: 0.