Get argo-cd git ssh key from s3 bucket in terraform

ismail yenigül
2 min readOct 20, 2021

--

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 mys3keybucketbucket 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_atomic
set {
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 object
data "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

--

--

ismail yenigül
ismail yenigül

Written by ismail yenigül

CKA/CKAD,AWS certified Freelancer DevOps Engineer

No responses yet