Techioz Blog

マネージド ID を使用して、Ruby On Rails のアクティブ ストレージを Azure に接続できますか?

概要

私はこの記事を読みました:- https://hix.dev/tutorials/ruby-on-rails/active-storage#azure-rails-configuration

レール側の設定

azure:
  service: AzureStorage
  storage_account_name: <%= ENV['AZURE_STORAGE_ACCOUNT_NAME'] %>
  storage_access_key: <%= ENV['AZURE_STORAGE_ACCESS_KEY'] %>
  container: <%= ENV['AZURE_STORAGE_CONTAINER'] %>

また、マネージド ID を使用した Azure ストレージの接続については、この記事に従いました。 https://translate.google.com/translate?hl=ja&sl=en&tl=ja&u=https://github.com/azure/azure-storage-ruby/tree/master/blob#access-token

そこで、以下の構成を試してみました

azure:
  service: AzureStorage
  storage_account_name: <%= VaultService.get_secret("AZURE-STORAGE::AZURE-STORAGE-ACCOUNT-NAME") %>
  signer: <%= Storage::Azure::Client.get_token_signer %> 
  container: <%= VaultService.get_secret('AZURE-ATTACHMENTS-BUCKET-NAME') %>

署名者の値を取得するには、上記に添付された github リンクに従いました。

      def self.get_token_signer
        # https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/tutorial-windows-vm-access-storage-sas#get-an-access-token-using-the-vms-identity-and-use-it-to-call-azure-resource-manager
        # https://github.com/azure/azure-storage-ruby/tree/master/blob#access-token
        access_token = AzureAd::ManagedIdentityTokenProvider.new('https://storage.azure.com/', client_id: ENV['AKS_MANAGED_IDENTITY_ID']).get_authentication_header.split(' ').last
        # Creating an instance of `Azure::Storage::Common::Core::TokenCredential`
        token_credential = ::Azure::Storage::Common::Core::TokenCredential.new access_token
        token_signer = ::Azure::Storage::Common::Core::Auth::TokenSigner.new token_credential
        token_signer
      end

AzureAd::ManagedIdentityTokenProvider については、このコード部分から参照しました。 https://translate.google.com/translate?hl=ja&sl=en&tl=ja&u=https://github.com/Azure/azure-sdk-for-ruby/blob/master/runtime/ms_rest_azure/lib/ms_rest_azure/credentials/msi_token_provider.rb

次のエラーが発生します

##[error]#38 6.433 Errno::ECONNREFUSED: Connection refused - connect(2) for "169.254.169.254" port 80
##[error]#38 6.433 /usr/lib/ruby/3.2.0/net/http.rb:1271:in `initialize'
##[error]#38 6.433 /usr/lib/ruby/3.2.0/net/http.rb:1271:in `open'
##[error]#38 6.433 /usr/lib/ruby/3.2.0/net/http.rb:1271:in `block in connect'
##[error]#38 6.433 /usr/local/bundle/gems/timeout-0.3.2/lib/timeout.rb:189:in `block in timeout'
##[error]#38 6.433 /usr/local/bundle/gems/timeout-0.3.2/lib/timeout.rb:196:in `timeout'
##[error]#38 6.433 /usr/lib/ruby/3.2.0/net/http.rb:1269:in `connect'
##[error]#38 6.433 /usr/local/bundle/gems/opentelemetry-instrumentation-net_http-0.19.4/lib/opentelemetry/instrumentation/net/http/patches/instrumentation.rb:59:in `block in connect'
##[error]#38 6.433 /usr/local/bundle/gems/opentelemetry-api-1.0.1/lib/opentelemetry/trace/tracer.rb:29:in `block in in_span'
##[error]#38 6.433 /usr/local/bundle/gems/opentelemetry-api-1.0.1/lib/opentelemetry/trace.rb:82:in `block in with_span'
##[error]#38 6.433 /usr/local/bundle/gems/opentelemetry-api-1.0.1/lib/opentelemetry/context.rb:87:in `with_value'
##[error]#38 6.433 /usr/local/bundle/gems/opentelemetry-api-1.0.1/lib/opentelemetry/trace/tracer.rb:29:in `in_span'
##[error]#38 6.433 /usr/local/bundle/gems/opentelemetry-instrumentation-net_http-0.19.4/lib/opentelemetry/instrumentation/net/http/patches/instrumentation.rb:58:in `connect'
##[error]#38 6.433 /usr/lib/ruby/3.2.0/net/http.rb:1248:in `do_start'
##[error]#38 6.433 /usr/lib/ruby/3.2.0/net/http.rb:1237:in `start'

誰かこれを手伝ってくれませんか?上記の方法でアクティブストレージを接続することは可能でしょうか?

解決策

残念ながら、Ruby 用の Azure SDK は非推奨になりました。参考として、このドキュメントを確認してください。

現在動作しているのは、2024 年 9 月まで利用可能な Azure Storage SDK のみです。そのため、アクセス トークンを取得して Azure Active Directory で認証することはできません。マネージド ID を使用して承認することは不可能だと思います。参考として、このドキュメントを確認してください。

私の知る限り、現時点では、ストレージ アカウントへのアクセスに使用できるのはアクセス キーのみです。

主キーを使用してアクセスし、アクセスキーを使用して操作を実行できます。

私のコード テスト.rb:

require 'azure/storage/blob'  
  
  
storage_account='blobbinding'  
storage_key = 'bl6mr2k440Kg6xxxxxxxxxxxxxxxxxxxxx'  
  
client = Azure::Storage::Blob::BlobService.new(storage_account_name:storage_account, storage_access_key:storage_key)  
  
# Create a container  
container = client.create_container('metrics')

出力: