Azure Web Appsお勉強メモ(3)Azure Web AppsにてデプロイするDockerイメージをGitHub Actionsで作成してAzure Container Registryにpushする(2)

はじめに

先日からAzure Web AppsにRailsアプリを動かすことをやっています。動かすことは簡単にできたのですが、色々と手作業が多かったのでちょっとでも自動化しようと試してみました。前回は結局Azure Container Registryへのpushについては手作業で実施してしまったのですが、今日はそこも自動化します。

先週の内容は以下を参照してください。

サービスプリンシパルとは?

そもそもサービスプリンシパルがあまりよく分かっていなかったので復習から。以下のQiitaの記事(「Azure AD のサービスプリンシパルを 3 つのユースケースから眺めてみた」)を参考にしました。

qiita.com

完璧に理解したとは言えませんが、少なくとも前回でやろうとしていた以下の記事の内容は理解することができました。

docs.microsoft.com

併せてaz ad sp create-for-rbacのコマンドのマニュアルにも目を通しておきます。

docs.microsoft.com

ものすごく簡単に書くと以下のことをやることが目的。

  • Azure Container Registryにpushできる仮想的なユーザをaz ad sp create-for-rbacで作成する
  • 作成する仮想的なユーザができることはできるだけ絞り込みたいので、scopeにAzure Container Registryのidを指定しておく
  • また、同じ理由でroleもpushしかできないようにしておく

実際にaz ad sp create-for-rbacを実行すると以下の結果が得られました。

Creating 'acrpush' role assignment under scope 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
The output includes credentials that you must protect. Be sure that you do not include these credentials in your code or check the credentials into your source control. For more information, see https://aka.ms/azadsp-cli
'name' property in the output is deprecated and will be removed in the future. Use 'appId' instead.
{
  "appId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx",
  "displayName": "acrsp",
  "name": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx",
  "password": "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
  "tenant": "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
}

得られた結果からappIdpasswordを使うことになります。

GitHub Actionsでの実装

前回では、tagをつけたらDockerイメージをGitHub Actionsで作成することを実装しました。今回は作成したDockerイメージをAzure Container RegistryにGitHub Actionsでpushします。

まずは、ログインです。以下のように実装しました。

# 省略
    steps:
    - uses: actions/checkout@v2
    - uses: azure/docker-login@v1
      with:
        login-server: miyohidecontainer.azurecr.io
        username: ${{ secrets.REGISTRY_USERNAME }}
        password: ${{ secrets.REGISTRY_PASSWORD }}
# 省略

ここでAzure Container Registryにログインするためのユーザー名とパスワードを指定する必要があります。これらの値は先ほど作成したサービスプリンシパルappIdpasswordが該当するのですが、それをそのまま入力すると第三者による悪用が起こるので、それはできません。そこで上記で使っているのがsecrets.REGISTRY_USERNAMEsecrets.REGISTRY_PASSWORDです。これはGitHub Actionsで用意されている「暗号化されたシークレット」という機能です。詳細は、以下を参照してください。

docs.github.com

これを使うと、安全にappIdpasswordGitHub Actionsに渡すことができます。

GitHub Actionsはログも出力されるのですが、以下の画面のように該当部分が***でマスク化されています。

f:id:miyohide:20210704163345j:plain

あとはdocker pushするだけ。以下のように実装しました。

# 省略
    - name: create Docker Image
      run: |
        IMAGE_TAG=$(echo ${{ github.ref }} | sed -e 's/refs\/tags\///')
        docker build -f Dockerfile.prd -t miyohidecontainer.azurecr.io/runlog:$IMAGE_TAG .
        docker push miyohidecontainer.azurecr.io/runlog:$IMAGE_TAG

実行

あとはGitHub Actionsを起動します。適当なタグをつけてgit pushし、しばらく待つとAzure Container Registryにpushされていることが確認できました。

f:id:miyohide:20210704163538j:plain

Azure Container RegistryからAzure Web Appsへのデプロイを試みる

ここまでできたので、あとはAzure Web Appsへのデプロイをやってみようと思います。しかしながらAzure Web Appsの作成でDockerイメージを選択するときに以下の画面のようになり作成できませんでした。

f:id:miyohide:20210704163730j:plain

よくよくエラーメッセージを読むと、adminを有効にしないとダメっぽいです...。ここまでadminを有効化しないで頑張ってきたのに...

