I've created a service account and furnished with private key in JSON format (/adc.json
). It can be loaded into google-cloud python client via Client.from_service_account_json
function fine. But when I tried call the Monitoring API to write a custom metric, it's getting 403 error like below.
In [1]: from google.cloud import monitoring
In [2]: c = monitoring.Client.from_service_account_json('/adc.json')
In [6]: resource = client.resource('gce_instance', labels={'instance_id': '1234567890123456789', 'zone': 'us-central1-f'})
In [7]: metric = client.metric(type_='custom.googleapis.com/my_metric', labels={'status': 'successful'})
In [9]: from datetime import datetime
In [10]: end_time = datetime.utcnow()
In [11]: client.write_point(metric=metric, resource=resource, value=3.14, end_time=end_time)
---------------------------------------------------------------------------
Forbidden Traceback (most recent call last)
<ipython-input-11-b030f6399aa2> in <module>()
----> 1 client.write_point(metric=metric, resource=resource, value=3.14, end_time=end_time)
/usr/local/lib/python3.5/site-packages/google/cloud/monitoring/client.py in write_point(self, metric, resource, value, end_time, start_time)
599 timeseries = self.time_series(
600 metric, resource, value, end_time, start_time)
--> 601 self.write_time_series([timeseries])
/usr/local/lib/python3.5/site-packages/google/cloud/monitoring/client.py in write_time_series(self, timeseries_list)
544 for timeseries in timeseries_list]
545 self._connection.api_request(method='POST', path=path,
--> 546 data={'timeSeries': timeseries_dict})
547
548 def write_point(self, metric, resource, value,
/usr/local/lib/python3.5/site-packages/google/cloud/_http.py in api_request(self, method, path, query_params, data, content_type, headers, api_base_url, api_version, expect_json, _target_object)
301 if not 200 <= response.status < 300:
302 raise make_exception(response, content,
--> 303 error_info=method + ' ' + url)
304
305 string_or_bytes = (six.binary_type, six.text_type)
Forbidden: 403 User is not authorized to access the project monitoring records. (POST https://monitoring.googleapis.com/v3/projects/MY-PROJECT/timeSeries/)
In the GCP's Access Control Panel, I didn't see a specific predefined role scope for Stackdriver Monitoring API. See the screenshot below:
I've tried Project Viewer
, Service Account Actor
predefined roles, neither worked. I am hesitatant to assigned a Project Editor
role this service account because it feels like it's too broad of a scope for Stackdriver dedicated service account credential. So what should be the correct role to assign to this service account? Thanks.
You are right that it's too broad, and we are working on finer-grained roles, but, as of today, "Project Editor" is the correct role.
If you are running on a GCE VM and omit the private key, the Stackdriver monitoring agent will by default attempt to use the VM's default service account. This will work as long as the VM has the https://www.googleapis.com/auth/monitoring.write
scope (this should be turned on by default for all GCE VMs these days). See this page for a detailed description of what credentials the agent needs.