Google Gemini Code Assist

Published: May 2, 2024 by Isaac Johnson

At Google Cloud NEXT, they announced their Co-Pilot equivalent, “Gemini Code Assist”. GCP GCA is free until July so there is no reason not to check it out.

Today we’ll set it up in Visual Studio Code. We’ll look at use for some different languages including IaC. I’ll cover costs and subscriptions before wrapping with some side-by-side comparisons with Co-Pilot, Gemini for web and Vertex AI.

Installation

The first step is to set it up with the VS Code Extensions Marketplace

/content/images/2024/04/geminicode-01.png

Once installed, you’ll be prompted to Connect to a Google Account

/content/images/2024/04/geminicode-02.png

As we configure, we can change advanced features such as Duet settings, er, I mean Gemini and even feed from an existing codebase

/content/images/2024/04/geminicode-03.png

I’m not certain what ‘Cloudcode’ is so I plan to leave it blank. I would think Google Code, but that went into the Google Graveyard long long ago

/content/images/2024/04/geminicode-04.png

When we (think) we are done, we can mark done

/content/images/2024/04/geminicode-05.png

I did go back and add some languages (not sure I call JSON a language, but sure, add it).

/content/images/2024/04/geminicode-06.png

When I clicked “Backup and Save”, it prompted a merge

/content/images/2024/04/geminicode-07.png

Now, to use it, I click the Gemini icon

/content/images/2024/04/geminicode-08.png

So, okay, we need a GCP Project with the “Cloud AI Companion API enabled”. I guess that makes sense.

Let’s look to that

/content/images/2024/04/geminicode-09.png

I challenge you to find a price on this page: https://cloud.google.com/gemini/docs/discover/set-up-gemini#activate-duet-ai.

In fact, I used Bing to search for the actual cost after trial which informed me it would be $19/mo:

/content/images/2024/04/geminicode-10.png

That is a bit more than the $7 I would pay for co-pilot, however, if we are talking about “for work”, then the Pro seats line up at $20/mo

/content/images/2024/04/geminicode-11.png

Once I “activated” to auth to GCP, I could select a project

/content/images/2024/04/geminicode-12.png

I’ll pick one of my favourite projects to home (charges) in

/content/images/2024/04/geminicode-13.png

and then Enable the API

/content/images/2024/04/geminicode-14.png

This then looked like it is enabling the API

/content/images/2024/04/geminicode-15.png

Once I enabled the API I found I needed to circle back and pick the project again.

Because it is enabled, I can use Bard, I mean Duet, I mean Gemini in the GCP Console as well

/content/images/2024/04/geminicode-16.png

We can go to APIs to disable it or see usage

/content/images/2024/04/geminicode-17.png

Will disabling it cancel? I have no idea. In fact, the whole pricing page says nothing on how to stop it before the $240 (20 x 12) annual charge.

Gemini doesn’t seem to know either

/content/images/2024/04/geminicode-18.png

Note: See Costs and Billing below - I got answers to this and we are fine. In communication with some people at Google, they have plans to update the documentation to bring clarity to the matter.

Usage

Let’s go to that Weather App and try and generate some Unit Tests for our function

/content/images/2024/04/geminicode-19.png

Which came back with some options

/content/images/2024/04/geminicode-20.png

I tried running it, but clearly something is amiss (even changing to 300 return code did nothing)

/content/images/2024/04/geminicode-21.png

I tried something written by Gemini (not Code Assist)

/content/images/2024/04/geminicode-22.png

However, even when adding my own functions, it isn’t working

/content/images/2024/04/geminicode-23.png

Google Cloud Console

We’ve spoken of Gemini in VS Code, but it also can help us build out our GCP Infra.

We can launch Gemini via the icon in the GCP Console

/content/images/2024/04/geminicode-29.png

My first question was to ask about it’s bigger sibling

/content/images/2024/04/geminicode-30.png