GitHub Actionsからのデプロイを試みる

というわけで、当初参考にした下記ドキュメントにある通り、GitHub Actionsで実行してみたいと思います。

docs.microsoft.com

適当にDockerアプリを作成したのち、GitHub Actionsで以下の処理を末尾に追加し、ドキュメントにあるようにAZURE_WEBAPP_PUBLISH_PROFILEも設定しておきます。

    - uses: azure/webapps-deploy@v2
      with:
        app-name: 'miyohiderailsapp'
        publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
        images: miyohidecontainer.azurecr.io/runlog:$IMAGE_TAG

これで適当なタグをつけてgit pushすると、GitHub Actionsはうまく動いてくれたのですが、実際のアプリがうまく動いてくれず...

f:id:miyohide:20210704164525p:plain

デプロイメントセンターにあるログを見てみましたが、どうもDockerイメージをうまくpullできないようです。う〜ん...

f:id:miyohide:20210704164617p:plain

というわけで今日はここで時間切れ。残念...

macOSをクリーンインストールした(2021年6月版)

はじめに

最近、使っているMacBook Proの調子があまり良くなく、挙動がちょっと怪しい。Finderが突如落ちたり、バッテリーは十分あるはずなのに突如落ちたり。「OS Xは安定している」という触れ込みはどこに行ったのか?と思いつつ、よく訓練されているApple信者なのでmacOSクリーンインストールすることにしました。これでダメなら新しく買うかなあ。

手順の確認

Appleが「Mac を売却、譲渡、下取りに出す前にやっておくべきこと」というドキュメントを公開しているので、これに目を通しておきます。

support.apple.com

バックアップは言わずもがなで、Timemachineでバックアップは取れているはずですが、USBメモリとかで二重三重にバックアップを取ることにしました。

バックアップを取る対象は人それぞれかと思いますが、個人的には、

  • 書類フォルダー
  • Chromeの設定&パスワード
    • Googleアカウントで同期されているとはいえ、念の為
  • Day One(無課金)のデータエクスポート

を取りました。

クリーンインストールするには、「Intel 搭載の Mac を消去する方法」というドキュメントがありますので、これにも目を通しておきます(Intel Mac用。Appleシリコンはまた別)。

support.apple.com

実際にやってみる

自分の環境は、Catalina(10.15)だったので、ついでにBigSur(11)にしようとするために、「macOS を再インストールする方法」というドキュメントの下部に以下の記述があります。

起動時に「option + command + R」を使った場合は、たいていは、お使いの Mac と互換性があるうちでいちばん新しい macOS がインストールされます。

support.apple.com

この方法で最初はやってみましたが、1時間ぐらいしたあとにエラーコード「-2001F」が表示されて失敗したっぽいので、「command + R」でCatalina(10.15)をクリーンインストールした後にBigSur(11)をインストールしました。作業自身は、ネットワークのスピードにもよりますが、macOS再インストールは大体1時間ぐらい。BigSurインストールで1時間でした。

Macintosh HD - Dataが二つ?

BigSurインストール後、アプリの新規インストールをしようFinderを開くと、Macintosh HD - Dataというドライブが表示されます。あれ?これって何?と思いつつ、TimeMachineの設定をしようとすると

「バックアップを作成する2つのディスクに同じ名前がついています。"Macintosh HD - Data"というディスクのいずれか1つの名前を変更してください」

と出て、TimeMachineのバップアップに失敗します。これはやってしまったか...。とりあえず時間も遅かったことですし、頭を冷やすために一旦ここで作業を中断しました。

再度、再インストール

TimeMachineの設定ができないのはちょっと困りものなので、再度クリーンインストールをすることにします。

よくよく手順を確認すると、Macを消去するときに「ボリュームグループを消去」ではなく「消去」を押したのが間違った原因っぽい。今回は「ボリュームグループを消去」をちゃんとクリックして、Macintosh HD - Dataを削除します。また、ボリュームの削除ボタン (-) をクリックして、残っていた他のボリュームも削除しました。

BigSurをインストールした後だったので、Command + RでインストールされるmacOSもBigSur。ちょっとだけ手順が省略されました。

環境復旧

