tech.guitarrapc.cóm

Technical updates

東プレ REALFORCE R3HC12 にメインキーボードを変更した

Realforce R3 が発売されました。

これまで Realfoce が抱えていた不満がほぼすべて解消されたモデルに見えるので、メインキーボードに据えてみました。

前回の R2TLS-JP4 から約4年での新モデル、実際どうなのか見てみます。

tech.guitarrapc.com

tl;dr;

R2 を有線で使って満足しているなら、R3 を買う動機は薄いと思います。 ただ、Realforce を 無線で使いたいならオススメです。 Realforce ConnectによるAPCやキーマップ設定も使ってみるとよいものです。

よく比較に挙げられていたNIZ と比較して足りないものはほぼなくなったので、正しく進化した感触です。 価格が高いのがネックですが、キーボードは職業柄一番使う道具なので更新していきたいところです。

余談ですが、キースペーサー2mm を入れると、キーボード入力が気持ち浅くなる以上に、入力音が低減されてよかったです。

簡易まとめ

  • R3 はベゼルは太い
  • スコスコは強くなった。(違和感ある人もいそう)
  • 静音はR2 より気持ち劣ってるかもしれない
  • Bluetooth で使って、キータップで自動復旧させるなら モード4 一択
  • Bluetooth なのに 1.3 kg あるのは、Realforce はそういうものといえばそうだけどちょっとちぐはぐになっていくかもしれませんね
  • キースペーサー2mm と APC 1.5mm で、メンブレンタイプも試せるように矯正したりもできる

外見と特徴

ホームページから見てみましょう。

www.realforce.co.jp

特徴的なのが、上部のボタンとインジケーターランプです。

見た目は R2 から初代に戻っており、サイズとベゼルが残念です。

R2 に比べてベゼルが太く、角がの丸っこいため初代に近く感じます。

サイズを見てみましょう。

モデル サイズ
R2 142mm x 369mm x 30mm
R3 163mm × 379mm × 30mm

キーピッチ、キー入力の配置感覚はは変わらないので、単純にベゼルが増えた分だけ上下左右に長くなっています。

  • 横方向は、キーピッチの配置で合わせると左右に微妙に伸びただけで案外違いは分かりません
  • 上方向は、1cmあまりの差がはっきりわかります。ボタンとインジケータで増えたにしては大きかった

上 R2、下R3 で横合わせ

上 R3、下R2でキーピッチ合わせ

スペースはR2より少し短くなり、初代ぐらいになっています。

そのほか

R3 は R2 と違い、モデルによらずキー印刷はレーザー印刷です。

今回購入したのは、Bluetooth 5.0 & USB 有線のハイブリッド接続なので、USB C - USB A ケーブルがつけ外し可能になっています。(Realforce 側が Type-C)

Bluetooth は、バスパワーか単三電池x2 で動作します。

キープラーや替えのキートップは同梱されませんので注意です。 キートップは別売りでさまざまな色が売られるようなので、面白そうですね。黒 + 黄 などもよさそうです。

https://www.realforce.co.jp/products/R3_key-caps-set/www.realforce.co.jp

操作

電源ボタンが追加されました。1秒長押しするとつながります。

Fn キーと一緒に、キートップ側面に書かれたキーを押すと各種操作ができます。

よく使うものをあげてみると

  • Fn + P で、Bluetooth のペアリングができます
  • Fn + 1~4 で Bluetooth 接続先を4つキーボードが記録でき、 Fn + 5 でUSB 接続に切り替えることができます
  • Fn +F9 でバッテリー状態を確認できます
  • Fn +F11 で、Bluetooth のエコモードを切り替えられます

取説にも説明がありますが、側面を見るとすぐにわかるのは便利ですね。

Bluetooth 接続時の復旧

Bluetooth キーボードやマウスは、電池節約のために自動的に切れるのが一般的です。 R3 も例外にもれず、Bluetooth 接続時はエコモードが働きます。

エコモードは全部で4モードあり、デフォルトはモード 1です。

取説のエコモード

取説の時間放置後の復旧を試したのですが、モードごとの違いは次の通りです。

  1. 10分でキーボードがスリープ。キータップでは復帰せず、電源ボタン1秒長押しでキーボードの電源onが必要
  2. 10分でキーボードがスリープ。キータップでは復帰せず、電源ボタン1秒長押しでキーボードの電源onが必要
  3. 30分でキーボードがスリープ。キータップでは復帰せず、電源ボタン1秒長押しでキーボードの電源onが必要
  4. 30分でキーボードが切断。キータップで自動的に再接続して、2キー入力から使える

