Service account created from a sink cannot be found - google-cloud-platform

I'm creating a sink by running the following command (as an organization administrator):
gcloud logging sinks create vpc_flow_sink storage.googleapis.com/<storage_bucket_name> --include-children --organization=<organization_id> --log-filter="resource.type="gce_subnetwork" AND logName:"logs/compute.googleapis.com%2Fvpc_flows""
The command executes successfully and outputs the following text:
Created [https://logging.googleapis.com/v2/organizations/<organization_id>/sinks/<sink_name>].
Please remember to grant serviceAccount:o<organization_id>-511237#gcp-sa-logging.iam.gserviceaccount.com the Storage Object Creator role on the bucket.
However, when I go to actually apply the permission to the storage bucket, I cannot find this account (in either the project or within the organization). The accounts also do not appear when I run:
gcloud organizations get-iam-policy <organization_id>
When I describe the sink, the service account exists within the writerIdentity field:
gcloud beta logging sinks describe vpc_flow_sink --organization <organization_id>
...
writerIdentity: serviceAccount:o<organization_id>-511237#gcp-sa-logging.iam.gserviceaccount.com
...
For reference, to try debug this issue, I've attached the following roles: Organization Role Administrator, Logging Admin, Owner, Project Owner, Organization Administrator, Storage Admin.
I am genuinely lost on what to do, how do I go about granting the bucket the role to this account?

When applying the permission to you export destination, don't copy:
serviceAccount:o<organization_id>-511237#gcp-sa-logging.iam.gserviceaccount.com
but instead just use everything after serviceAccount:
o<organization_id>-511237#gcp-sa-logging.iam.gserviceaccount.com...
Google will then recognize the service account. However, I still cannot detect it via gcloud organizations get-iam-policy <organization_id>

Related

Creating a custom service account for Cloud Run using the gcloud CLI

Background
By default, Cloud Run uses the Compute Engine default service account which grants a broad range of permissions which are not required by the container that I'm trying to run in it, and as a result I'd like to set up a new service account.
If I understand correctly, I'd need to do the following:
Create a role with the desired set of permissions (using gcloud iam roles create)
Create a service account (using gcloud iam service-accounts create)
Bind the role permissions to the service account.
Deploy an image with the service account set up in step 2 (using gcloud run deploy --service-account).
The aforementioned documentation doesn't mention how to achieve step 3. I found the gcloud iam service-accounts add-iam-policy-binding command, but I see this is a three way binding between an user (member), a service account and a role, whereas what I've described above seems to require only a two-way binding with the permission grant to the Cloud Run service occurring in the fourth step.
Questions
Do I have the right understanding with regards to the steps required to set up a custom service account for Cloud Run to use?
Assuming I have understood this correctly, what would be the correct way to set up the binding of permissions with the service account?
You can use a custom role in addition of user managed service account, but it's not mandatory. You can also create a user managed service account and bind it with predefined roles.
Anyway, if you want to bind a custom role to a service account (or a user account, no difference), you have to use the fully qualified path for the role
# Project level
projects/<projectID>/roles/<custom role name>
# Organization level
organizations/<organizationID>/roles/<custom role name>
And the gcloud command can be this one
gcloud projects add-iam-policy-binding <projectID> \
--member=serviceAccount:<service account email> \
--role=projects/<projectID>/roles/<custom role name>

How To Grant GCP Organization Level Permissions to Service Account via Command Line

I'm trying to create a data source in terraform to get information about a Google billing account.
data "google_billing_account" "ac" {
display_name = "foo-Billing"
open = true
}
But terraform throws the error Error: Billing account not found: foo-Billing which looks like my service account lacks the required permissions to do this, as the billing account definitely exists.
I'm able to run this command
gcloud projects add-iam-policy-binding main1-project --member=serviceAccount:$ID --role=roles/ROLE_NAME
which works fine with just about any other role binging except that of billing.admin which throws the error
ERROR: (gcloud.projects.add-iam-policy-binding) INVALID_ARGUMENT: Role (roles/billing.admin) does not exist in the resource's hierarchy.
I'm faily new to GCP so I"m not sure how to go about fixing this.
Is there a way to grant billing.admin permissions to a service account from the command line?
Maybe another API to call or something.
I'm able to grant the permission from the UI which then makes my terraform command work, but I would like to be able grant it from the command line.
You're getting this error because you're trying to assign the billing admin role from the project level but it can only be done at the organization level.
If you have an organization, then the same command should work with a slight tweak.
gcloud organizations add-iam-policy-binding ORGANIZATION --member=serviceAccount:$ID --role=roles/billing.admin
You should be able to get a list of your organizations using
gcloud organizations list
If you don't have any, then just create one.
You'll just need a Gsuite or Cloud Identity account.

(gcloud.dataflow.flex-template.build) PERMISSION_DENIED: The caller does not have permission

I'm trying to build a flex-template image using a service account:
gcloud dataflow flex-template build "$TEMPLATE_PATH" \
--image-gcr-path "$TEMPLATE_IMAGE" \
--sdk-language "JAVA" \
--flex-template-base-image JAVA11 \
--metadata-file "metadata.json" \
--jar "target/XXX.jar" \
--env FLEX_TEMPLATE_JAVA_MAIN_CLASS="XXX"
The service account has the following roles:
"roles/appengine.appAdmin",
"roles/bigquery.admin",
"roles/cloudfunctions.admin",
"roles/cloudtasks.admin",
"roles/compute.viewer",
"roles/container.admin",
"roles/dataproc.admin",
"roles/iam.securityAdmin",
"roles/iam.serviceAccountAdmin",
"roles/iam.serviceAccountUser",
"roles/iam.roleAdmin",
"roles/resourcemanager.projectIamAdmin",
"roles/pubsub.admin",
"roles/serviceusage.serviceUsageAdmin",
"roles/servicemanagement.admin",
"roles/spanner.admin",
"roles/storage.admin",
"roles/storage.objectAdmin",
"roles/firebase.admin",
"roles/cloudconfig.admin",
"roles/vpcaccess.admin",
"roles/compute.instanceAdmin.v1",
"roles/dataflow.admin",
"roles/dataflow.serviceAgent"
However, even with the dataflow.admin and dataflow.serviceAgent roles, my service account is still unable to perform this task.
The documentation https://cloud.google.com/dataflow/docs/guides/templates/using-flex-templates advises to grant the roles/owner role to the service account, but I'm hesitant to do that as this is meant to be part of a CI/CD pipeline and giving a service account an owner role doesn't really make sense to me unless I'm completely wrong.
Is there any way to circumvent this issue without granting the owner role to the service account?
I just ran into the exact same issue and spent a few hours figuring this out. We use terraform service account as well. As you mentioned there are 2 main issues: service account access and the build logs access.
By default, cloud build will use a default service account of form [project_number]#cloudbuild.gserviceaccount.com so you need to grant permissions to this service account to write to your gcs bucket backing the gcr container registry. I granted roles/storage.admin to my service account.
Like you mentioned, by default again, cloud build saves the logs at gs://[project_number].cloudbuild-logs.googleusercontent.com. This seems to be a hidden bucket in the project, at least I could not see it. In adddition, can't configure google_storage_bucket_iam_member for it, instead the recommendation as per this doc is to give roles/viewer at the project level to the service account running the gcloud dataflow ... command.
I was able to run the command successfully after the above changes.

IAM permissions to run "gcloud compute images import"

We are attempting to import an image into GCP with the following command
gcloud compute images import
under the context of a service account. When running this command, the message states that it wants to elevate the permissions of the service account to a "Service Account Actor". Since this role is deprecated (i.e. - https://cloud.google.com/iam/docs/service-accounts#the_service_account_actor_role ) and the recommendation of effectively setting the service account to a "service account user" and "service account token creator" does not work. What would be the correct role or set of roles for the execution of this command?
We are running the following version for the gcloud cli
Google Cloud SDK 232.0.0
alpha 2019.01.27
beta 2019.01.27
bq 2.0.40
core 2019.01.27
gsutil 4.35
kubectl 2019.01.27
Also, if this is not the correct forum to ask this type of question, please let me know which and I will be glad to move this to the correct location.
If this is a one-time operation, upload the image to a bucket and execute gcloud compute image import from the cloud shell--which will execute using your user permissions (likely owner). Reference the image in the shell like gs://my-bucket/my-image.vmd
The instructions below will be necessary if you are forced to use a service account on a VM or another resource.
You'll need to (a) identify the active service account and (b) grant the roles/compute.admin role.
(a) Identify the service Account
On the system running gcloud compute images import run this command to identify the active service account
gcloud auth list
Credentialed Accounts
ACTIVE ACCOUNT
* SERVICE_ACCOUNT#googlexxx.com
(b) Add the roles/compute.admin role
You'll need to add the role roles/compute.admin (once working, find a privileged role for POLP)
Open a separate Google Cloud Shell or another shell where you are authenticated with an "owner" role.
Grant the role.computeAdmin permission
# replace this with the active service acct above
ACTIVE_SERVICE_ACCOUNT=SERVICE_ACCOUNT#googlexxx.com
gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
--member="serviceAccount:${ACTIVE_SERVICE_ACCOUNT}" \
--role=roles/compute.admin
this is what worked for me (in my case, compute.admin was not enough):
# this project hosts the service account and the instance that the service account calls `gcloud compute images import ...` from.
worker_project=my-playground-for-building-stuff
# this project hosts your images (it can be the same project as ${worker_project} if that's how you roll)
image_project=my-awesome-custom-images
# this bucket will host resources required by, and artifacts created by cloudbuild during image creation (if you have already run `gcloud compute images import ...` as a normal user (not serviceaccount), then the bucket probably already exists in your ${image_project})
cloudbuild_bucket=${image_project}-daisy-bkt-us
# this is your service account in your ${worker_project}
service_account=my-busy-minion-who-loves-to-work#${worker_project}.iam.gserviceaccount.com
for legacy_role in legacyBucketReader legacyBucketWriter; do
gsutil iam ch serviceAccount:${service_account}:${legacy_role} gs://${cloudbuild_bucket}
done
for role in editor compute.admin iam.serviceAccountTokenCreator iam.serviceAccountUser; do
gcloud projects add-iam-policy-binding ${image_project} --member serviceAccount:${service_account} --role roles/${role}
done
for api in cloudbuild cloudresourcemanager; do
gcloud services enable ${api}.googleapis.com --project ${worker_project}
done

How can I allow a user to become an actor of a service account in Google Cloud Platform (GCP)?

I have a service account that I want to be able to 'act as' (in AWS it's called 'assume'). My service account called 'bucket-viewer-service-account' is shown below in my project:
$ gcloud projects get-iam-policy myproject
bindings:
- members:
- serviceAccount:123456789012-compute#developer.gserviceaccount.com
role: roles/editor
- members:
- user:me#myemail.com
role: roles/owner
- members:
- serviceAccount:bucket-viewer-service-account#myproject.iam.gserviceaccount.com
role: roles/storage.objectViewer
etag: BwVOE_CkjAo=
version: 1
I want to grant another user the ability to 'act as' this service account and I have applied the following, but not getting very far:
$ gcloud iam service-accounts add-iam-policy-binding \
bucket-viewer-service-account#myproject.iam.gserviceaccount.com \
--member='user:test.gcp1#myemail.com' --role='roles/iam.serviceAccountActor'
bindings:
- members:
- user:user:test.gcp1#myemail.com
role: roles/iam.serviceAccountActor
etag: BwVOFAhEVqY=
Is that all I have to do so that the user test.gcp1#myemail.com (once they're logged in) can access the resources available to the service account? Or is there another step required for the user to 'assume' the service account?
I've looked through the many pages of documentation Understanding Service Accounts for starters, but most seem to be thinking in terms of applications using service accounts, where the docs definitely mention users, groups etc can use service accounts to.
The iam.serviceAccountActor role gives users the ability to create and manage compute engine instances that use a service account.
I could be misunderstanding something, but if you want to give someone permission to directly act as a service account, the most straightforward way would probably be to create a private key file for the service account that represents that particular user acting as that service account, and then giving them that private key file.
Giving a user the Service Account Actor role does not give access transitively, like you're suggesting. Instead, it allows a user to "use" the service account to start long-running jobs (e.g. creating a compute engine instance) that have that service account as an identity.
iam.serviceAccountActor role deprecated, you need to use Service Account User role
See More details
Apparently, the test.gcp1#myemail.com will not be able to get the privileges this way when you're running commands from your Terminal. A straightforward solution to this problem is to create and use Keys (similar to "Access Keys" in AWS). The following steps describe how you can achieve this:
Create "Keys" for your service account:
gcloud iam service-accounts keys create KEY-FILE-NAME.json --iam-account=SA-NAME#PROJECT-ID.iam.gserviceaccount.com
Load the "Keys" in your terminal by adding the following environment variable (in .bashrc or equivalent file for your OS):
export GOOGLE_APPLICATION_CREDENTIALS="/file-location/KEY-FILE-NAME.json"
Open a new terminal (or source your environment variable file) and execute CLI commands which will now be executed as your service account.
PS: Do note that the creation of "Keys" poses a considerable risk to the security of your cloud account. Ensure that the service account has minimum GCP Roles (i.e. privileges/policies) added and make sure to delete the keys when they are no longer required.