Skip to content

Commit efde307

Browse files
committed
Allow role-based authentication for Athena
You can now specify role_arn to assume a role for querying Athena, rather than using the access key & secret directly. STS requires a region, which might not be the same region as the database's region. To try & clean up the distinction I've moved all the Athena credential settings to a new `credentials` sub-hash.
1 parent 16b1b62 commit efde307

File tree

2 files changed

+35
-8
lines changed

2 files changed

+35
-8
lines changed

README.md

+7-2
Original file line numberDiff line numberDiff line change
@@ -601,9 +601,14 @@ data_sources:
601601
# optional settings
602602
output_location: s3://some-bucket/
603603
workgroup: primary
604-
access_key_id: ...
605-
secret_access_key: ...
606604
region: ...
605+
credentials:
606+
access_key_id: ...
607+
secret_access_key: ...
608+
# optional credential-settings, for role-based authentication:
609+
role_arn: ...
610+
region: ...
611+
607612
```
608613

609614
Here’s an example IAM policy:

lib/blazer/adapters/athena_adapter.rb

+28-6
Original file line numberDiff line numberDiff line change
@@ -168,13 +168,35 @@ def glue
168168
end
169169

170170
def client_options
171-
@client_options ||= begin
172-
options = {}
173-
if settings["access_key_id"] || settings["secret_access_key"]
174-
options[:credentials] = Aws::Credentials.new(settings["access_key_id"], settings["secret_access_key"])
171+
options = {}
172+
if credentials = client_credentials
173+
options[:credentials] = credentials
174+
end
175+
options[:region] = settings["region"] if settings["region"]
176+
options
177+
end
178+
179+
def client_credentials
180+
@client_credentials ||= begin
181+
# Loading the access key & secret from the top-level settings is supported for backwards compatibility,
182+
# but prefer loading them from the 'credentials' sub-hash.
183+
creds = (settings["credentials"] || {}).with_defaults(settings.slice("access_key_id", "secret_access_key", "region"))
184+
access_key_id = creds["access_key_id"]
185+
secret_access_key = creds["secret_access_key"]
186+
role_arn = creds["role_arn"]
187+
if role_arn
188+
region = creds["region"]
189+
role_session_name = creds["role_session_name"] || "blazer"
190+
Aws::AssumeRoleCredentials.new(
191+
access_key_id: access_key_id,
192+
secret_access_key: secret_access_key,
193+
region: region,
194+
role_arn: role_arn,
195+
role_session_name: role_session_name,
196+
)
197+
elsif access_key_id && secret_access_key
198+
Aws::Credentials.new(access_key_id, secret_access_key)
175199
end
176-
options[:region] = settings["region"] if settings["region"]
177-
options
178200
end
179201
end
180202
end

0 commit comments

Comments
 (0)