私は時間が経ってキーボードとPCがつながらくなっても、何かしらのキーをタップしたら復旧してほしいと考えています。 この要件にあるのは「エコモード4」だけでした。 1~3 の電源長押しが必須なのはちょっと受け入れがたいです。

気になるのが、4の切断でスリープとちがうということはスリープしないんですかね。 とりあえず単三電池で使っていますが、どうなるのか今後が気になります。(3か月も持てば十分ですが)

キータッチの違い

R2 と比べて、R3 は、スコスコ感が増したようです。 良くも悪くもスコスコ、好みはあるかもしれませんがすぐに慣れて R2 を忘れたので私にはその程度でした。

ただ、R2と同じ静音ですが、少しキーボードがうるさい気がします。

キースペーサーを2mm を試してみるので、静音やタッチ感覚がどうなるか楽しみです。

www.realforce.co.jp

Realforce Connect

Realforce のだめといわれた最大のゆえんは、お高いわりに調整がしょぼいことです。

R3 ではRealforce Connect をインストールして、USB でつなぐとAPCやキーマップの入れ替えが可能におなっています。

例えば、APCモデルならデフォルト2.2mm から「キーボード全部」や「キー個別」に浅くしたり深くしたりが可能なのはうれしいところです。

キーマップの入れ替えも、Windows レジストリや機能を使うことなくキーボードで完結できます。今回は、Caps lock を Ctrl にしました。

変更後のキーマップ。Caps Lock を L-Ctrl に切り替えている

面白いところでは、今のキーストロークの深さがわかる機能もあって、普段自分がどれぐらいの深さで入力しているのかがわかります。

Realforce Connectでキーストロークの深さが可視化される

惜しむらくは、USB接続していないと接続を検知してくれないことでしょう。 普段 Bluetooth 接続なので、気になったときにUSBにつなぐのは面倒ですね。

Windows の Japanese IME 設定

スペースの左右にある無変換、変換をそれぞれ IME-off / IME-on に割り当てています。これは、macOS は英字、日本語になっているので合わせているのですが、日本語キーボードで頻繁に日本語、英字の切り替えをするので便利です。

日本語 IME > キー & タッチ

キースペーサー2mm を入れてみる。

2021/11/9 2mm のキースペーサーをつけてみました。

キースペーサーをつける前

キースペーサーをつけた後

Realforce Connect で見ると、キーストロークはFull に近いようですが、APC 1.5mm にしてより軽くタイプできるようにもしてみました。

期待した効果ですが、装着前と比べて次の違いがあります。

  • キーストロークの深さが、気にするとわかる程度に浅くなった
  • キーボードのカタカタ音から高音が減ったことで静かになったように感じる

耳の位置あたりで録音したものを聞くと、普段の Realfoce R3 は結構うるさく感じますね。静音とはいえ、録音するとそういうものなのかもしれません。

Cascadia Mono の検討

プログラミング用のフォントは、前回は DevaVu Sans Mono Bront が今一番好みとしました。

しばらく、パッと思うのがなかったのですが、Windows Terminal に入った Cascadia Mono (合字ありは Cascadia Code) がいいという噂を聞いて、実際採用するか検討してみます。

tech.guitarrapc.com

tl;dr;

  • Cascadia Mono のほうが Consolas よりいい感じのバランスだった
  • 少しBold で Consolas 気味にしたいなら、Cascadia Mono、合字が欲しいなら Cascadia Code がよさそう
  • 今のところ普段使いは DejaVuSansMono-Bront のままだけど、Cascadia Mono はWindows 11 標準で提供される + Bold 気味にしたいときによさそうなので切り替える対象として有用

結果

今回も、個人の感覚でスコアを点けてみました。 Cascadia Mono、DejaVuSansMono-Bront と並んで気に入っているようです。

Score

基準は

Target Border(:eyes:) Bad(-1) Good (+1)
oO08 distinct each 0 has dot inside 0 has slash
iIlL1 distinct each l and 1 are almost same l and 1 are completely different
g9qCGQ distinct each g is Slab serif g is not Slab serif, Q is serif font
~-+=> no ligature not center or any unbalance n/a
Left and right side padding too narrow TODO: measure
Top and bottom side padding too wide TODO: measure
Size too small 2/3 or 3/4 height of small letters
Balance Letter Paddings and Boldness

Fonts-lab/SCORE.md at master · guitarrapc/Fonts-lab · GitHub

Requirements

  • モノスペースフォント(等幅フォント)必須。プロポーショナルフォントは絶対だめ
  • 文字幅が少しあるほうがいい
  • 行が少し詰まっているほうが全体を見れてうれしい
  • 0 は スラッシュいれてほしい
  • 小文字L と 1 の区別は大事
  • 小文字 g がグねってしていると q と区別つきやすくて最高
  • Ligature はいらない
  • もともとプログラム内で日本語はかかないので入っていなくてもok
  • 横は狭いより広くてok
  • 縦が広いのはダメ
  • フォントは大き目がよい

