Search code examples
pythongoogle-cloud-platformgoogle-apigoogle-api-python-client

Remove GCP instance metadata using Python API


I'm trying to remove an instance's metadata using the Google Python API with the following code, but it seems that I can only add a new one or update an existing one:

from googleapiclient import discovery
from google.oauth2.service_account import Credentials

auth = Credentials.from_service_account_file("my/jwt/file.json")

service = discovery.build(
    serviceName="compute",
    version="v1",
    credentials=auth,
    cache_discovery=False
)

project, zone, instance = ("my-project", "us-east1-c", "my-instance")

result = service.instances().get(project=project, zone=zone,
                                 instance=instance).execute()

fingerprint = result["metadata"]["fingerprint"]
kind = result["metadata"]["kind"]

body = {
    "items": [{
        "key": "want-to-remove-this-key",
        "value": None
    }],
    "kind": kind,
    "fingerprint": fingerprint
}

service.instances().setMetadata(project=project, zone=zone,
                                instance=instance, body=body).execute()

With that code, my instance keeps the metadata key but with no value, and I wanted to remove even the key from the metadata.

Is there a way of doing it, or it's only possible to leave it empty?


Solution

  • Compute Engine only allows update or add metadata so you need handle this.

    If you want to remove all the metadata from an instance, this can work:

    import googleapiclient.discovery
    
    compute = googleapiclient.discovery.build('compute', 'v1')
    
    project= "YOUR_PROJECT_ID"
    zone= "A_ZONE"
    instance_name = "INSTANCE_NAME"
    
    instance_data = compute.instances().get(project=project, zone=zone, instance=instance_name).execute()
    
    body = {
      "fingerprint": instance_data["metadata"]["fingerprint"],
      "items": []
    }
    
    compute.instances().setMetadata(project=project, zone=zone, instance=instance_name, body=body).execute()
    

    If you need to remove a particular key you need to get the current metadata, remove the key and set it again:

    import googleapiclient.discovery
    
    compute = googleapiclient.discovery.build('compute', 'v1')
    
    project= "YOUR_PROJECT_ID"
    zone= "A_ZONE"
    instance_name = "INSTANCE_NAME"
    
    instance_data = compute.instances().get(project=project, zone=zone, instance=instance_name).execute()
    
    metadata_items = instance_data["metadata"]["items"]
    
    body = {
        "fingerprint": instance_data["metadata"]["fingerprint"],
        "items": list(filter(lambda i: i['key'] != "KEY_TO_DELETE", metadata_items))
    }
    
    compute.instances().setMetadata(project=project, zone=zone, instance=instance_name, body=body).execute()
    

    This can be extended to delete multiple key but this can give you an idea.