3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AWS SDK for Ruby Version 2でIAM Roleを使った時にアクセスキーを設定しないで使える仕組み

3
Posted at

はじめに

Version 1の場合の説明はこの記事に書かれてましたが、Version 2はソースコードの中身がVersion 1と全く違かったので調べてみました。

アクセスキーを取得する処理の実行順序

aws-sdk-core/lib/aws-sdk-core/credential_provider_chain.rb

def resolve
  providers.each do |method_name, options|
    provider = send(method_name, options.merge(config: @config))
    return provider if provider && provider.set?
  end
  nil
end

def providers
  [
    [:static_credentials, {}],
    [:env_credentials, {}],
    [:shared_credentials, {}],
    [:instance_profile_credentials, {
       retries: 0,
       http_open_timeout: 1,
       http_read_timeout: 1,
    }],
  ]
end
  1. static_credentials
  2. env_credentials
  3. shared_credentials
  4. instance_profile_credentials

の順に実行されるが、アクセスキーが取得できたらそこで処理は終了。

static_credentials

aws-sdk-core/lib/aws-sdk-core/credential_provider_chain.rb

def static_credentials(options)
  config = options[:config]
  Credentials.new(
    config.access_key_id,
    config.secret_access_key,
    config.session_token)
end

引数で渡したアクセスキーがアクセスキーとしてセットされる。

Aws::EC2::Client.new(
  access_key_id: 'access key',
  secret_access_key: 'secret access key'
)

env_credentials

aws-sdk-core/lib/aws-sdk-core/credential_provider_chain.rb

def env_credentials(options)
  key =    %w(AWS_ACCESS_KEY_ID     AMAZON_ACCESS_KEY_ID     AWS_ACCESS_KEY)
  secret = %w(AWS_SECRET_ACCESS_KEY AMAZON_SECRET_ACCESS_KEY AWS_SECRET_KEY)
  token =  %w(AWS_SESSION_TOKEN     AMAZON_SESSION_TOKEN)
  Credentials.new(envar(key), envar(secret), envar(token))
end

環境変数で設定したものがアクセスキーとしてセットされる。

shared_credentials

aws-sdk-core/lib/aws-sdk-core/shared_credentials.rb

.aws/credentialsに書いた設定からアクセスキーとしてセットされる。

instance_profile_credentials

aws-sdk-core/lib/aws-sdk-core/instance_profile_credentials.rb

def refresh
  # Retry loading credentials up to 3 times is the instance metadata
  # service is responding but is returning invalid JSON documents
  # in response to the GET profile credentials call.
  retry_errors([JSON::ParserError, StandardError], max_retries: 3) do
    c = JSON.parse(get_credentials.to_s)
    @credentials = Credentials.new(
      c['AccessKeyId'],
      c['SecretAccessKey'],
      c['Token']
    )
    @expiration = c['Expiration'] ? Time.parse(c['Expiration']) : nil
  end
end

def get_credentials
  # Retry loading credentials a configurable number of times if
  # the instance metadata service is not responding.
  begin
    retry_errors(NETWORK_ERRORS, max_retries: @retries) do
      open_connection do |conn|
        path = '/latest/meta-data/iam/security-credentials/'
        profile_name = http_get(conn, path).lines.first.strip
        http_get(conn, path + profile_name)
      end
    end
  rescue
    '{}'
  end
end

http://169.254.169.254/latest/meta-data/iam/security-credentials/
を取得するとロール名が返って来る

そのロール名を元に

で取得することでアクセスキーの情報入ったJSONが返って来る。
なのでIAM Roleからアクセスキーの情報を取得するようになっている。

環境による切り分け方

ローカルの開発環境(IAM Roleが使えない)場合

環境変数にアクセスキーを設定して動かす。

本番環境の場合

EC2でIAM Role付きで動かしている場合、環境変数にアクセスキーを設定する必要がない。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?