Compare

Cascadia Code (Mono) を Consolas と DevaVu Sans Mono Bront と比べてみます。

https://app.programmingfonts.org

Bront Dejavu Sans Mono

Cascadia Code

Cascadia Code と Consolas

Cascadia Code と DejaVu Sans Mono - Bront

Selection

DejaVu Sans Mono - Bront と Cascadia Mono の選択

フォント自体がべつもの。Cascadia Mono は セリフが少し強め。

Cascadia Mono は、Bold 気味で文字が詰まって見えるのと、小文字の縦のサイズが 1/2 で 2/3 や 3/4 ぐらいが好きなのでそこだけ惜しい感じ。

Dejavu Sans Mono は 少しBold 気味で読みたい時に代替がなかったので、Cascadia Mono はそこを埋めてくれそうです。

Consolas と Cascadia Mono の選択

フォント自体は似ている。

文字1つ一つが Cascacia Mono はより大きく、Bold も強めなので視認性が良い印象です。

g が、Cascacia Monoでは 丸くなっていないのが残念。

文字の詰まり具合が、Cascacia MonoのほうがConsolas より改善していて好ましい感じです。

GitHub Actions で configure-aws-credentials を使った OIDCではまったこと

GitHub Actions の OpenID Connector と AWS の OIDC Provider を使うことで、IAM Role を Assume できるというのは前回書きました。

tech.guitarrapc.com

構築中によく出るエラーに関しても書いたのですが、いざ実際に使おうとしたら別のエラーではまったので忘れないようにメモしておきます。

tl;dr;

  • OpenID Connect で認証すると、AWS OIDC Provider の認証の上限に引っ掛かりやすい
  • Composite Action の中で、 configure-aws-credentials を呼び出すときは注意
  • 2021/12/10 追記: このPR が入れば自動的にリトライしてくれるで記事のプラクティスは不要になる予定

GitHub Actions で並列実行すると時々失敗する。

2022/2/4 本バグは https://github.com/aws-actions/configure-aws-credentials/issues/299 で修正されています。もう気にしなくともリトライもされます。

次のエラーがでることがあります。

エラーメッセージ Error: Couldn't retrieve verification key from your identity provider, please reference AssumeRoleWithWebIdentity documentation for requirements

対策: configure-aws-credentials で OIDC 認証を頻繁に呼び出す場合は、キャッシュかリトライしましょう。

並列でジョブを実行するなど、短時間に頻繁に認証を取得ようとすると、時々認証に失敗します。 IAM Userを使っていると当然でないのですが、OIDC Providerで認証をかけようとするとぐさっと刺さります。

これを回避するには、リトライかキャッシュ作戦をとる必要があります。

github.com

workflow で1回だけ認証ととって、キャッシュを使いまわす場合次のような workflow になります。

gist.github.com

ただ、GitHub Actions の cache は 「パブリックリポジトリのキャッシュには、センシティブな情報を保存しないことをおすすめします。」とある通り取扱いには注意だと思います。トークン自体 は 900sec (min) か 1 hour (default) で切れますが、時間の問題ではないという。

Warning: We recommend that you don't store any sensitive information in the cache of public repositories. For example, sensitive information can include access tokens or login credentials stored in a file in the cache path. Also, command line interface (CLI) programs like docker login can save access credentials in a configuration file. Anyone with read access can create a pull request on a repository and access the contents of the cache. Forks of a repository can also create pull requests on the base branch and access caches on the base branch. https://docs.github.com/en/actions/advanced-guides/caching-dependencies-to-speed-up-workflows

configure-aws-credentials を1 jobで複数回呼び出したときに初回の認証を上書きできない

対策: configure-aws-credentials の呼び出しは一回の composite action で行うか、workflow で呼び出しましょう。

通常 configure-aws-credentials は、呼び出しのたびに job 内の認証を後勝ちで上書きします。 ただし、composite action の中で、configure-aws-credentials を呼び出すと、意図しない結果になるパターンがあります。

configure-aws-credentials を呼び出す処理を composite action に書いて、1 job内で 別の IAM Role の Assume を呼びだすと 2 回目の configure-aws-credentials で上書きできないので避けましょう。

github.com

正常動作例1

