Giter VIP home page Giter VIP logo

Comments (3)

cdcme avatar cdcme commented on June 12, 2024 1

Actually, the way it's done here is also nice: https://github.com/matti/terraform-shell-resource. I might fold some of those ideas into the approach up there โ˜๏ธ

from terraform-google-vault.

sethvargo avatar sethvargo commented on June 12, 2024 1

I updated this a bit in #41, but whether you shell out to a script or shell out in a null_resource provisioner is basically the same. Unfortunately there's not a great way to solve this without adding a kms_encrypt resource into Terraform itself.

from terraform-google-vault.

cdcme avatar cdcme commented on June 12, 2024

@medyagh At the moment, I'm using a combination of a Terraform inline template, an env var for the plaintext private key, a file for the encrypted key, and local-exec. From gcloud kms encrypt --help:

If --plaintext-file or --additional-authenticated-data-file is set to '-',
that file is read from stdin. Similarly, if --ciphertext-file is set to
'-', the ciphertext is written to stdout.

In a crypto.tf file, I do this (tested on Alpine):

data "template_file" "encrypt-command" {
  template = <<EOF
      echo -n $SA_PRIV_KEY_BASE64 | base64 -d | gcloud kms encrypt \
      --location $${region} \
      --project $${custom_project_id} \
      --keyring $${google_kms_key_ring_name} \
      --key $${google_kms_crypto_key_name} \
      --plaintext-file - \
      --ciphertext-file - | echo -n | base64 > $${custom_project_id}-sa-key.json.encrypted.base64 \
      && SA_PRIV_KEY_BASE64=
    EOF

  vars {
    custom_project_id          = "${var.project_id}"
    region                     = "${var.region}"
    google_kms_key_ring_name   = "${google_kms_key_ring.project.name}"
    google_kms_crypto_key_name = "${google_kms_crypto_key.project.name}"
  }
}

resource "null_resource" "encrypt-file" {
  triggers {
    sa_key  = "${google_service_account_key.project-sa.id}"
    kms_key = "${google_kms_crypto_key.project.id}"
    sa_key_encrypted = "${google_storage_bucket_object.project-sa-key.id}"
  }

  provisioner "local-exec" {
    command     = "${data.template_file.encrypt-command.rendered}"
    working_dir = "${path.module}"
    interpreter = ["/bin/sh", "-c"]

    environment {
      SA_PRIV_KEY_BASE64 = "${google_service_account_key.project-sa.private_key}"
    }
  }
}

data "local_file" "encrypted-key" {
  filename   = "${path.module}/${var.project_id}-sa-key.json.encrypted.base64"
}

and in my main, I do this:

// Upload the encrypted service account key to the project bucket
resource "google_storage_bucket_object" "project-sa-key" {
  name         = "${var.project_id}-sa-key.json.encrypted.base64"
  content      = "${data.local_file.encrypted-key.content}" // <<--- gets the encrypted contents
  content_type = "application/octet-stream"
  bucket       = "${var.project_id}-bucket"

  provisioner "local-exec" {
    when        = "destroy"
    command     = "rm -f ${var.project_id}-sa-key.json*"
    interpreter = ["sh", "-c"]
  }
}

When I did this, I was thinking in terms of my CI/CD environment. This allows me to avoid using the external provider or the encrypt shellscript at all, avoid making use of temporary unencrypted service account key files, and prevent showing the key contents (encrypted or not) in build output. Note that I'm not doing the SHA checking the script doesโ€”I'm not sure it's really that valuable ๐Ÿค”but wouldn't be too difficult to add to the template above (would probably want to move it into its own template file at that point, though).

Sometimes, the plan or apply step can fail because a) enabling the API takes a bit of time to propagate or b) the encrypted certificate is no longer in the container. To deal with the first issue, I just wait and re-run plan and apply. For the second, I put the encrypted SA key in an environment variable after the first run and copy it to the build container's filesystem in my CI/CD script's before_script section.

If things get very out of sync and you're able to do so, you can also copy the state file to your local machine, taint the SA key, run plan and apply again, copy the encrypted SA key to an environment variable in your CI/CD environment (it will already be uploaded to the project bucket), and re-run the build from there. Anyone using the old encrypted SA key would need to get the new one, though.

I suppose a better way to do this would be to check the project bucket to see if the encrypted SA key is there and if so, copy it to a file during the build so the local-file can find it. There are probably a bunch of other options that haven't occurred to me, too, but this works for me! ๐Ÿค“

from terraform-google-vault.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.