綺麗な環境になったので、復旧作業を実施します。「システム環境設定」から以下の設定を実施します。

  • 「キーボード」にて
    • 「キーボード」ページにて
      • 「キーのリポート」を一番「速い」に
      • 「リポート入力認識までの時間」を一番「短い」に
    • 「ユーザ辞書」ページにて
      • 「Touch Barに入力候補を表示」をオフに
        • これをしないと遅い
  • アクセシビリティ」にて
  • 「Dockとメニューバー」にて
    • 「画面上の位置」を「左」に

アプリケーションは今後徐々に整備していきますが、まずは以下のものを。おいおい増えてくるかなとは思います。

トラブル対応などに身軽に動きたいため、基本はあまりカスタマイズせずに使う方向で。

Chromeをインストール後、Googleアカウント同期を有効にすると、ブックマークやらパスワードなどが一瞬で復旧されました。いちいちバックアップ取らなくてもよかったかもしれませんが、バックアップは何重にも取ったほうが良いかなと思ったりもします。

これで安定してくれればいいんだけれども、安定しなきゃしないで新しくmacを買う理由ができるわけでそれはそれで良いかも。

Azure Web Appsお勉強メモ(2)Azure Web AppsにてデプロイするDockerイメージをGitHub Actionsで作成してAzure Container Registryにpushする

はじめに

先週からAzure Web AppsにRailsアプリを動かすことをやっています。動かすことは簡単にできたのですが、色々と手作業が多かったのでちょっとでも自動化しようと試してみました。

先週の内容は以下を参照してください。

Dockerイメージを作成する

手始めにDockerイメージを自動ビルドするようにします。DockerHubにはAutobuildという機能がありましたが、先日の発表で無料ではできなくなりました。

www.docker.com

そこで、GitHub Actionsを使って実装したいと思います。以下のドキュメントが参考になりました。

docs.microsoft.com

上のドキュメントではpushするごとにイメージを作りますが、GitのタグをDockerイメージのタグと紐付けるため、少し修正します。

name: Create Docker Image

on:
  push:
    tags:
      - v*

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - run: |
        IMAGE_TAG=$(echo ${{ github.ref }} | sed -e 's/refs\/tags\///')
        docker build -f Dockerfile.prd -t イメージ名:$IMAGE_TAG .

タグ名を取得するには、${{ github.ref }}を使えば良さそうです。詳しくは以下のドキュメントを参照してください。

docs.github.com

DockerイメージをAzure Container Registryにpushする

Dockerイメージが作れたので、Azure Container Registryにイメージをpushします。Azure Container Registryには複数の認証方式があるようです。

docs.microsoft.com

docker loginコマンドを使う場合、管理者ユーザを使うのがいちばんお手軽っぽいですが、CI/CD上で使うにはあまりよくない気がしたので、サービスプリンシパルを使う方式をとることにします。

サービスプリンシパルを使う場合については、丁寧なドキュメントがあるので、これに沿ったらできそうです。

docs.microsoft.com