次のように workflow 上で連続でconfigure-aws-credentialsを呼び出すと、2回目の configure-aws-credentials で myrole_Bに上書きできていることが確認できます。

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
     # 1st
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@master
        with:
          aws-region: ap-northeast-1
          role-to-assume: arn:aws:iam::123456789012:role/myrole_A
          role-session-name: GitHubActions-${{ github.run_id }}
      - name: get-caller-identity shows myrole_A as expected
        run: aws sts get-caller-identity
      # 2nd
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@master
        with:
          aws-region: ap-northeast-1
          role-to-assume: arn:aws:iam::123456789012:role/myrole_B
          role-session-name: GitHubActions-${{ github.run_id }}
      - name: get-caller-identity shows myrole_B as expected
        run: aws sts get-caller-identity

1回目のget-caller-identity は myrole_A です。

{
    "UserId": "AROASJXUOK5UM7XZKRYTB:GitHubActions-1426675663",
    "Account": "***",
    "Arn": "arn:aws:sts::***:assumed-role/myrole_A/GitHubActions-1426675663"
}

2回目のget-caller-identity は myrole_B です。

{
    "UserId": "AROASJXUOK5UM7XZKRYTB:GitHubActions-1426675663",
    "Account": "***",
    "Arn": "arn:aws:sts::***:assumed-role/myrole_B/GitHubActions-1426675663"
}

意図通りの挙動です。

正常動作例2

Composite Action の中で configure-aws-credentials をまとめて2回呼び出すと、2回目の呼び出しで myrole_B に上書きできていることが確認できます。

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Configure AWS Credentials
        uses: ./.github/actions/aws_oidc_auth_all

aws_oidc_auth_all はこうなっています。

# ./.github/actions/aws_oidc_auth_all/action.yaml
name: aws oidc auth
description: |
  Get aws oidc auth.
runs:
  using: "composite"
  steps:
    # 1st
    - name: Configure AWS Credentials (Role A)
      uses: aws-actions/configure-aws-credentials@master
      with:
        aws-region: ap-northeast-1
        role-to-assume: arn:aws:iam::123456789012:role/myrole_A
        role-session-name: GitHubActions-${{ github.run_id }}
    - name: get-caller-identity shows myrole_A as expected
      run: aws sts get-caller-identity
      shell: bash
    # 2nd
    - name: Configure AWS Credentials (Role B)
      uses: aws-actions/configure-aws-credentials@master
      with:
        aws-region: ap-northeast-1
        role-to-assume: arn:aws:iam::123456789012:role/myrole_B
        role-session-name: GitHubActions-${{ github.run_id }}
    - name: get-caller-identity shows myrole_B as expected
      run: aws sts get-caller-identity
      shell: bash

1回目のget-caller-identity は myrole_A です。

{
    "UserId": "AROASJXUOK5UM7XZKRYTB:GitHubActions-1426687022",
    "Account": "***",
    "Arn": "arn:aws:sts::***:assumed-role/myrole_A/GitHubActions-1426687022"
}

2回目のget-caller-identity は myrole_B です。

{
    "UserId": "AROASJXUOK5UHN4XWD3XF:GitHubActions-1426687022",
    "Account": "***",
    "Arn": "arn:aws:sts::***:assumed-role/myrole_B/GitHubActions-1426687022"
}

意図通りの挙動です。

問題の動作

Composite Action の中で configure-aws-credentials を それぞれのIAM Role について呼び出すと、2回目の呼び出しが myrole_A のままで myrole_B で上書きできていないことが確認できます。

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      # 1st <- Shows myrole_A, expected.
      - name: Configure AWS Credentials (Role A)
        uses: ./.github/actions/aws_oidc_auth_single
        with:
