Comments (3)
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.
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.
@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)
- Use backend service for external balancer HOT 1
- Remove google project reference so module can be used with count HOT 2
- Provide existing KMS Key for init keys encryption HOT 1
- Unable to use module on Apply M1. HOT 2
- google_compute_instance_group_manager HOT 1
- Tls provider compatibility issue with M1 chip HOT 1
- The root ca and server cert validity_period is hardcoded HOT 1
- Usage of deprecated template_file
- Autoscaling on active/standby node HOT 1
- Dependency Dashboard
- Examples do not work - circular dependency? HOT 1
- Allow tls_save_ca_to_disk to also chose the filename of the full path of the local CA public certificate copy HOT 3
- Recreate MIG VMs after TLS cert update HOT 1
- compute router bgp keepalive_interval is not set HOT 2
- Support deployment to shared VPC with allow_public_egress
- Is bullseye officially supported yet for this module? HOT 1
- Permission 'cloudkms.cryptoKeys.get' denied on init setup HOT 3
- Autohealing port doesn't align with firewall rule port when not using internal LB HOT 1
- Permission 'cloudkms.cryptoKeys.get' denied on init setup HOT 2
- Googleapi error 403 Required 'compute.zones.list' permission for 'projects/XXX', forbidden
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from terraform-google-vault.