GitHub ActionsのOIDC id tokenでGCPにアクセスしてみた

巷で話題になってるGitHub Actionsのid tokenでGCPにアクセスしてみた。

AWS federation comes to GitHub Actions | Aidan Steele’s blog (usually about AWS)

これを参考に試してみた。

GCP

以下、49482415725, ryotarai-github-oidc-sampleはproject number, project ID(このprojectは削除済み)

cloud.google.com

これを参考にWorkload Identityまわりの設定をする。

まず、IAM, Resource Manager, Service Account Credentials, and Security Token Service (STS) API を有効にする。

gcloud iam workload-identity-pools create github-oidc-sample \
  --location="global" \
  --description="github-oidc-sample" \
  --display-name="github-oidc-sample"
gcloud iam workload-identity-pools providers create-oidc github-oidc \
  --workload-identity-pool="github-oidc-sample" \
  --issuer-uri="https://vstoken.actions.githubusercontent.com" \
  --location="global" \
  --attribute-mapping="google.subject=assertion.sub" \
  --allowed-audiences="https://github.com/ryotarai/github-oidc-gcp-sample"

github-oidc-sample, github-oidcは適当に名前をつけた箇所。

providerをつくるときにallowed-audiencesを指定しておくこと。デフォルトだとaudにはリポジトリのURLが入ってくるっぽいのでそれを指定しておく。

gcloud iam service-accounts add-iam-policy-binding viewer@ryotarai-github-oidc-sample.iam.gserviceaccount.com \
  --role=roles/iam.workloadIdentityUser \
  --member="principal://iam.googleapis.com/projects/49482415725/locations/global/workloadIdentityPools/github-oidc-sample/subject/repo:ryotarai/github-oidc-gcp-sample:ref:refs/heads/main"

viewer@ryotarai-github-oidc-sample.iam.gserviceaccount.comは事前に作っておいたSA。このSAの権限が使えるようになる。 このmemberのフォーマットは https://cloud.google.com/iam/docs/access-resources-oidc#iam-workload-pools-create-gcloudあたりを参照。上記の場合、特定のsubject(repo:ryotarai/github-oidc-gcp-sample:ref:refs/heads/main)を指定している。

GitHub Actions

適当なAPIをつかうなにかを書いて

# client/main.go
package main

import (
    "context"
    "log"

    "cloud.google.com/go/storage"
)

func main() {
    ctx := context.Background()

    // Sets your Google Cloud Platform project ID.
    projectID := "ryotarai-github-oidc-sample"

    // Creates a client.
    client, err := storage.NewClient(ctx)
    if err != nil {
        log.Fatalf("Failed to create client: %v", err)
    }
    defer client.Close()

    // Creates a Bucket instance.
    iter := client.Buckets(ctx, projectID)
    attr, err := iter.Next()
    if err != nil {
        log.Fatalf("failed to iter: %s", err)
    }

    log.Printf("%+v", attr)
}

ワークフローを設定

# .github/workflows/sample.yml
name: sample
on:
  push:

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@v2

      - run: sleep 5 # there's still a race condition for now

      - name: id token sample
        run: |
          gcloud iam workload-identity-pools create-cred-config \
            projects/49482415725/locations/global/workloadIdentityPools/github-oidc-sample/providers/github-oidc \
            --service-account=viewer@ryotarai-github-oidc-sample.iam.gserviceaccount.com \
            --output-file=cred-config.json \
            --credential-source-url="$ACTIONS_ID_TOKEN_REQUEST_URL" \
            --credential-source-headers="Authorization=bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
            --credential-source-type=json \
            --credential-source-field-name=value
          export GOOGLE_APPLICATION_CREDENTIALS="$(pwd)/cred-config.json"

          cd client
          GO111MODULE=on go run .

f:id:ryotarai:20210916014004p:plain

branchを変えるとsubjectが変わるので、権限不足で失敗することも確認

f:id:ryotarai:20210916014208p:plain

SOELU株式会社に入社しました

2021/8/1付けでSOELU株式会社に入社しました。

SOELU

SOELU(ソエル)というオンラインヨガ・フィットネスのサービスを提供しています。

https://soelu.com

ヨガ・トレーニングのライブレッスンが受けられるサービスです。
特徴としては、インストラクターとの双方向のコミュニケーションがとれたり、他の参加者には自分の姿が見えないようになっていて安心だったり。
コミュニケーション取りたくないときはインストラクターの映像が見えるだけの参加方法もありますし、ライブではないビデオレッスンもあります。