[https://docs.github.com/en/actions/creating-actions/creating-a-composite-action:embed:cite]


          role-to-assume: arn:aws:iam::123456789012:role/myrole_A
      # 2nd <- Shows myrole_A, unexpected!!
      - name: Configure AWS Credentials (Role B)
        uses: ./.github/actions/aws_oidc_auth_single
        with:
          role-to-assume: arn:aws:iam::123456789012:role/myrole_B

aws_oidc_auth_single はこうなっています。

# ./.github/actions/aws_oidc_auth_single/action.yaml
name: aws oidc auth
description: |
  Get aws oidc auth.
inputs:
  role-to-assume:
    description: "AWS IAM Role to assume 1"
    required: true
runs:
  using: "composite" # this is key point
  steps:
    - name: Configure AWS Credentials
      uses: aws-actions/configure-aws-credentials@master
      with:
        aws-region: ap-northeast-1
        role-to-assume: ${{ inputs.role-to-assume }}
        role-session-name: GitHubActions-${{ github.run_id }}
    - name:  get-caller-identity shows myrole_A on both 1st and 2nd run. (2nd run must be myrole_B but incorrect result.)
      run: aws sts get-caller-identity
      shell: bash

1回目のget-caller-identity は myrole_A です。

{
    "UserId": "AROASJXUOK5UM7XZKRYTB:GitHubActions-1426687028",
    "Account": "***",
    "Arn": "arn:aws:sts::***:assumed-role/myrole_A/GitHubActions-1426687028"
}

2回目のget-caller-identity も myrole_A です。myrole_B に上書きできていません。

{
    "UserId": "AROASJXUOK5UHN4XWD3XF:GitHubActions-1426687028",
    "Account": "***",
    "Arn": "arn:aws:sts::***:assumed-role/myrole_A/GitHubActions-1426687028"
}

aws-actions/configure-aws-credentials の中身を見ても、composite action 特有の処理は当然存在しません。 composite action の仕様かと思いつつ、そういった記述もないので謎です。

仕方ないので、正常動作例1,2 のいずれかを用いることになるでしょう。

あるいは、両方の権限をもつ単一Roleでやるのも手でしょう。

GitHub Actions が OpenId Connect に対応したので AWS OIDC Provider と連携する

前々から言われていた GitHub Actions で OpenID Connect 経由で、各種Cloud Provider の認証を得るのが GA しました。 めでたい。

github.blog

これにより、aws-actions/configure-aws-credentials のみで認証が組めるようになったので見てみましょう。

https://github.com/marketplace/actions/configure-aws-credentials-action-for-github-actionsgithub.com

tl;dr;

  • GitHub Actions でAWS操作をするために、IAM User が不要になるので神
  • セルフホストな GitHub Actions を EC2 で動かしているなら、素直に Instance Role を使うので十分というのもある。(何か事情があれば OpenId Connector でもいい)
  • AWS アカウントで OpenId Connect Provider は 一意です。1 AWSアカウントで複数環境を持っている & 環境ごとに IAM Role を持っている場合は、環境ごとに OpenId Conect Provider を作ろうとして失敗しないように
  • 並列度高く認証を取得しようとすると失敗することが多いので注意

動作例

設定がただしければ、必要な IAM Role Arn を role-to-assume に指定するだけで、その Role 権限で 操作ができるようになります。

これで

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@master
        with:
          aws-region: ap-northeast-1
          role-to-assume: "作ったIAM Role の Arn を入れる"
          role-session-name: "適当な名前"

こうなる。

GitHub OpenId Conector と AWS OIDC Provider でAWS の操作ができる

基本

GitHubから公式にドキュメントが公開されたのでこれに従いましょう。先日までuses: aws-actions/configure-aws-credentials@v1 になってたせいでドキュメントが嘘つきでしたが @master に修正されています。

docs.github.com

なお、https://github.com/aws-actions/configure-aws-credentials は、uses: aws-actions/configure-aws-credentials@v1 になっているので動きません。uses: aws-actions/configure-aws-credentials@master に読み替えましょう。

Terraform で AWSを用意する。

用意する必要があるのは、OIDC Provider と IAM Role です。

  • OIDC Provider は、GitHub OIDC と信頼関係を結ぶのに必要です
  • IAM Role は OIDC Provider 経由で GitHub OIDC でリクエストされたときに、リクエスト元のリポジトリオーナー/リポジトリ名:ブランチ名 を検証し条件にマッチしたらそのRoleを Assume して利用できるようにします。つまり、このRoleに、リポジトリの制約と必要な IAM Policyを振ればok

全体を示します。

gist.github.com

OIDC Provider を用意する

値は固定なので単純です。terraform ならこうなります。

// oidc provider
resource "aws_iam_openid_connect_provider" "main" {
  url             = "https://token.actions.githubusercontent.com"
  client_id_list  = ["sts.amazonaws.com"]
  thumbprint_list = ["a031c46782e6e6c662c2c87c76da9aa62ccabd8e", "6938fd4d98bab03faadb97b34396831e3780aea1"] // 2022/1/11 に 中間証明書更新された
}

thumbprint に関しては 中間証明書の寿命が1年なので、毎年1/11 に代わっていくはずです。 thumbprint はコマンドでとれるので、更新直後などドキュメントが間に合ってないときは適当に対応しましょう。

Get Thumbprint of GitHub OIDC, updated on 2022/01/13. · GitHub

client_id_list がGA前と後で変わっています。古いバージョンではここで、リクエスト元のリポジトリURL を指定していましたが、今は sts.amazonaws.com といつものになりました。標準に沿ってくれてよかった。

GitHub の Endpoint が確認できますね。

https://token.actions.githubusercontent.com/.well-known/openid-configuration

{"issuer":"https://token.actions.githubusercontent.com","jwks_uri":"https://token.actions.githubusercontent.com/.well-known/jwks","subject_types_supported":["public","pairwise"],"response_types_supported":["id_token"],"claims_supported":["sub","aud","exp","iat","iss","jti","nbf","ref","repository","repository_owner","run_id","run_number","run_attempt","actor","workflow","head_ref","base_ref","event_name","ref_type","environment","job_workflow_ref"],"id_token_signing_alg_values_supported":["RS256"],"scopes_supported":["openid"]}

IAM Role を用意する

順番に解説します。

重要なのは、Assume Role です。 Assume Role で OIDC Provider からのリクエストを検証しています。

  • principal は、認証を委譲されて受けるので type: "Federated" + 先ほど作った OIDC Provider の arn を指定 します
  • condition で、リクエスト元が repo:<GitHubOwner>/<Repositry>:Branch の条件とマッチするか検証します

OIDC 経由で、許可した「リポジトリ、かつブランチ」だった場合に IAM Role をsts:AssumeRoleWithWebIdentity としてAssume できるようにします。

さて、複数のリポジトリで同じロールを使いたいケースはどうすればいいでしょうか?

IAM Policy の condition は、ワイルドカード一致するかを StringLike で検証できますが、これは value が1要素 (=単一リポジトリ) のときにしか機能しません。 value が複数要素(=複数リポジトリ)でもワイルドカードで一致するかを見る場合は、ForAnyValue: + StringLike を用います。

今回は 分岐させましたが、別に ForAnyValue で初めから書いてもいいでしょう。

data "aws_iam_policy_document" "github_oid_assume_role_policy" {
  statement {
    effect  = "Allow"
    actions = ["sts:AssumeRoleWithWebIdentity"]
    principals {
      type        = "Federated"
      identifiers = [aws_iam_openid_connect_provider.main.arn]
    }
    # aud があるとはじかれてるので、aud の値がおかしいっぽい。 aws-actions/configure-aws-credentials の仕組みからすると、sts.amazonaws.com が来るはず。 <- github.com/aws-actions/configure-aws-credentials ではなしになってる :(
    # condition {
    #   test     = "StringEquals"
    #   variable = "token.actions.githubusercontent.com:aud"
    #   values   = ["https://github.com/${var.github_owner}"]
    # }
    condition {
      test     = length(var.github_oidc_repo_names) == 1 ? "StringLike" : "ForAnyValue:StringLike"
      variable = "token.actions.githubusercontent.com:sub"
      values   = [for item in var.github_oidc_repo_names : "repo:${var.github_owner}/${item}:*"]
    }
  }
}

AssumeRole ができてしまえば IAM Roleを作るだけです。今回は、aws sts get-caller-identity を実行できるようにしてみましょう。

特にいうことはないですね。終わり。

data "aws_iam_policy_document" "github_actions" {
  // allow running `aws sts get-caller-identity`
  statement {
    effect    = "Allow"
    actions   = ["sts:GetCallerIdentity"]
    resources = ["*"]
  }
}

resource "aws_iam_policy" "github_actions" {
  name        = "githubactions_policy"
  path        = "/"
  description = "Policy for GitHubActions"
  policy      = data.aws_iam_policy_document.github_actions.json
}
resource "aws_iam_role" "test_role" {
  name               = "githubactions-oidc-role"
  path               = "/"
  assume_role_policy = data.aws_iam_policy_document.github_oid_assume_role_policy.json
  policy_arns = [
    aws_iam_policy.github_actions.arn
  ]
}

リソースを作成

さて、これで AWS にリソースを作るとこんな感じになります。

今回は私は、guitarrapc/githubactions-lab と guitarrapc/infrastructure の 2リポジトリから GitHub Actions 経由で認証を受けられるようにしました。 IAM Role の Trust relationships > Conditions で2リポジトリが ForAnyValue:StringLike で指定されているのがわかりますね。

IAM > Identity providers > token.actions.githubusercontent.com

IAM > Roles > githubactions-oidc-role

ここまでのどれかにミスがあると Assume Role されません。 うまくいかない場合は何度も見直すことになるでしょう。

GitHub Actions の構成

Workflow を用意します。 キーポイントは3つです。

  • permissions で、id-token: write で書き込み権限が必要です。 permissions: write-all でもいいのですが、現状では permissions を指定しないとうごかないので注意です
  • role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}secrets.AWS_ROLE_TO_ASSUME は、GitHub Secret に AWS_ROLE_TO_ASSUME という名前で先ほど作った IAM Role の Arn を仕込んであります。Arnのフォーマットは、今回の例なら arn:aws:iam::xxxxxxxxxxxxx:role/githubactions-oidc-role というフォーマットになります
  • role-session-name で、CloudTrail イベントにユーザー名が出るのでいい感じの名前にしましょう
  • uses: aws-actions/configure-aws-credentials@master を指定します。 uses: aws-actions/configure-aws-credentials@v1 でないので注意してください

