deploy-cloud-functions icon indicating copy to clipboard operation
deploy-cloud-functions copied to clipboard

Update V3.x ReadMe to Bring Back "Declarative" Message

Open seth-acuitymd opened this issue 1 year ago • 4 comments

TL;DR

The v2 README has a block of text near the top that states

This GitHub Action is declarative, meaning it will overwrite any values on an existing Cloud Function deployment. If you manually deployed a Cloud Function, you must specify all parameters in this action. Any unspecified values will be reverted to their default value (which is usually "null").

The V3 README does not have that text, as such - when using the v3 action, I accidentally defaulted a bunch of config I was specifying via Terraform (that's why we test in lower envs first 😄 )

Detailed design

No response

Additional information

If this GitHub Action is not meant to be declarative in the way that v2 was, then there's a bug, but I assume since v2 is declarative, that v3 will be as well

seth-acuitymd avatar Jun 27 '24 22:06 seth-acuitymd

Hi @seth-acuitymd - it's not supposed to be anymore 😄 . Do you have examples of the specific field(s) that were overwritten?

P.S. Cool name.

sethvargo avatar Jun 27 '24 23:06 sethvargo

P.S. Cool name. Right back at ya!

Here's the block in my GH Action Workflow

- id: 'Deploy'
  uses: 'google-github-actions/deploy-cloud-functions@v3'
  timeout-minutes: 10
  with:
    name: '<FUNCTION_NAME>'
    runtime: 'python311'
    region: 'us-east1'
    entry_point: '<FUNCTION_NAME>'
    source_dir: './cloud_functions/<FUNCTION_NAME>'
    project_id: '<PROJECT_NAME>'

After running this in my dev environment, I later made an unrelated Terraform change, and saw that my state had drifted for that specific function (this function has existed for many months) - was able to confirm that these changes were made when I checked the UI

~ resource "google_cloudfunctions2_function" "territory_visualizer" {
        id               = "projects/<PROJECT_NAME>/locations/us-east1/functions/<FUNCTION_NAME>"
        name             = "<FUNCTION_NAME>"
        # (11 unchanged attributes hidden)

      ~ service_config {
          ~ available_cpu                    = "0.1666" -> "1"
          ~ available_memory                 = "256Mi" -> "2G"
          ~ environment_variables            = {
              + "ENVIRONMENT"      = "development"
                # (1 unchanged element hidden)
            }
          ~ ingress_settings                 = "ALLOW_ALL" -> "ALLOW_INTERNAL_ONLY"
          ~ max_instance_count               = 100 -> 60
          ~ service_account_email            = "<DEFAULT_COMPUTE_SERVICE_ACCOUNT" -> "<FUNCTION_SPECIFIC_SERVICE_ACCOUNT>"
          ~ timeout_seconds                  = 60 -> 1800
            # (8 unchanged attributes hidden)

          + secret_environment_variables {
              + key        = "<SECRET_KEY>"
              + project_id = "<PROJECT_NAME>"
              + secret     = "<SECRET>"
              + version    = "latest"
            }
        }
    }

So it looks like it modified:

  • available_memory (and thus available_cpu)
  • environment_variables / secret_environment_variables
  • ingress_settings
  • max_instance_count
  • timeout_seconds (I think this is service_timeout in the GH Action)

Thanks for looking my friend! Let me know if I can provide more info!

seth-acuitymd avatar Jun 28 '24 16:06 seth-acuitymd

Can you apply that Terraform, then re-run the GitHub Action with GitHub logging enabled and send the output? You didn't set any environment_variables in the action.yml, so they should not have been set upstream.

Or if you can give me a Terraform snippet and full action.yml, I can try to reproduce this myself.

sethvargo avatar Jun 28 '24 20:06 sethvargo

@sethvargo yessir! I'll have that over ASAP - didn't want you to think this was getting stale!

seth-acuitymd avatar Jul 01 '24 17:07 seth-acuitymd

function.tf.txt action.yml.txt sorry for the delay!

seth-acuitymd avatar Jul 11 '24 20:07 seth-acuitymd

Hi @seth-acuitymd your terraform uses node22, but your github action specifies python - that would trigger a full rebuild since you cannot change the environment runtime like that.

sethvargo avatar Jul 11 '24 22:07 sethvargo

Hi @seth-acuitymd - I modified the Terraform to make it work. The first thing I noticed is that, without running any GitHub Action, Terraform is detecting changes:

  # google_cloudfunctions2_function.function_name will be updated in-place
  ~ resource "google_cloudfunctions2_function" "function_name" {
        id               = "projects/sethvargo-dev-e4e82/locations/us-east1/functions/function"
        name             = "function"
        # (11 unchanged attributes hidden)

      ~ service_config {
          ~ environment_variables            = {
              - "LOG_EXECUTION_ID" = "true" -> null
                # (1 unchanged element hidden)
            }
            # (14 unchanged attributes hidden)

            # (1 unchanged block hidden)
        }

        # (1 unchanged block hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

This repeats no matter how many times I apply the changes. If I ignore that, I think there could be a bug/misunderstanding in the FieldMask documentation for Cloud Functions which states (emphasis mine):

The list of fields to be updated. If no field mask is provided, all provided fields in the request will be updated.

My interpretation of that was, if no field is provided, the value will not be touched. The payload being produced by the GitHub Action YAML does not include any secrets or environment variables, so I would expect those fields to be untouched:

##[debug]Compiled Cloud Function definition: {
##[debug]  "name": "function",
##[debug]  "environment": "GEN_2",
##[debug]  "buildConfig": {
##[debug]    "runtime": "nodejs22",
##[debug]    "entryPoint": "function"
##[debug]  },
##[debug]  "serviceConfig": {
##[debug]    "allTrafficOnLatestRevision": true,
##[debug]    "availableMemory": "256Mi",
##[debug]    "ingressSettings": "ALLOW_ALL",
##[debug]    "timeoutSeconds": 60
##[debug]  }
##[debug]}

However, it seems like those fields are being modified, even though they aren't sent with the payload. I think that means we need to construct a field mask (sigh) by iterating over the object. It'll take me a bit to figure out a good way to do that.

sethvargo avatar Jul 11 '24 23:07 sethvargo

Hi @seth-acuitymd your terraform uses node22, but your github action specifies python - that would trigger a full rebuild since you cannot change the environment runtime like that.

@sethvargo - We have two cloud functions we deploy, one in Node and one in Python, I think I grabbed the Action for one, and the Terraform for the other, my bad! 😭

seth-acuitymd avatar Jul 12 '24 16:07 seth-acuitymd

It's all good - I got it working and was able to reproduce it.

sethvargo avatar Jul 12 '24 17:07 sethvargo