なお、上記ドキュメント中にあるSP_PASSWD=$(az ad sp create-for-rbac --name http://$SERVICE_PRINCIPAL_NAME --scopes $ACR_REGISTRY_ID --role acrpull --query password --output tsv)SP_PASSWD=$(az ad sp create-for-rbac --name http://$SERVICE_PRINCIPAL_NAME --scopes $ACR_REGISTRY_ID --role acrpush --query password --output tsv)にしないと、イメージのpushができないので注意です。

ただ、私がやったところ、SP_APP_ID=$(az ad sp show --id http://$SERVICE_PRINCIPAL_NAME --query appId --output tsv)を実行した時にERROR: Service principal 'xxxxxxx' doesn't existと出てしまいました。

f:id:miyohide:20210620185216j:plain

アプリケーションIDを取れば良いので、Azure ADの「アプリの登録」画面から当該のものを選択してアプリケーションIDを取得しました。

f:id:miyohide:20210620185720j:plain

これでdocker loginコマンドのユーザー名とパスワードに相当するものが得られたので、それを使ってログインしてpushすればOKです。テストとして手元でやってみると無事、pushできました。

f:id:miyohide:20210620190047p:plain

Azure Web Appsお勉強メモ(1)Azure Web AppsにてRailsアプリを動かす(2021年6月版)

はじめに

2年ぐらい前にRailsアプリをAzure Web Appsで動かすと言うことをやったのですが、Azure Web Appsについて調べる必要性が出てきたので今の状態で動かしてみます。

miyohide.hatenablog.com

2021年6月時点でのAzure Web AppsにおけるRubyの対応

Azure Web AppsはRubyを動かすことができますが、2021年6月時点でRubyのバージョンは2.6。さすがに新しいバージョンで動かしたいものです。

f:id:miyohide:20210613172714p:plain

そこで、RailsアプリをDockerイメージ化して、それを動かすことにします。

RailsアプリのDockerイメージ化

RailsアプリのDockerイメージ化はいろんな情報が入り乱れていて分かりにくいのですが、以下の記事がとっかかりにはいいと感じました。

sinsoku.hatenablog.com

本番環境を作成するにはもう少しDockerイメージサイズを小さくする必要がありますが、とっかかりとしては十分かと思います。Dockerイメージを作成して、Docker Hubにpushしておけば準備完了です。

DockerイメージをAzure Web Appsで動かす

作成したDockerイメージをAzure Web Appsで動かすには、Azure Web Appsの作成時に対象のDockerイメージを指定すればOKです。

f:id:miyohide:20210613174227p:plain

ただ、作成した時点でDockerイメージをPullをするだけではなく、WebアプリにはじめてアクセスしたときにDockerイメージをpullします。このため、初回起動時には時間がかかります。プランにもよるかと思いますが、BasicのB1インスタンスで実行したところ、3分ぐらいかかりました。

f:id:miyohide:20210613174607p:plain
初回アクセス時

Dockerイメージのpullが終了時点

f:id:miyohide:20210613174649p:plain
Dockerイメージのpullが終了したとき

以上でAzure Web AppsでRailsアプリを動かすことができます。

ログを見る

アプリケーションを動かすときに、大事なことの一つがログです。ログがないとトラブル発生時にどのようなことが起きたのかすら分かりません。ログに関しては、以下のドキュメントがありますが、私は読んでもよく分かりませんでした。

docs.microsoft.com

実際にApp Service ログを有効化してみましたが、FTPでファイルを取らないとダメっぽくてちょっと現実的ではなさそうです。

f:id:miyohide:20210613175554p:plain

さらに調べてみると、プレビュー機能ではありますが診断設定を使うことでLog AnalyticsやAzure Storageにログを送ることができるようです。

azure.github.io

Azure Storageとの連携をやってみると...

f:id:miyohide:20210613175914p:plain

以下のような感じで出力されました。

f:id:miyohide:20210613175940p:plain

それぞれのコンテナを見てみると、深いディレクトリが作成され、PT1H.jsonというファイルが作成されていることが確認できました。

Azure Functionsのお勉強メモ(12)Azure Functionsのモニター機能の小ネタ

最近、Azure Functionsのお勉強をチマチマと始めました。色々と分からないことが多かったのでお勉強メモをまとめて記します。

どこまで続くかわからないお勉強メモ。今日は12回目です。今回はAzure Functionsのモニター機能について小ネタ。過去のものは以下を参照。

あれ?回数がおかしい?

前回のブログ記事を書いていたとき、ふとAzure Functionsにある「モニター」を見ていると、表示されている回数がおかしいことに気がつきました。Queueには300件ほどのメッセージを入れたはずなのにそれよりも少ない数字が出ている(スクリーンショット取り忘れ)...

最初は下のスクリーンショットのように「結果は、最大で5分遅れる可能性があります」ということであまり気にも留めていませんでした。

f:id:miyohide:20210606155454p:plain

しかしながら、だんだんと気になったので簡単なhttpトリガーのアプリを作って試してみました。

検証

アプリはJavaで作り、Consumption PlanでLinux環境で動かしました。アプリのコードは以下のようなものですが、今回はこれは本質ではないです。

package com.github.miyohide;

import com.microsoft.azure.functions.*;
import com.microsoft.azure.functions.annotation.AuthorizationLevel;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.annotation.HttpTrigger;
import org.springframework.cloud.function.adapter.azure.FunctionInvoker;

public class HttpHandler extends FunctionInvoker<String, String> {
    @FunctionName("hello")
    public HttpResponseMessage hello(
            @HttpTrigger(
                    name = "req",
                    methods = {HttpMethod.GET},
                    authLevel = AuthorizationLevel.FUNCTION
            )HttpRequestMessage<String> req,
            ExecutionContext context
    ) {
        String msg = req.getQueryParameters().getOrDefault("msg", "Hello World");
        return req.createResponseBuilder(HttpStatus.OK)
                .body(msg)
                .header("Content-Type", "application/json")
                .build();
    }
}

このアプリをAzure上にデプロイし、abコマンドで1,000回のリクエスト・同時接続数100で実行することを3回行いました。動作確認用に1回リクエストを流したので、3,001回の成功回数が出てくれるはずですが、私の今回の場合は2,045回以上は記録されませんでした。

f:id:miyohide:20210606160042p:plain

上記問題の回避

何か対策はないかなと探してみると、マイクロソフトのドキュメントに以下の記述がありました。

ログ サンプリングが原因で、一部の実行が Application Insights の [モニター] ブレードに表示されない場合があります。 ログ サンプリングを回避するには、excludedTypes: "Request" を samplingSettings 値に追加します。

docs.microsoft.com

なるほど、デフォルトではログサンプリングが行われているようです。ここではドキュメントに記載の通りに設定してみます。host.jsonを以下のように記述してデプロイします。

{
  "version": "2.0",
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[1.*, 2.0.0)"
  },
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "excludedTypes": "Request"
      }
    }
  }
}