github.com

name: aws oidc credential

on:
  workflow_dispatch:
  push:
    branches: ["main"]

# allow use id-token
permissions:
  id-token: write # required!
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Configure AWS Credentials
        # must use "master", not "v1". v1 is not yet released to use latest role-to-assume.
        # Error: Credentials could not be loaded, please check your action inputs: Could not load credentials from any providers
        uses: aws-actions/configure-aws-credentials@master
        with:
          aws-region: ap-northeast-1
          role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
          role-session-name: GitHubActions-${{ github.run_id }}
          role-duration-seconds: 900 # minimum: 900sec, maximum: iam role session duration
      - name: get-caller-identity is allowed to run on role.
        run: aws sts get-caller-identity

実行してみると、冒頭のスクショのように成功するはずです。

$ aws sts get-caller-identity
{
    "UserId": "AROASJXUOK5UM7XZKRYTB:GitHubActions-1420393244",
    "Account": "***",
    "Arn": "arn:aws:sts::***:assumed-role/githubactions-oidc-role/GitHubActions-1420393244"
}

うまくできましたか? おめでとうございます!

ダメでした? 私も失敗を繰り返したので、経験したエラーと対処をFAQに載せておきます。

FAQ

GitHub Actionsで実行してみたら動作しない。

エラーメッセージ Credentials could not be loaded, please check your action inputs: Could not load credentials from any providers