30日間100円でトライアルできるんで、ぜひ試してみてください。

なんで入社したの

SOELUのCEO, COOとは新卒同期で、起業した当初からたまーにコンタクトをとってました。
今年入ってから副業でちょっと手伝うようになって、社員にならないかとオファーをもらって、入社しました。
入社の理由は

  • すでにユーザがいて、事業が伸びている
    • 個人的にはいわゆる0→1より、1→100的なフェーズのほうが得意な気がしている
  • まだ30人ぐらいの会社で、(執行役員として)上場に向けて挑戦できるチャンスなかなかなさそう
  • これから大きくなっていくのに向けて、これまでの会社での経験が活きそう
  • 技術スタック的にもスキルが活きそう
  • 小さい会社なので、コーポレートエンジニアリングとかセキュリティ周りのあれこれとか、あたらしい経験もできそう

という感じでしょうか。

技術スタック

雑にキーワードを並べるとこんな感じ。

(個人的には隙あらばGoを使っていきたいと思ってます)

開発チーム

エンジニアは一桁人、モバイルアプリは正社員は1名で、副業の方に手伝ってもらっています(募集中です!!)

www.wantedly.com

愉快な仲間たち

CTOの片岡↓

twitter.com

Webエンジニアのoreshinya↓

oreshinya.hatenablog.com

iOSエンジニアのmyammm_↓

note.com

採用してます

リモートワークメインなので、東京に住んでないという方でもぜひ。
(北海道に住んでいるメンバーもいます)

現在、iOS/Androidエンジニア募集中です!ちょっとでも興味ある方はhttps://twitter.com/ryot_a_raiにDMください。

その他のポジションは↓をごらんください。

www.wantedly.com

AWS Management ConsoleでSwitch Roleした際にヘッダの色を変更する

AWSのManagement Consoleに他のアカウントのロールになりすませる機能があります。

docs.aws.amazon.com

大変便利なんですが、うっかり意図したアカウントと違うアカウントで操作をしてしまうと大惨事になりかねないので、雑user jsでヘッダ全体の色を変えてます。 (以下のuser.jsではSwitch Roleしてないときに赤くしている)

ご活用ください。

f:id:ryotarai:20160914154513p:plain

gist.github.com

AWSマネジメントコンソールを開くAlfred Workflow

f:id:ryotarai:20160329001913g:plain

タイトルの通りですが、AWSのマネジメントコンソールを開くAlfred Workflowを作りました。使い方は以下のとおり。

  1. (Alfredをインストールする + Powerpackを買う)
  2. open_aws_console.alfredworkflowをダウンロードして開いてインストール
  3. Alfredでaws ec2のようにawsの後ろにサービス名をつなげる

サービスが増えたら適宜アップデートしていきます。 ぜひご活用ください。

Fluentdのin_forwardに流れているレコードをtcpdumpで見る

本番環境で動いているFluentdのin_forwardに何が流れているのかを知りたい、けど設定を触りたくない…みたいな場合に流れているタグやレコードを見る方法です。特にFluentdに限った話ではないですが、備忘録として書いておきます。

1. tcpdumpでキャプチャ

調べたいサーバ上で、tcpdumpを使ってパケットキャプチャを取ります。in_forwardのポート番号などを指定してキャプチャします。

$ sudo tcpdump -i eth0 -w fluentd.pcap port 24224 and tcp

2. tcptraceでTCPストリームのデータだけ吐き出す

tcptraceは-eオプションを渡すと、TCPストリームごとのデータをファイルに吐いてくれるのでこれを利用します。なお、tcptraceはHomebrewやaptで入ると思います。

$ tcptrace -e fluentd.pcap
1 arg remaining, starting with 'fluentd.pcap'
Ostermann's tcptrace -- version 6.6.7 -- Thu Nov  4, 2004

494 packets seen, 494 TCP packets traced
elapsed wallclock time: 0:00:00.005602, 88182 pkts/sec analyzed
trace file elapsed time: 0:00:25.927472
TCP connection info:
  1: host1:53633 - host2:24224 (a2b)  213>  213<  (reset)
  2: host1:53668 - host2:24224 (c2d)    1>    1<  (reset)
  3: host1:53669 - host2:24224 (e2f)   17>   17<  (reset)
  4: host1:53670 - host2:24224 (g2h)    1>    1<  (reset)
  5: host1:53671 - host2:24224 (i2j)   15>   15<  (reset)

