Rails on ECS Fargateでタスクロールを使ってS3にアクセスする


背景

FargateコンテナからS3バケットにアクセスしたかったのだが、アクセスキーをコンテナに入れるのはアンチパターン的な話を聞いていたので、AWSオススメ的にECSのタスクロールを使ってアクセスできるように構成したかった。
しかしActiveStorageの本家サイトを見ても、アクセスキーを設定する方法しか紹介されておらず、いろいろ調べたのだがドンピシャの情報が見つからず、ドハマリしたので防備録を書く。

 通常

config/storage.ymlに以下のように書くようになっている。

config/storage.yml
amazon:
  service: S3
  access_key_id: ""
  secret_access_key: ""
  region: ""
  bucket: ""

access_key_id secret_access_keyを省略すれば勝手にタスクロールを利用してつながってくれると思い、以下のように設定した。

config/storage.yml
amazon:
  service: S3
  region: "ap-northeast-1"
  bucket: "myBucket"

だが、さっぱりつながらない。Access Deniedとなる。

コンテナにログインして調査

コンテナにログインして

$ rails c
> s3 = Aws::S3::Client.new
> s3.list_objects(bucket: 'myBucket')

とすると、やっぱりAccess Deniedとなる。タスクロールにS3FullAccessをアタッチしてもダメ。

結論

Railsガイドには以下のように書かれている。

環境変数、標準SDKの設定ファイル、プロファイル、IAMインスタンスのプロファイルやタスクロールを使いたい場合は、上述のaccess_key_id、secret_access_key、regionを省略できます。Amazon S3サービスでは、AWS SDK documentationに記載されている認証オプションをすべてサポートします。

微妙に抽象的なことしか書いていないのでRailsガイドがいつまで経っても苦手なのだが、結論を言うと以下の方法で解決した。

config/initializars/aws.rbを作成し、以下のように書く。

aws.rb
# Configure AWS SDK for Ruby.
if ENV['AWS_ACCESS_KEY_ID'].blank? && Rails.env.production?
  Aws.config.update({ credentials: Aws::ECSCredentials.new })
end

Aws::ECSCredentialsというのは、タスクロールから認証情報を生成してくれるクラスで、aws-sdkに含まれている。
タスクロールは自動的には利用してくれず、上記のように明示的に「タスクロールを使用してAWSリソースにアクセスするよっ!」とRubyで宣言しなければならないらしい。

ActiveStorageの解説は、S3やAzureStorageといった様々なストレージサービスを利用できる様になっているせいか、個々のストレージサービスに関する深堀りした説明がちょっと不足しているような気がする。