I’ll try a question about a gcloud command I use fairly often to bastion in via RDC to windows hosts

/content/images/2024/04/geminicode-31.png

At first, I thought it was in err as (visually) it is missing the “3389” port on the VM as we can see in gcloud documentation

However, when I copied to the clipboard, the VM port was there just hidden off-screen (below is pasted from the Gemini chat)

gcloud compute start-iap-tunnel my-instance 3389 \
    --local-host-port=localhost:13389 \
    --zone=us-central1-a

I then thought of another tidbit that comes up for me regularly; generating TF code.

I’m often whipping up some Terraform for work to sort out a complicated lifecycle policy. I asked for a pretty straightforward one

/content/images/2024/04/geminicode-32.png

I decided to push it a bit. Could I get it to talk about GCP Logging (I find older models have lots of info on Stackdriver, but rarely GCP Logging - which is just about branding/renaming).

Okay, before I go on, I have bone to pick Google! The below is on my LAPTOP and I have old man eyes so I’m not even at max resolution. Why wont you give more space to Gemini? It’s oddly squeezed in a fixed width column on the right.

/content/images/2024/04/geminicode-33.png

As you can see, I asked for a GCP Logging workspace to track changes to my bucket

/content/images/2024/04/geminicode-34.png

resource "google_logging_workspace" "my-workspace" {
  name = "my-workspace"
}

resource "google_logging_sink" "my-sink" {
  name = "my-sink"
  destination = google_logging_workspace.my-workspace.name
  filter = "logName:syslog"
}

resource "google_storage_bucket" "my-bucket" {
  name     = "my-bucket"
  location = "US"

  lifecycle_rule {
    condition {
      age = 30
    }
    action {
      type = "SetStorageClass"
      storage_class = "COLDLINE"
    }
  }

  lifecycle_rule {
    condition {
      age = 180
    }
    action {
      type = "SetStorageClass"
      storage_class = "ARCHIVE"
    }
  }
}

resource "google_logging_folder_sink" "my-folder-sink" {
  name        = "my-folder-sink"
  destination = google_logging_workspace.my-workspace.name
  filter      = "logName:syslog"
}

Let’s consider that code. It will create two sinks for the filter ‘logName:syslog’ and store them into a Logging Workspace. I asked for “Add terraform to log activity to that bucket into a GCP Logging Workspace”

I’m not seeing how actions to ‘my-bucket’ would translate to a filter of ‘logName:syslog’

I pivoted and used Gemini for the web and got the following by asking:

  • GCP logging workspace query for activity on a bucket named mybucket
  • how could i create a sink for that query to a bucket named myloggingbucket?
  • can you write that as terraform?

The last response gave me the code I desired:

Absolutely, here's the Terraform configuration for creating a sink that captures all Cloud Storage logs except those related to "mybucket" and sends them to a separate bucket "myotherlogs":

Terraform
# Configure the Google Cloud Provider
provider "google" {
  project = "<your_project_id>"
  region  = "<your_region>"
}

# Create the bucket for storing excluded Cloud Storage logs
resource "google_storage_bucket" "excluded_logs" {
  name     = "myotherlogs"
  location = google_region.main.location
}

# Create a sink to capture all Cloud Storage logs
resource "google_logging_project_sink" "all_storage_logs" {
  name = "all_storage_logs"
  destination = "storage.googleapis.com/myloggingbucket"

  # Empty filter to capture all logs initially
  filter = ""
}

# Grant storage object creator role to the sink for writing to the bucket
resource "google_storage_bucket_iam_binding" "all_logs_writer" {
  bucket = google_storage_bucket.excluded_logs.name
  role   = "roles/storage.objectCreator"
  members = [google_logging_project_sink.all_storage_logs.writer_identity]
}

# Define the exclusion filter
variable "excluded_filter" {
  type = string
  default = "resource.type=\"storage.googleapis.com\" AND protoPayload.bucket != \"mybucket\""
}

