Skip to content

Commit

Permalink
Enabling Application Default Credentials for BigQuery (#1210)
Browse files Browse the repository at this point in the history
* Enabling Application Default Credentials for BigQuery

* Updated documentation, cleaned up code, and bumped versions.

* Fixed documentation

* Resolved lint issue.

* BigQuery credentials with just a projectId are valid -- remove test.
  • Loading branch information
mescanne authored Apr 22, 2021
1 parent 707c87e commit 42bedcb
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 18 deletions.
5 changes: 3 additions & 2 deletions api/dbadapters/bigquery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,9 +316,10 @@ export class BigQueryDbAdapter implements IDbAdapter {
projectId,
new BigQuery({
projectId,
credentials: JSON.parse(this.bigQueryCredentials.credentials),
scopes: EXTRA_GOOGLE_SCOPES,
location: this.bigQueryCredentials.location
location: this.bigQueryCredentials.location,
credentials: this.bigQueryCredentials.credentials &&
JSON.parse(this.bigQueryCredentials.credentials)
})
);
}
Expand Down
29 changes: 20 additions & 9 deletions cli/credentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,26 @@ import { actuallyResolve } from "df/cli/util";
import { dataform } from "df/protos/ts";

export function getBigQueryCredentials(): dataform.IBigQuery {
const locationIndex = selectionQuestion("Enter the location of your datasets:", [
"US (default)",
"EU",
"other"
]);
let location = locationIndex === 0 ? "US" : "EU";
if (locationIndex === 2) {
location = question("Enter the location's region name (e.g. 'asia-south1'):");
}
const isApplicationDefaultOrJSONKeyIndex = selectionQuestion("Do you wish to use Application Default Credentials or JSON Key:", [
"ADC (default)",
"JSON Key"
]);
if (isApplicationDefaultOrJSONKeyIndex === 0) {
const projectId = question("Enter your billing project ID:");
return {
projectId,
location
}
}
const cloudCredentialsPath = actuallyResolve(
question(
"Please follow the instructions at https://docs.dataform.co/dataform-cli#create-a-credentials-file/\n" +
Expand All @@ -17,15 +37,6 @@ export function getBigQueryCredentials(): dataform.IBigQuery {
throw new Error(`Google Cloud private key file "${cloudCredentialsPath}" does not exist!`);
}
const cloudCredentials = JSON.parse(fs.readFileSync(cloudCredentialsPath, "utf8"));
const locationIndex = selectionQuestion("Enter the location of your datasets:", [
"US (default)",
"EU",
"other"
]);
let location = locationIndex === 0 ? "US" : "EU";
if (locationIndex === 2) {
location = question("Enter the location's region name (e.g. 'asia-south1'):");
}
return {
projectId: cloudCredentials.project_id,
credentials: fs.readFileSync(cloudCredentialsPath, "utf8"),
Expand Down
10 changes: 9 additions & 1 deletion content/docs/getting-started-tutorial/set-up.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,15 @@ For this this tutorial we’ll use BigQuery. Anyone with a Google Account can us

## Generate warehouse credentials

In order for Dataform to connect to your BigQuery warehouse you’ll need to generate some credentials. Dataform will connect to BigQuery using a service account. You’ll need to create a service account from your Google Cloud Console and assign it permissions to access BigQuery.
In order for Dataform to connect to your BigQuery warehouse you’ll need to use Application Default Credentials or a service account and JSON key.

### Using Application Default Credentials

If running on GCE or GKE this will be automatically available. If not, then use `[gcloud auth application-default](https://cloud.google.com/sdk/gcloud/reference/auth/application-default)` to authenticate.

### Create a service account with JSON key

You’ll need to create a service account from your Google Cloud Console and assign it permissions to access BigQuery.

1. To create a new service account in Google Cloud Console you need to:

Expand Down
12 changes: 10 additions & 2 deletions content/docs/warehouses/bigquery.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,18 @@ priority: 1

## Authentication

Dataform will connect to BigQuery using a service account. You’ll need to create a service account from your Google Cloud Console and assign it permissions to access BigQuery.
Dataform will connect to BigQuery using Application Default Credentials or using a service account.

### Application Default Credentials

If using Application Default Credentials ensure that the service account or user has `BigQuery Admin` role or equivalent. (Dataform requires access to create queries and list tables.) Read <a target="_blank" rel="noopener" href="https://cloud.google.com/iam/docs/granting-roles-to-service-accounts#granting_access_to_a_service_account_for_a_resource">this</a> if you need help.

### Service Account

You’ll need to create a service account from your Google Cloud Console and assign it permissions to access BigQuery.

1. Follow <a target="_blank" rel="noopener" href="https://cloud.google.com/iam/docs/creating-managing-service-accounts#creating_a_service_account">these instructions</a> to create a new service account in Google Cloud Console.
2. Grant the new account the `BigQuery Admin` role. (Admin access is required by Dataform so that it can create queries and list tables.) Read
2. Grant the new account the `BigQuery Admin` role. (Admin access is required by Dataform so that it can create datasets and list tables.) Read
<a target="_blank" rel="noopener" href="https://cloud.google.com/iam/docs/granting-roles-to-service-accounts#granting_access_to_a_service_account_for_a_resource">this</a> if you need help.
3. Create a key for your new service account (in JSON format). You will upload this file to Dataform. Read
<a target="_blank" rel="noopener" href="https://cloud.google.com/iam/docs/creating-managing-service-account-keys#creating_service_account_keys">this</a> if you need help.
Expand Down
3 changes: 1 addition & 2 deletions core/adapters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ export function supportsCancel(warehouseType: WarehouseType) {
}

const requiredBigQueryWarehouseProps: Array<keyof dataform.IBigQuery> = [
"projectId",
"credentials"
"projectId"
];
const requiredJdbcWarehouseProps: Array<keyof dataform.IJDBC> = [
"host",
Expand Down
1 change: 1 addition & 0 deletions protos/profiles.proto
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ message Snowflake {

message BigQuery {
string project_id = 1;
// If credentials are unset, then the library will use the application default credentials
string credentials = 3;
// Options are listed here: https://cloud.google.com/bigquery/docs/locations
string location = 4;
Expand Down
2 changes: 1 addition & 1 deletion tests/api/api.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -930,7 +930,7 @@ select \${foo}
);
});

[{}, { wrongProperty: "" }, { projectId: "" }].forEach(bigquery => {
[{}, { wrongProperty: ""}].forEach(bigquery => {
test("bigquery_properties_check", () => {
expect(() =>
credentials.coerce("bigquery", JSON.parse(JSON.stringify(bigquery)))
Expand Down
2 changes: 1 addition & 1 deletion version.bzl
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# NOTE: If you change the format of this line, you must change the bash command
# in /scripts/publish to extract the version string correctly.
DF_VERSION = "1.18.0"
DF_VERSION = "1.19.0"

0 comments on commit 42bedcb

Please sign in to comment.