再検証

再度Azure上にデプロイし、abコマンドで1,000回のリクエスト・同時接続数100で実行することを3回しました。動作確認用に1回リクエストを飛ばしたので、合計で3,001回のリクエストが出てくれることを期待します。

f:id:miyohide:20210606160626p:plain

期待通り、3,001回という数字が出ていました。

Azure Functionsのお勉強メモ(11)Queue Trigger利用の深掘り(一部未解決)

最近、Azure Functionsのお勉強をチマチマと始めました。色々と分からないことが多かったのでお勉強メモをまとめて記します。

どこまで続くかわからないお勉強メモ。今日は11回目です。今回はQueue Triggerの利用について深掘りしてみます。過去のものは以下を参照。

Queueにメッセージを送る

テスト用にQueueにメッセージを送るプログラムを以下の記事で作成しました。

miyohide.hatenablog.com

記事ではAzuriteで作成したエミュレーター用の記述ですが、以下のように少し書き換えてやればAzure上でのQueueに対してデータを送ることができます。

# 省略
client = Azure::Storage::Queue::QueueService.create(
  storage_account_name: ストレージアカウント名,
  storage_access_key: アクセウスキー,
  storage_queue_host: "https://ストレージアカウント名.queue.core.windows.net/"
)
# 省略

上記記事の初出時は、メッセージ送付を

client.create_message(キュー名, "test message #{index}")

としていましたが、これではAzure FunctionsのQueue Triggerにて以下のエラーが発生しました。

Unable to translate bytes [B5] at index 0 from specified code page to Unicode.

f:id:miyohide:20210530164826p:plain

これを解決するには、メッセージをBase64エンコードしてあげれば良いです。Rubyのコードで書けば以下の通り。

client.create_message(キュー名, Base64.encode64("test message #{index}"))

多くのQueueを送ったときにNullPointer Exceptionが発生する(未解決)

上記のプログラムでQueueに多くの(といっても100件ぐらい)メッセージを送ると以下のメッセージがでて処理が失敗しました。

Result: Failure Exception: NullPointerException: Stack: java.lang.reflect.InvocationTargetException at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.base/java.lang.reflect.Method.invoke(Unknown Source) at com.microsoft.azure.functions.worker.broker.JavaMethodInvokeInfo.invoke(JavaMethodInvokeInfo.java:22) at com.microsoft.azure.functions.worker.broker.EnhancedJavaMethodExecutorImpl.execute(EnhancedJavaMethodExecutorImpl.java:55) at com.microsoft.azure.functions.worker.broker.JavaFunctionBroker.invokeMethod(JavaFunctionBroker.java:57) at com.microsoft.azure.functions.worker.handler.InvocationRequestHandler.execute(InvocationRequestHandler.java:33) at com.microsoft.azure.functions.worker.handler.InvocationRequestHandler.execute(InvocationRequestHandler.java:10) at com.microsoft.azure.functions.worker.handler.MessageHandler.handle(MessageHandler.java:45) at com.microsoft.azure.functions.worker.JavaWorkerClient$StreamingMessagePeer.lambda$onNext$0(JavaWorkerClient.java:92) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) at java.base/java.util.concurrent.FutureTask.run(Unknown Source) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.base/java.lang.Thread.run(Unknown Source) Caused by: java.lang.NullPointerException at org.springframework.cloud.function.adapter.azure.FunctionInvoker.handleRequest(FunctionInvoker.java:117) at com.github.miyohide.QueueHandler.queueHandler(QueueHandler.java:17) ... 16 more

