Concourse SSH Keys using AWS SSM
We started using Concourse at $job, as a replacement for Jenkins. One common thing that almost every Concourse job/pipeline/task will need is access to our git repository, which means Concourse needs an SSH key for our repos.
I googled around for examples of other people using Concourse with SSH keys, and wasn’t able to find any example of anyone storing their SSH keys in AWS SSM Parameter Store. So I’ll post my own example and hopefully help the next person who googles it.
Add your public key to GitHub
This step is GitHub-specific, but the general principal would apply to any git hosting provider. In GitHub, you need to add your public key as a deploy key.
Add your private key to AWS Parameter Store
Which is how Concourse will be able to fetch the private key. You can add the private key to SSM Parameter Store using the AWS CLI like this:
aws ssm put-parameter \
--name /concourse/main/github_private_key \
--type SecureString \
--value $(cat /path/to/your/id_rsa)
Or create the parameter using Terraform or however you normally spin up AWS resources, which is how I did it.
Note that the name of the parameter is pretty important,
/concourse/main/github_private_key
. By default Concourse will look for
parameters who’s names look like /concourse/main/NAME_OF_PARAMETER
. The
/concourse/main
parts, by default, need to be that literal string. Notice the
Credential Lookup Rules in Concourse’s
documentation for more on that.
Using the private key inside Concourse
Now that your private key is stored in SSM, make sure your Concourse server has
IAM permissions to access the parameter (ssm:GetParameter
).
Then you can use, for example, a Concourse git-resource which uses the private key.
---
resources:
- name: my-repo
type: git
source:
branch: master
uri: git@github.com:yourcompany/yourrepo.git
private_key: ((github_private_key))
Notice how Concourse uses the lookup rules described above. The name of the
parameter (((github_private_key))
), matches the third part of the name of
the SSM parameter that we created above. And due to the lookup rules, it just
works.