# Create a sink to exclude logs related to "mybucket"
resource "google_logging_project_sink" "exclude_mybucket" {
  name = "exclude_mybucket_logs"
  destination = "storage.googleapis.com/${google_storage_bucket.excluded_logs.name}"
  filter = var.excluded_filter
}

# Grant storage object creator role to the exclusion sink
resource "google_storage_bucket_iam_binding" "exclude_writer" {
  bucket = google_storage_bucket.excluded_logs.name
  role   = "roles/storage.objectCreator"
  members = [google_logging_project_sink.exclude_mybucket.writer_identity]
}
Use code with caution.
Explanation:

Provider Configuration: Defines the GCP project and region.
Excluded Log Bucket: Creates a bucket named "myotherlogs" to store excluded Cloud Storage logs.
All Storage Logs Sink: Creates a sink named "all_storage_logs" that captures all Cloud Storage logs by leaving the filter empty. It sends them to "myloggingbucket".
Grant Storage Permissions: Grants the "all_storage_logs" sink permission to write objects to the "myotherlogs" bucket.
Exclusion Filter: Defines a variable named "excluded_filter" containing the LQL filter to exclude logs related to "mybucket".
Exclude "mybucket" Sink: Creates a sink named "exclude_mybucket_logs" that uses the exclusion filter. This sink sends all excluded Cloud Storage logs (except "mybucket") to "myotherlogs" bucket.
Grant Storage Permissions (Exclusion Sink): Grants the "exclude_mybucket_logs" sink permission to write objects to the "myotherlogs" bucket.

Alternatively, for capturing only "mybucket" logs:

Replace the exclusion filter with an inclusion filter:
resource "google_logging_project_sink" "mybucket_logs" {
  name = "mybucket_logs"
  destination = "storage.googleapis.com/myloggingbucket"
  filter = "resource.type=\"storage.googleapis.com\" AND protoPayload.bucket = \"mybucket\""
}
This approach creates a separate sink named "mybucket_logs" that captures only logs related to "mybucket".

Remember to replace <your_project_id> and <your_region> with your actual values. This code creates the desired Terraform configuration for your Cloud Logging sink based on your specific needs.

Compare to Vertex AI

Let’s try out Vertex and see how it might handle my GCP Bucket Logging problem

/content/images/2024/04/geminicode-35.png

It felt the following was sufficient

resource "google_logging_project_sink" "mybucket_sink" {
  name        = "mybucket-sink"
  destination = "storage.googleapis.com/myloggingbucket"
  filter      = "resource.type=\"gcs_bucket\" AND resource.labels.bucket_name=\"mybucket\""
}

resource "google_storage_bucket" "myloggingbucket" {
  name          = "myloggingbucket"
  location      = "US" # Replace with your desired location
  force_destroy = true
}

I may need to test these two options as they are very different. The final notes on my Gemini output suggested I could use

  filter = "resource.type=\"storage.googleapis.com\" AND protoPayload.bucket = \"mybucket\""

Wheras Vertex suggested

  filter      = "resource.type=\"gcs_bucket\" AND resource.labels.bucket_name=\"mybucket\""

I tried this with the free version of Copilot, though I gave it more freedom on the “how”

/content/images/2024/04/geminicode-36.png

In this terraform we simply are enabling the “logging” service and pointing the output to the logging bucket

# Define the project and region
project = "my-gcp-project"
region = "us-central1"

# Define the bucket names
mybucket_name = "mybucket"
myloggingbucket_name = "myloggingbucket"

# Create the GCP buckets
resource "google_storage_bucket" "mybucket" {
  name     = mybucket_name
  location = region
}

resource "google_storage_bucket" "myloggingbucket" {
  name     = myloggingbucket_name
  location = region
}

# Enable logging for mybucket
resource "google_project_service" "logging" {
  project = project
  service = "logging.googleapis.com"
}