この場合、AWS OIDC Provider の設定がおかしい or GitHub Actions の permissions が抜けています。

  • (AWSの設定ミス) OIDC Provider の client_id_list に "sts.amazonaws.com" ではなく、リポジトリのURL を指定している。(古いブログが記事がそうなっている)
  • (GitHub Actions Workflowの設定ミス) Workflow で、permissions がない。デフォルトの GitHub Actionsは write-all のはずですが、まだ id-tokens は含まれていないようです。明示的に permissions: write-all を指定するか、id-token: write を指定しましょう

GitHub Actionsで実行してみたら動作しない。

エラーメッセージ Not authorized to perform sts:AssumeRoleWithWebIdentity

このケースは、OIDC Provider は問題なく、AssumeRole の設定にミスがあります。

  • (AWSの設定ミス) AssumeRole の Action が "Action": "sts:AssumeRoleWithWebIdentity" になっていない
  • (AWSの設定ミス) 複数リポジトリなのに ForAnyValue:StringLike ではなく StringLike で判定している
  • (AWSの設定ミス) AWS の IAM Role の Assume Policy が設定しようとしている GitHub Owner/Repository:ブランチ と内容と一致していない

過去にある類似記事との差分

GA前の内容で、結構ずれています。GA前の記事の内容でやると失敗するので注意です。(aws-actions/configure-aws-credentials が v1 で OIDC 変更を反映すればいける)

dev.classmethod.jp

zenn.dev

github.com

Git GUIクライアントと Fork

Git の GUI クライアント、いろんなツールがあってそれぞれ使いやすさがあります。

普段私は、GitKraken をメインにしていますが、サイズの大きなリポジトリでは Fork を利用しています。 しばらくForkをメイン気味に使っていた中で、私がForkに感じた良さと苦手なことをメモしておこうと思います。

tl;dr;

Git GUI クライアント、まだまだ全然決定版がないですね。

  • GitHub.com や GHE、GitLab など複数のVCSを同時に扱うなら、GitKraken 一択です
  • 現在のブランチにいつつ、別のブランチの操作、ツリーのハンドリングなどgitの使い勝手は GitKraken が最高です
  • SourceTree使ってたなら Fork がいいでしょう。すべての動作が高速な上位互換です
  • あるいは10GB 超えるようなリポジトリも Fork は高速で使いやすいと思います
  • GitKraken で git操作が遅いと感じるなら Fork はgit操作が高速でUIもロックされず快適です。一方で、Fork のgit操作、UIコンセプトはGitKrakenより手間がかかるのでストレスです。1
クライアント 価格 認証 複数VCS対応 備考
Fork $49.99 (買い切り) OAuth × 試用は無料
GitKraken $4.95 user/month (サブスク) OAuth OSS利用は無料
SourceTree 無料 PAT/SSH ×

自分のgit利用ケース

