title: How do I rotate service account keys and copy new ones to cloud storage
body: <p>I am trying to automate daily service account key rotation using a function, but not sure how to upload newly created keys to cloud storage and remove old ones.</p>
  
  <p>I have tried the following code, but obviously, it doesn't add to cloud storage bucket. I've also tried incorporating a few gcloud commands into the code, but no luck there either. </p>
  
  <pre><code>import logging
  import os
  
  import googleapiclient.discovery
  from googleapiclient.http import HttpError
  from google.cloud import storage
  
  def rotate(event, context):
      """Triggered from a message on a Cloud Pub/Sub topic. This will rotate the
      key on a service account by creating and adding a new key to the configured
      service account and, if successful, deleting any existing keys.
  
      Args:
           event (dict): Event payload.
           context (google.cloud.functions.Context): Metadata for the event.
      """
  
      service = googleapiclient.discovery.build('iam', 'v1',
                                                cache_discovery=False)
      service_account_email = os.getenv('key-rotation-function@security-logging-test.iam.gserviceaccount.com')
      bucket_name = 'gs://key-rotation-test'
      storage_client = storage.Client()
      bucket = storage_client.get_bucket(bucket_name)
  
      # Create a new key for the service account.
      name = 'projects/-/serviceAccounts/' + service_account_email
      key = service.projects().serviceAccounts().keys().create(
          name=name, body={}).execute()
      new_key = key['name']
      logging.info('Created key: {}'.format(new_key))
  
      # TODO: update usages of the key here.
  
      # Delete any other existing keys.
      keys = service.projects().serviceAccounts().keys().list(
          name='projects/-/serviceAccounts/' + service_account_email).execute()
      for key in keys['keys']:
          if key['name'] != new_key:
              try:
                  service.projects().serviceAccounts().keys().delete(
                      name=key['name']).execute()
                  logging.info('Deleted old key: {}'.format(key['name']))
              except HttpError as e:
                  # Service accounts can have GCP-managed keys which cannot be
                  # deleted. This causes a 400 error on the request, so ignore
                  # 400 errors.
                  if e.resp.status != 400:
                      raise
  
      return None
  </code></pre>