0

I use Cloud Function by Google Cloud Platform and terraform for automatic deploys. I use the Cloud Source Repositories for store the code for Cloud Function. I looked for question (Google function source not refreshed after git push) and concludes that automatic refresh is not possible when change the code. When use the terraform for deploy, although not change the banch of my repository the terraform not apply the banch with diferente code.

Someone with the same problem? What solutions did you choose?

Edit 1:

The problem is as follows:

  1. Deploy (with terraform) of my code on the developer branch
  2. I make changes to my branch (developer)
  3. Google function source not refreshed after git push (Google function source not refreshed after git push)
  4. With terraform, I "apply" the changes to the same branch again. Terraform does not recognize changes to the code and does not "modify" the cloud function (with a new "deploy").

Edit 2.

source_repository in google_cloudfunctions_function resource:

  source_repository {
    url = "https://source.developers.google.com/projects/MY_PROJECT_NAME/repos/MY_REPOSITORY_NAME/moveable-aliases/develop/paths/"
  }
roliveira
  • 87
  • 1
  • 12
  • Not sure I understand your question in details. I did understand this answer https://stackoverflow.com/a/56608727/6073141 might be useful in your case. You can configure Cloud Build trigger to deploy a cloud function on push into a chosen branch or 'tag' of the repository. And here you can find some additional info https://cloud.google.com/functions/docs/testing/test-cicd – al-dann Feb 15 '21 at 11:45
  • I'm sorry I wasn't enlightening enough. The problem is as follows: 1. Deploy (with terraform) of my code on the developer branch 2. I make changes to my branch (developer) 3. Google function source not refreshed after git push (https://stackoverflow.com/questions/56607937/google-function-source-not-refreshed-after-git-push/56608727#56608727) 4. With terraform, I "apply" the changes to the same branch again. Terraform does not recognize changes to the code and does not "modify" the cloud function (with a new "deploy"). – roliveira Feb 15 '21 at 12:14
  • When I "deploy with terraform" - it means that I push my commit into the "remote origin" git, which either a GCP repo directly, or mirrored into a GCP repo. My repo has a 'cloudbuild.yaml' file, for example, which is executed automatically (triggered) by the Cloud Build. Inside that 'cloudbuild.yaml' - there are, for example, two commands (simplification) - "terraform init" and "terraform apply". In this scenario, any time my commit is pushed into the remote repository, the cloud build redeploys my cloud functions. No exceptions. Do you mean this case, when you wrote "deploy with terraform"? – al-dann Feb 15 '21 at 12:24
  • Ok I understand. My problem is that even if I make changes to the code, "terraform apply" does not apply my code changes. In the output I see - "0 changed". When I say "deploy with terraform" I mean running the command "terraform apply". – roliveira Feb 15 '21 at 12:33
  • "terraform apply" - locally from your machine? or through cloud build trigger as I described? – al-dann Feb 15 '21 at 12:41
  • Locally in my machine. It is strange not detect the changes, no? – roliveira Feb 15 '21 at 13:08
  • In terraform resource "google_cloudfunctions_function" (https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/cloudfunctions_function), there should be a block "source_repository" with the "url" attribute. Can you describe or show the value of it, please? Usually that url refers to a specific commit, or to a moveable alias (branch), or to a specific fixed alias (tag). Can you disclose what happens in your case, please? – al-dann Feb 15 '21 at 17:10
  • Yes @al-dann. I added to the main topic – roliveira Feb 16 '21 at 17:08

2 Answers2

2

Thank you very much for clarification details.

When terraform runs plan or apply, it tries to find a difference between 3 sources of information - "source code", "state data", and "real life resources". But, the "source code" - is terraform code, not the python, go or node.js, etc. code.

In your example, a "movable alias (branch)" is used in the terraform source code in the source_repository - url attribute. When you modify the cloud function source code, the value of this url attribute is not changed. Thus, from the terraform's point of view the cloud function has not been changed, therefore nothing to be redeployed.

There may be a few ways to solve the issue. One of them is described below.

Instead of a "movable alias (branch)", use a specific "git commit hash". In this case, the value of the url attribute is changed, so terraform sees that the cloud function is to be redeployed.

Therefore, the url attribute should look:

url = https://source.developers.google.com/projects/MY_PROJECT_NAME/repos/MY_REPOSITORY_NAME/revisions/GIT_COMMIT_HASH/paths/RELATIVE_PATH

The RELATIVE_PATH may be omitted if you deploy from the "local root" (the cloud function code is not in any subdirectories).

Now, it is necessary to find out the actual (or the most recent) GIT_COMMIT_HASH. As you deploy from your local machine, you probably can either find the commit hash on your local machine and use it, or find the commit hash from the remote git repository.

The later case is more complex (I guess), but safer. The former case is more simple, but if you forget to git push, the terraform plan/apply will be finished with an error (as the 'commit hash' won't be found in the remote repository from which you deploy the cloud function code). Let's consider the simpler (local) case.

How to find the most recent git commit hash => use a command like: git rev-list -1 HEAD ./ or git rev-list -1 HEAD ./some_path

So that command is to be run (during plan/apply) and the result to be propagated into a terraform file, so that the difference can be revealed by terraform.

In order to implement that, we can use an "external" terraform provider (I guess the latest version is 2.0.0 at the present moment):

provider "external" {
  version     =  "~> 1.2"
}

data "external" "git_commit_hash" {
  program = ["sh", "get-commit-hash.sh"]
}

and we need a bash script with the name "get-commit-hash.sh" (in the same directory, where the terraform is running):

#!/bin/sh

{
  hash_value=`git rev-list -1 HEAD ./`
} &> /dev/null

echo {\"hash\":\""$hash_value"\"}

Bear in mind to apply correct chmod, so it is an executable file.

The last step - to configure the url attribute in the terraform cloud function, and it should be something like this one:

...revisions/${data.external.git_commit_hash.result.hash}/paths...

al-dann
  • 2,545
  • 1
  • 12
  • 22
0

For me it was because someone renamed 1 character in the name of the git project. So hence it wasn't picking up the new commit in my Terraform git project.

Yet somehow it still knew to pick the previous commit. Anyway I just renamed it back to the old name in GitHub (or could have re-linked the Terraform project to git via Terraform's Admin UI). Once I did that, the latest commit that I did in my Terraform got picked up automatically.

AcuTesting
  • 11
  • 2