gcp.storage.getProjectServiceAccount
Explore with Pulumi AI
Get the email address of a project’s unique automatic Google Cloud Storage service account.
For each Google Cloud project, Google maintains a unique service account which is used as the identity for various Google Cloud Storage operations, including operations involving customer-managed encryption keys and those involving storage notifications to pub/sub. This automatic Google service account requires access to the relevant Cloud KMS keys or pub/sub topics, respectively, in order for Cloud Storage to use these customer-managed resources.
The service account has a well-known, documented naming format which is parameterised on the numeric Google project ID. However, as noted in the docs, it is only created when certain relevant actions occur which presuppose its existence. These actions include calling a Cloud Storage API endpoint to yield the service account’s identity, or performing some operations in the UI which must use the service account’s identity, such as attempting to list Cloud KMS keys on the bucket creation page.
Use of this data source calls the relevant API endpoint to obtain the service account’s identity and thus ensures it exists prior to any API operations which demand its existence, such as specifying it in Cloud IAM policy. Always prefer to use this data source over interpolating the project ID into the well-known format for this service account, as the latter approach may cause provider update errors in cases where the service account does not yet exist.
When you write provider code which uses features depending on this service account and your provider code adds the service account in IAM policy on other resources, you must take care for race conditions between the establishment of the IAM policy and creation of the relevant Cloud Storage resource. Cloud Storage APIs will require permissions on resources such as pub/sub topics or Cloud KMS keys to exist before the attempt to utilise them in a bucket configuration, otherwise the API calls will fail. You may need to use
depends_on
to create an explicit dependency between the IAM policy resource and the Cloud Storage resource which depends on it. See the examples here and in thegcp.storage.Notification
resource.
For more information see the API reference.
Example Usage
Pub/Sub Notifications
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const gcsAccount = gcp.storage.getProjectServiceAccount({});
const binding = new gcp.pubsub.TopicIAMBinding("binding", {
topic: topic.name,
role: "roles/pubsub.publisher",
members: [gcsAccount.then(gcsAccount => `serviceAccount:${gcsAccount.emailAddress}`)],
});
import pulumi
import pulumi_gcp as gcp
gcs_account = gcp.storage.get_project_service_account()
binding = gcp.pubsub.TopicIAMBinding("binding",
topic=topic["name"],
role="roles/pubsub.publisher",
members=[f"serviceAccount:{gcs_account.email_address}"])
package main
import (
"fmt"
"github.com/pulumi/pulumi-gcp/sdk/v7/go/gcp/pubsub"
"github.com/pulumi/pulumi-gcp/sdk/v7/go/gcp/storage"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
gcsAccount, err := storage.GetProjectServiceAccount(ctx, nil, nil)
if err != nil {
return err
}
_, err = pubsub.NewTopicIAMBinding(ctx, "binding", &pubsub.TopicIAMBindingArgs{
Topic: pulumi.Any(topic.Name),
Role: pulumi.String("roles/pubsub.publisher"),
Members: pulumi.StringArray{
pulumi.String(fmt.Sprintf("serviceAccount:%v", gcsAccount.EmailAddress)),
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var gcsAccount = Gcp.Storage.GetProjectServiceAccount.Invoke();
var binding = new Gcp.PubSub.TopicIAMBinding("binding", new()
{
Topic = topic.Name,
Role = "roles/pubsub.publisher",
Members = new[]
{
$"serviceAccount:{gcsAccount.Apply(getProjectServiceAccountResult => getProjectServiceAccountResult.EmailAddress)}",
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.storage.StorageFunctions;
import com.pulumi.gcp.storage.inputs.GetProjectServiceAccountArgs;
import com.pulumi.gcp.pubsub.TopicIAMBinding;
import com.pulumi.gcp.pubsub.TopicIAMBindingArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
final var gcsAccount = StorageFunctions.getProjectServiceAccount();
var binding = new TopicIAMBinding("binding", TopicIAMBindingArgs.builder()
.topic(topic.name())
.role("roles/pubsub.publisher")
.members(String.format("serviceAccount:%s", gcsAccount.applyValue(getProjectServiceAccountResult -> getProjectServiceAccountResult.emailAddress())))
.build());
}
}
resources:
binding:
type: gcp:pubsub:TopicIAMBinding
properties:
topic: ${topic.name}
role: roles/pubsub.publisher
members:
- serviceAccount:${gcsAccount.emailAddress}
variables:
gcsAccount:
fn::invoke:
Function: gcp:storage:getProjectServiceAccount
Arguments: {}
Cloud KMS Keys
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const gcsAccount = gcp.storage.getProjectServiceAccount({});
const binding = new gcp.kms.CryptoKeyIAMBinding("binding", {
cryptoKeyId: "your-crypto-key-id",
role: "roles/cloudkms.cryptoKeyEncrypterDecrypter",
members: [gcsAccount.then(gcsAccount => `serviceAccount:${gcsAccount.emailAddress}`)],
});
const bucket = new gcp.storage.Bucket("bucket", {
name: "kms-protected-bucket",
location: "US",
encryption: {
defaultKmsKeyName: "your-crypto-key-id",
},
}, {
dependsOn: [binding],
});
import pulumi
import pulumi_gcp as gcp
gcs_account = gcp.storage.get_project_service_account()
binding = gcp.kms.CryptoKeyIAMBinding("binding",
crypto_key_id="your-crypto-key-id",
role="roles/cloudkms.cryptoKeyEncrypterDecrypter",
members=[f"serviceAccount:{gcs_account.email_address}"])
bucket = gcp.storage.Bucket("bucket",
name="kms-protected-bucket",
location="US",
encryption=gcp.storage.BucketEncryptionArgs(
default_kms_key_name="your-crypto-key-id",
),
opts = pulumi.ResourceOptions(depends_on=[binding]))
package main
import (
"fmt"
"github.com/pulumi/pulumi-gcp/sdk/v7/go/gcp/kms"
"github.com/pulumi/pulumi-gcp/sdk/v7/go/gcp/storage"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
gcsAccount, err := storage.GetProjectServiceAccount(ctx, nil, nil)
if err != nil {
return err
}
binding, err := kms.NewCryptoKeyIAMBinding(ctx, "binding", &kms.CryptoKeyIAMBindingArgs{
CryptoKeyId: pulumi.String("your-crypto-key-id"),
Role: pulumi.String("roles/cloudkms.cryptoKeyEncrypterDecrypter"),
Members: pulumi.StringArray{
pulumi.String(fmt.Sprintf("serviceAccount:%v", gcsAccount.EmailAddress)),
},
})
if err != nil {
return err
}
_, err = storage.NewBucket(ctx, "bucket", &storage.BucketArgs{
Name: pulumi.String("kms-protected-bucket"),
Location: pulumi.String("US"),
Encryption: &storage.BucketEncryptionArgs{
DefaultKmsKeyName: pulumi.String("your-crypto-key-id"),
},
}, pulumi.DependsOn([]pulumi.Resource{
binding,
}))
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var gcsAccount = Gcp.Storage.GetProjectServiceAccount.Invoke();
var binding = new Gcp.Kms.CryptoKeyIAMBinding("binding", new()
{
CryptoKeyId = "your-crypto-key-id",
Role = "roles/cloudkms.cryptoKeyEncrypterDecrypter",
Members = new[]
{
$"serviceAccount:{gcsAccount.Apply(getProjectServiceAccountResult => getProjectServiceAccountResult.EmailAddress)}",
},
});
var bucket = new Gcp.Storage.Bucket("bucket", new()
{
Name = "kms-protected-bucket",
Location = "US",
Encryption = new Gcp.Storage.Inputs.BucketEncryptionArgs
{
DefaultKmsKeyName = "your-crypto-key-id",
},
}, new CustomResourceOptions
{
DependsOn =
{
binding,
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.storage.StorageFunctions;
import com.pulumi.gcp.storage.inputs.GetProjectServiceAccountArgs;
import com.pulumi.gcp.kms.CryptoKeyIAMBinding;
import com.pulumi.gcp.kms.CryptoKeyIAMBindingArgs;
import com.pulumi.gcp.storage.Bucket;
import com.pulumi.gcp.storage.BucketArgs;
import com.pulumi.gcp.storage.inputs.BucketEncryptionArgs;
import com.pulumi.resources.CustomResourceOptions;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
final var gcsAccount = StorageFunctions.getProjectServiceAccount();
var binding = new CryptoKeyIAMBinding("binding", CryptoKeyIAMBindingArgs.builder()
.cryptoKeyId("your-crypto-key-id")
.role("roles/cloudkms.cryptoKeyEncrypterDecrypter")
.members(String.format("serviceAccount:%s", gcsAccount.applyValue(getProjectServiceAccountResult -> getProjectServiceAccountResult.emailAddress())))
.build());
var bucket = new Bucket("bucket", BucketArgs.builder()
.name("kms-protected-bucket")
.location("US")
.encryption(BucketEncryptionArgs.builder()
.defaultKmsKeyName("your-crypto-key-id")
.build())
.build(), CustomResourceOptions.builder()
.dependsOn(binding)
.build());
}
}
resources:
binding:
type: gcp:kms:CryptoKeyIAMBinding
properties:
cryptoKeyId: your-crypto-key-id
role: roles/cloudkms.cryptoKeyEncrypterDecrypter
members:
- serviceAccount:${gcsAccount.emailAddress}
bucket:
type: gcp:storage:Bucket
properties:
name: kms-protected-bucket
location: US
encryption:
defaultKmsKeyName: your-crypto-key-id
options:
dependson:
- ${binding}
variables:
gcsAccount:
fn::invoke:
Function: gcp:storage:getProjectServiceAccount
Arguments: {}
Using getProjectServiceAccount
Two invocation forms are available. The direct form accepts plain arguments and either blocks until the result value is available, or returns a Promise-wrapped result. The output form accepts Input-wrapped arguments and returns an Output-wrapped result.
function getProjectServiceAccount(args: GetProjectServiceAccountArgs, opts?: InvokeOptions): Promise<GetProjectServiceAccountResult>
function getProjectServiceAccountOutput(args: GetProjectServiceAccountOutputArgs, opts?: InvokeOptions): Output<GetProjectServiceAccountResult>
def get_project_service_account(project: Optional[str] = None,
user_project: Optional[str] = None,
opts: Optional[InvokeOptions] = None) -> GetProjectServiceAccountResult
def get_project_service_account_output(project: Optional[pulumi.Input[str]] = None,
user_project: Optional[pulumi.Input[str]] = None,
opts: Optional[InvokeOptions] = None) -> Output[GetProjectServiceAccountResult]
func GetProjectServiceAccount(ctx *Context, args *GetProjectServiceAccountArgs, opts ...InvokeOption) (*GetProjectServiceAccountResult, error)
func GetProjectServiceAccountOutput(ctx *Context, args *GetProjectServiceAccountOutputArgs, opts ...InvokeOption) GetProjectServiceAccountResultOutput
> Note: This function is named GetProjectServiceAccount
in the Go SDK.
public static class GetProjectServiceAccount
{
public static Task<GetProjectServiceAccountResult> InvokeAsync(GetProjectServiceAccountArgs args, InvokeOptions? opts = null)
public static Output<GetProjectServiceAccountResult> Invoke(GetProjectServiceAccountInvokeArgs args, InvokeOptions? opts = null)
}
public static CompletableFuture<GetProjectServiceAccountResult> getProjectServiceAccount(GetProjectServiceAccountArgs args, InvokeOptions options)
// Output-based functions aren't available in Java yet
fn::invoke:
function: gcp:storage/getProjectServiceAccount:getProjectServiceAccount
arguments:
# arguments dictionary
The following arguments are supported:
- Project string
- The project the unique service account was created for. If it is not provided, the provider project is used.
- User
Project string - The project the lookup originates from. This field is used if you are making the request from a different account than the one you are finding the service account for.
- Project string
- The project the unique service account was created for. If it is not provided, the provider project is used.
- User
Project string - The project the lookup originates from. This field is used if you are making the request from a different account than the one you are finding the service account for.
- project String
- The project the unique service account was created for. If it is not provided, the provider project is used.
- user
Project String - The project the lookup originates from. This field is used if you are making the request from a different account than the one you are finding the service account for.
- project string
- The project the unique service account was created for. If it is not provided, the provider project is used.
- user
Project string - The project the lookup originates from. This field is used if you are making the request from a different account than the one you are finding the service account for.
- project str
- The project the unique service account was created for. If it is not provided, the provider project is used.
- user_
project str - The project the lookup originates from. This field is used if you are making the request from a different account than the one you are finding the service account for.
- project String
- The project the unique service account was created for. If it is not provided, the provider project is used.
- user
Project String - The project the lookup originates from. This field is used if you are making the request from a different account than the one you are finding the service account for.
getProjectServiceAccount Result
The following output properties are available:
- Email
Address string - The email address of the service account. This value is often used to refer to the service account in order to grant IAM permissions.
- Id string
- The provider-assigned unique ID for this managed resource.
- Member string
- The Identity of the service account in the form
serviceAccount:{email_address}
. This value is often used to refer to the service account in order to grant IAM permissions. - Project string
- User
Project string
- Email
Address string - The email address of the service account. This value is often used to refer to the service account in order to grant IAM permissions.
- Id string
- The provider-assigned unique ID for this managed resource.
- Member string
- The Identity of the service account in the form
serviceAccount:{email_address}
. This value is often used to refer to the service account in order to grant IAM permissions. - Project string
- User
Project string
- email
Address String - The email address of the service account. This value is often used to refer to the service account in order to grant IAM permissions.
- id String
- The provider-assigned unique ID for this managed resource.
- member String
- The Identity of the service account in the form
serviceAccount:{email_address}
. This value is often used to refer to the service account in order to grant IAM permissions. - project String
- user
Project String
- email
Address string - The email address of the service account. This value is often used to refer to the service account in order to grant IAM permissions.
- id string
- The provider-assigned unique ID for this managed resource.
- member string
- The Identity of the service account in the form
serviceAccount:{email_address}
. This value is often used to refer to the service account in order to grant IAM permissions. - project string
- user
Project string
- email_
address str - The email address of the service account. This value is often used to refer to the service account in order to grant IAM permissions.
- id str
- The provider-assigned unique ID for this managed resource.
- member str
- The Identity of the service account in the form
serviceAccount:{email_address}
. This value is often used to refer to the service account in order to grant IAM permissions. - project str
- user_
project str
- email
Address String - The email address of the service account. This value is often used to refer to the service account in order to grant IAM permissions.
- id String
- The provider-assigned unique ID for this managed resource.
- member String
- The Identity of the service account in the form
serviceAccount:{email_address}
. This value is often used to refer to the service account in order to grant IAM permissions. - project String
- user
Project String
Package Details
- Repository
- Google Cloud (GCP) Classic pulumi/pulumi-gcp
- License
- Apache-2.0
- Notes
- This Pulumi package is based on the
google-beta
Terraform Provider.