resource "google_storage_bucket_logging" "mybucket_logging" {
  bucket           = google_storage_bucket.mybucket.name
  log_bucket       = google_storage_bucket.myloggingbucket.name
  log_object_prefix = "mybucket-logs/"
}

# Output the bucket names
output "mybucket_name" {
  value = google_storage_bucket.mybucket.name
}

output "myloggingbucket_name" {
  value = google_storage_bucket.myloggingbucket.name
}

Costs and Subscriptions

We can see that while I’m authorized to use VS Code with Gemini for this Trial

/content/images/2024/04/geminicode-24.png

However, after I actually spoke with some inside contacts at Google, they confirmed I would NOT be charged without agreeing to an annual contact.

In one case, I was informed they’ll be updating the docs soon and in another they pointed out no charge would occur and I would get alerted by email before the Gemini trial ended. (LOL. Gemini jumped into VS code and wrote that. sorry there buddy to make you speak of your likely demise).

My other contact pointed me to https://console.cloud.google.com/gemini-admin which is where one can (if they so desire) opt-in on a subscription

/content/images/2024/04/geminicode-25.png

From there it is really clear about start and end dates as well as if one wants to auto-renew

/content/images/2024/04/geminicode-28.png

At the time of this writing is set to be actually US$19/mo if annual (US228) or $22.80 a month (would work out to US$273.60)

To add a subscription, we click through to the Gemini Subscriptions page

/content/images/2024/04/geminicode-27.png

If I’m just considering Gemini for Code, then this might not be the optimum deal as Copilot (Github) is $10/mo for Individual (and $100/year)

/content/images/2024/04/geminicode-26.png

Syncing Settings Issues

I went to another machine where I use VS Code and ensured I was logged in to Github already

/content/images/2024/04/geminicode-40.png

However, I still had to Install the “Gemini + Google Cloud Code” extension. When done, it didn’t have any settings and started the “Welcome” wizard

/content/images/2024/04/geminicode-41.png

Connect worked but it would not let me pick a project. The button did nothing.

When I left here and went to try and find the setting, it never came back. However, I was able to close VS Code and come back to it

/content/images/2024/04/geminicode-42.png

You will have to trust no offscreen browsers are loading, but you can see it do nothing below:

I was just about to give up, but this time when I went to the Gemini Icon, it prompted to pick a project which then let me do so at the top.

/content/images/2024/04/geminicode-43.png

And I it is now working:

/content/images/2024/04/geminicode-44.png

Summary

I feel I need to explore more options before I settle on a final opinion of Gemini. I have yet to opt-in on paid Copilot for Github so my use of Copilot is akin to when it was named Bing AI. I feel it is a great start and I’ll keep trying it. I have to cut a lot of IaC in my role and this will go well to accelerate my day-to-day work.

It isn’t perfect, seems it cannot even introduce itself via VS Code

/content/images/2024/04/geminicode-37.png

However, the web version did fine:


Hey there! I’m Gemini Code Assist, your friendly AI companion in the world of coding. Feeling stuck on a bug? Need a nudge in the right direction? Or maybe you’re just itching to learn a new trick? I’m here to help!

Whether you’re a seasoned programmer or just starting out, I can be your one-stop shop for all things code-related. Think of me as your personal coding sherpa, ready to guide you through the challenges and unlock your coding potential.


It also entertained my dorky requests as well

/content/images/2024/04/geminicode-38.png

The more I use it the more I like it. However, I have to poke a bit of fun at Google for the endless onslaught of name changes - Bard, Duet, Companion AI, and now Gemini (and some product confusion with Vertex).

Gemini AI Google Code Terraform Cloud

Have something to add? Feedback? You can use the feedback form

Isaac Johnson

Isaac Johnson

Cloud Solutions Architect

Isaac is a CSA and DevOps engineer who focuses on cloud migrations and devops processes. He also is a dad to three wonderful daughters (hence the references to Princess King sprinkled throughout the blog).

Theme built by C.S. Rhymes