Warning : some extracted files are incomplete!
          Please see -l output for more detail.

$ ls *_contents.dat
a2b_contents.dat e2f_contents.dat i2j_contents.dat

3. Fluentdのin_forwardに流す

あとは*.datファイルをFluentdのin_forwardに流し直すだけです。

たとえば、out_stdoutに吐くだけのFluentdを起動して、

$ cat fluentd.conf
<source>
  @type forward
</source>

<match **>
  @type stdout
</match>
$ fluentd -c fluentd.conf

ncで先ほどのdatファイルを食わせると、

$ cat *_contents.dat | nc localhost 24224

こんな感じでタグやレコードを見られます。

2016-02-22 20:10:58 +0900 test: {"agent":"foo","uuid":"574da95b-23f1-42eb-8738-d646588b5639"}
2016-02-22 20:10:58 +0900 test: {"agent":"foo","uuid":"0b585265-72de-4277-91bb-99c94e2e745b"}
2016-02-22 20:10:58 +0900 test: {"agent":"foo","uuid":"7c4a1b43-5c04-4bfc-8532-1f9533bc7828"}
2016-02-22 20:10:58 +0900 test: {"agent":"foo","uuid":"10b24574-f74c-465b-b2fa-92f124fcf85e"}
2016-02-22 20:10:58 +0900 test: {"agent":"foo","uuid":"064ad535-764b-4eaa-a67c-4dda4b0982ba"}
2016-02-22 20:10:58 +0900 test: {"agent":"foo","uuid":"76d67398-0f55-473e-abe3-a13ce14b31ad"}
2016-02-22 20:10:58 +0900 test: {"agent":"foo","uuid":"b499a04b-3d0d-4a88-8fdd-e5d8eb501d2e"}
2016-02-22 20:10:58 +0900 test: {"agent":"foo","uuid":"a7dcfbe6-fbfc-45d8-9702-fdc7ac9993d5"}

追記 2016/02/24

上記の手順でpcapファイルを変換するスクリプトを書いた

fluentd-pcap-converter.rb · GitHub

$ ls
host1.pcap
$ ruby fluentd-pcap-converter.rb host1.pcap
$ ls
host1.pcap
host1.pcap.output.20160224_0.log

tracking branchのremote URLをみるpropen

で知ったGitHub - 作業中ブランチのプルリクエストをブラウザで開く - Qiitaがとても便利なんですが、origin以外にpushしているとプルリクの作成ができない(すでにプルリクがある場合はリダイレクトされる)ので、tracking branchのremote urlを参照するやつを書いた

function propen() {
  local current_branch_name=$(git symbolic-ref --short HEAD | xargs perl -MURI::Escape -e 'print uri_escape($ARGV[0]);')
  local remote=$(git branch -vv | grep '^*' | awk '{ print $4 }' | cut -d/ -f1 | sed -e 's/^\[//')
  local repo_url=$(git remote show -n $remote | grep 'Push  URL' | grep -E -o '[^ ]+$' | sed -e 's|^https://||' -e 's/^git@//' -e 's/\.git$//' -e 's|:|/|')
  open "https://${repo_url}/pull/${current_branch_name}"
}
$ git remote add fork git@github.com:ryotarai/itamae.git
$ git push -u fork awesome-feature
$ propen

とか叩くと、https://github.com/ryotarai/itamae/pull/awesome-featureが開く

re:dash + BigQueryでクエリのコスト上限が指定できるようになった

昨日に引き続きre:dashネタです。BigQueryはクエリが処理したデータ量に応じて課金されます。使った分だけ払えばいい反面、高額クエリを流すとたいへんなことになります…。Custom Quotasで1日のコスト上限を設定できるようになりましたが、これは10TBの倍数でしか設定できず、一撃10TB(= $50)のクエリは流れてしまう可能性があります。

Total MByte Processed Limit

Feature: BigQuery: limit amount of MB processed per query by ryotarai · Pull Request #710 · getredash/redashがマージされ、データ量(BigQueryのAPIでいうtotalBytesProcessed)の上限を設定できるようになりました。

Data Sourceの設定画面で"Total MByte Processed Limit"を設定しておくと、

f:id:ryotarai:20151217005847p:plain

クエリ実行前にdry run実行が行われ、指定した上限を超えた場合にエラーになります。

f:id:ryotarai:20151217005852p:plain

うっかり高額クエリを流さないためにご活用ください

(あくまで、1クエリのコストを制限出来るだけなので、Custom Quotasも併用しておくことをおすすめします)