f:id:miyohide:20210530170452p:plain

正直、この原因はわからなかったので、対処療法を行います。

対処療法としては以下二つを試しました。

  1. batchSizeを1にする
  2. batchSizeを2以上にしつつ、visibilityTimeoutを設定する

以下ドキュメントに書かれている通りのことをやっただけです。

docs.microsoft.com

batchSizeを1にすると1つのインスタンスで並行に動くことは無くなります。どうしても並行に動かしたいと言うことであれば、NullPointerExceptionが発生することは受け入れて、リトライで問題なければOKというスタンスでも良いかもしれません。動かすものによるかと思いますが、今回のサンプルではhost.jsonを以下のようにしました。

{
  "version": "2.0",
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[1.*, 2.0.0)"
  },
  "extensions": {
    "queues": {
      "visibilityTimeout": "00:00:05",
      "batchSize": 5
    }
  }
}

すると、1回目では失敗したメッセージが2回目では正常に処理できていることを確認できました。

1回目の処理。NullPointerExceptionが発生しています。 f:id:miyohide:20210530170705p:plain

2回目の処理。特に例外は発生していません。 f:id:miyohide:20210530170718p:plain

RubyからAzure Storage Queueにアクセスする

今週は小ネタ。あまり時間が取れなかった...

RubyからAzure Storage Queueにアクセスする

Azure Storage Queueにたくさんのデータを登録しようと思い、簡単なプログラムを書いて動かそうとしたらちょっとハマったので、備忘録で残しておきます。

公式ドキュメントが古すぎる件

まずは公式ドキュメントを見るようにしているので、公式ドキュメントを探してみると、そのものズバリの記事が以下にあります。が、結論から言うと以下のドキュメントに書かれている方法では動きませんでした。

docs.microsoft.com

Ruby 3.0の環境で動かそうとすると以下のエラーメッセージが出てrequire azureすら動きません。

/Users/hoge/bundle/ruby/3.0.0/gems/azure-0.7.10/lib/azure.rb:21:in `require': cannot load such file -- rexml/document (LoadError)
    from /Users/hoge/bundle/ruby/3.0.0/gems/azure-0.7.10/lib/azure.rb:21:in `<top (required)>'
    from lib/app.rb:2:in `require'
    from lib/app.rb:2:in `<main>'

また、azure gemのソースコードリポジトリであるAzure/azure-sdk-for-rubyのREADMEには2021年5月24日時点で以下の記述がされていました。

As of February 2021, Azure Resource Management SDK for Ruby has entered a retirement phase and is no longer officially supported by Microsoft.

もうメンテナンスされないので、別の方法を見つける必要があります。

Microsoft Azure Storage Client Library for Ruby

何か別の方法はないかなと探していたところ、Microsoft Azure Storage Client Library for Rubyを見つけました。azure gemのバージョン0.7.10からAzure Storage関係は別リポジトリに分かれたようです。

メンテナンスも(2021年5月24日時点で)行われているようなので、安心して使えます。以下ではこれを使います。

Azure Storage Queueにアクセスする

READMEに書いてあることそのままですが、念のため試してみます。試した環境は以下の通りです。

  • Ruby 3.0.0
  • azure-storage-queue gem 2.0.2

Azure Storage Queueにアクセスするにはazure-storage-queueを使います。gem install azure-storage-queueでgemをインストールして、以下のようなプログラムを書きます(追記:初出時、Base64.encode64を使って送信するメッセージをエンコードする処理を記述していませんでした。これによりメッセージを受け取ることはできなくなることがあります)

require 'azure/storage/queue'
require 'base64'

client = Azure::Storage::Queue::QueueService.create(
  use_development_storage: true
)

QUEUE_NAME = "myqueue"

client.create_queue(QUEUE_NAME)

100.times do |index|
  client.create_message(QUEUE_NAME, Base64.encode64("test message #{index}"))
end

REAMEには

Against local Emulator (Windows Only)

と書かれていますが、macでも動きます。Azuriteを起動しておいて、上記プログラムを実行すると、画像のようにQueueにメッセージが溜まっていることが確認できました。

f:id:miyohide:20210524213835p:plain

ソース

ソースは以下。gemをGemfileに入れたり、アプリのソースをlib以下に格納していますが、本質は変わらないかなと。

github.com