私がgitで利用するのは、主にコードのコミット (Unity や C#、Go、React 他)、並びに Git LFS です。

コミット頻度は高く、ブランチを切ったり、マージ操作、ファイルごとの差分確認、stageのフラット/ツリーでの確認、コンフリクト解消を重視しています。

git GUI クライアントについて

Forkだけ評価しても一方的なので、自分が使っている GitKraken も評価します。

Fork

git-fork.com

Fork は、買い切り $49.99 (One-time purchase) の Gitクライアントです。2

OAuth 認証が必要なので、Organizationで使うには Fork をOAuth 許可する必要があります。

Git操作が高速なのが特徴で、例えば10GB越えのリポジトリでUnity で3DモデルやLFSを使っていても、checkout、diff、stage、commit、push、pullのいずれも重いと感じることなく操作ができます。

GitKraken

www.gitkraken.com

GitKraken は、サブスクリプション購入 $4.95 per user/month (paid annually) のGitクライアントです。3

OAuth 認証が必要なので、Organizationで使うには GitKraken をOAuth 許可する必要があります。

個人的に最も好きな GUI Git クライアントです。

ツリーの見やすさ、マージコンフリクトの解消のしやすさ、いちいちブランチを切り替えずGit操作ができる快適さは他の追随を許しません。また、複数のVCSと接続できてプロファイル概念があるので、1つですべてができる万能さが特徴です。

Git操作が重くなりがちで、1つの操作中はほかの操作がロックされる欠点があります。4 いろいろ GUI Git を使ってきていますが、最も操作しやすく、UIとツリーが洗練されていると感じます。

Fork と SourceTreeの比較

Fork の操作やUIはSourceTree と非常に似通っているので、SourceTreeを使っていたら違和感なく移行できるでしょう。 また、SourceTreeのストレスが解消されているので気持ちいいぐらい使いやすいと思います。

有料なだけの価値があります。

Fork の良い点

  • どの操作でも固まらない
  • ファイルdiff 違和感はなく高速
  • 操作UI も違和感ほぼなし
  • push/pull が爆速
  • checkout が爆速
  • tree が SourceTree より見やすい

Fork の懸念点

  • 有料
  • OAuth 認証が必要

特筆点

特筆することはないです。 SourceTree 使っているなら使いやすくて軽い、でも有料かー。という印象に落ち着くと思います。

ForkとGitKrakenの比較

Fork のgit処理は、GitKraken に比べて非常に高速なので、GitKraken で重いと感じているならFork は快適に感じるでしょう。

一方で、UIが違いすぎるのがネックで、GitKraken の UIに慣れていると Forkは1つ一つの操作で目線を移動する必要があり、操作の一貫性がなくブランチを跨いだ操作ができず使いにくいと感じます。

有料の価値があるかは、GitKrakenが重いと感じるか次第。

Fork の良い点

  • push/pull が爆速
  • checkout が爆速
  • リポジトリごとの操作が非同期でロックされないので快適
  • 素直なgit。hooks など妙な挙動がない
  • カスタムコマンドができる。(私はいらないけど)

Fork の懸念点

  • diff をファイルの下に出すのは、複数ファイルのdiff を順にみていくのがつらくごみといわざるをえない
  • 操作していて、視点があっちこっち見ないといけない
  • 画面内でタブを使っているので、一覧しても見えないものがある
  • branch作成、ammend など些細な操作が厳しい
  • tree が厳しい、見やすくはない
  • repo 初期化はセルフサービス
  • repo 追加もセルフサービス。検索などない
  • Conflict 解消がやりにくすぎる、Forkでやるの無理では..
  • SSH 鍵生成などもセルフサービス
  • PR は Web でどうぞスタイル
  • ライセンス管理は原始的

特筆点

GitKraken とはコンセプトの違いはあると思いますが、油と水ぐらい使い勝手が違います。

Fork は操作の視点移動が多く、コミット操作中にツリーが隠れるなど、Fork は触って使いにくく感じます。

ツリーは好みがあります。 個人的に Fork のツリーはよくある表示ですが、コミットメッセージに食い込んでて、普段見せたいもの(head/changeの有無/コミット一覧)と、必要に応じて見たいもの(ブランチ名、commit user、commit id、commit日付) の区別がついていないと思います。

上 Fork の ツリー、下 GitKraken の ツリー

Fork の欠点と対処

Fork の縦ペインで視点移動は減らせるのか

Forkが GitKraken のように操作ごとの視点の動きを考慮したUIになれば好ましいですが、そんな未来は来ないと思います。 ということで、ペイン配置で何とかできないでしょうか。

Fork を水平、縦でペイン表示変更してみて視点移動を減らせるか試してみたので、Twitter にあげたのをぺたり。 結果は、縦なら少しは良くなるけど、diff がどうしようもなく使いにくい。


  1. GitKraken が Fork の早さをもって、ファイルロックが起こらなければ最強といえるんですがそんなものはない
  2. 試用のみ無料ですが、無料版は現在存在しないと明言されています。その上の発言と一貫性取れてない気がするけど。有料の価値はあるいい製品です。
  3. 無料版もあり、OSSのみ + 接続できるVCS が github.com というだったり制約があります。
  4. リポジトリが小さい限りははほぼ発生することはありません。