Get argo-cd git ssh key from s3 bucket in terraform
While deploying argo-cd from helm chart you can create credential template(git uri, ssh key) in values.yaml under configs.credentialTemplates
section.
credentialTemplates:
ssh-creds:
url: git@github.com:argoproj-labs
sshPrivateKey: |
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----
Then helm chart creates secret for this credentials in k8s. It is good, but we have a problem! If you push this code to GitHub, your ssh key will be stored in plain text. How can we solve this issue real quick?
Solution: Create a private bucket, upload ssh key into that bucket and retrieve s ssh key file from s3 bucket with terraform data source"aws_s3_bucket_object"
Before moving forward, there is a note at https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/s3_bucket_object
The content of an object (body field) is available only for objects which have a human-readable Content-Type (text/* and application/json). This is to prevent printing unsafe characters and potentially downloading large amount of data which would be thrown away in favour of metadata.
So we can’t simply copy ssh key file to s3 bucket as it is. because its content type is not text/plain
$ cat argocdgitssh.key
-----BEGIN OPENSSH PRIVATE KEY-----
b3.........
..... QIDBA==
-----END OPENSSH PRIVATE KEY-----
$ file argocdgitssh.key
argocdgitssh.key: OpenSSH private key
Lets copy the ssh key into mys3keybucket
bucket under argocd/argocdgitssh.key
For this I will use aws s3api put-object
command.
$ aws s3api put-object --bucket mys3keybucket --key argocd/argocdgitssh.key --body ./argocdgitssh.key--content-type text/plain
then read that file with terraform
resource "helm_release" "argocd" {
chart = var.helm_chart_name
create_namespace = var.helm_create_namespace
namespace = var.k8s_namespace
name = var.helm_release_name
version = var.helm_chart_version
repository = var.helm_repo_url
wait = var.helm_wait
timeout = var.helm_timeout
cleanup_on_fail = var.helm_cleanup_on_fail
atomic = var.helm_atomicset {
name = "configs.credentialTemplates.ssh-creds.url"
value = "git@github.com:myproject"
}
set {
name = "configs.credentialTemplates.ssh-creds.sshPrivateKey"
value = sensitive(data.aws_s3_bucket_object.argocdsshkey.body)
}}
#retrive ssh key from s3 bucket objectdata "aws_s3_bucket_object" "argocdsshkey" {
bucket = "mys3keybucket"
key = "argocd/argocdgitssh.key"
}
I used sensitive
terraform function to hide ssh key in terraform plan output. But terraform does not show other set’s in the plan output :D
helm_release.argocd will be updated in-place~ resource "helm_release" "argocd" {
id = "argocd"
name = "argocd"
# (27 unchanged attributes hidden~ set {# At least one attribute in this block is (or was) sensitive,
# so its contents will not be displayed.
}
}
That’s all
Ismail YENIGUL
DevOps Engineer