My hotfix wasn’t deploying
Codebuild and installing private CodeCommit npm packages
There’s nothing more baffling than making a simple code change, pushing that change, and finding the continuous integration build, broken.
I opened up the build logs.
One of the last lines showed this:
npm ERR! Please make sure you have the correct access rights
npm ERR! and the repository exists.
Low and behold. The build couldn’t npm-install a private CodeCommit repository. But I had been installing private npm packages for a year now. So what was the difference?
Before, we were installing npm packages like so:
npm install git+ssh://git.company/v1/repos/project#v1.4.1
And the git.company
nice name is only possible by defining the host in your ssh config file:
Host git.rentr
HostName git-codecommit.eu-west-1.amazonaws.com
However, the decision to use a nice name meant that when someone in our team used the plain old hostname as a dependency (git+ssh://git-codecommit.eu-west-1.amazonaws.com/v1/repos/project#v1.4.1), it could not find the relevant host.
The solution is simple. Have both hosts in the ssh config file:
Host git.company
HostName git-codecommit.eu-west-1.amazonaws.com
User XXXXXXXXXXXXX
IdentityFile ~/.ssh/id_rsaHost git-codecommit.*.amazonaws.com
User XXXXXXXXXXXXX
IdentityFile ~/.ssh/id_rsa
Now, the question is, how do we install private npm packages in CodeBuild. Below is the end result, but I’ll share with you what each line is.
The SSH Client
First, you need SSH on the CodeBuild box.
install:
commands:
- "which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )"
Preparing an ssh session
You’ll need to start the agent.
eval $(ssh-agent -s)
You’ll notice that there isn’t an ssh directory.
mkdir -p ~/.ssh
The Private Key
If you’re familiar with CodeBuild’s environment variables, you may wonder if you can put your id_rsa keys in there.
There are two problems with this:
- Formatting is ignored
- AWS highly suggests not using environment variables for sensitive information but their parameter store.
But is the parameter store a good alternative? Formatting is also ignored. So the SSH key simply won’t load correctly.
So I put the ssh key in an S3 bucket.
aws s3 cp s3://bucket_name/id_rsa ~/.ssh/id_rsa
The SSH Config
For emphasis, you define your ssh hosts.
Host git.company
HostName git-codecommit.eu-west-1.amazonaws.com
User XXXXXXXXXXXXX
IdentityFile ~/.ssh/id_rsaHost git-codecommit.*.amazonaws.com
User XXXXXXXXXXXXX
IdentityFile ~/.ssh/id_rsa
Lockdown your ssh files
SSH will complain if the file permissions are too open. This CodeBuild is just like any Ubuntu box so there are no exceptions here.
- chmod 700 ~/.ssh
- chmod 600 ~/.ssh/config
- chmod 600 ~/.ssh/id_rsa
Avoid the interactive prompt
What interactive prompt?
The authenticity of host '[hostname] ([IP address])' can't be established.
RSA key fingerprint is [key fingerprint].
Are you sure you want to continue connecting (yes/no)?
If you don’t add the following line, your CodeBuild will never complete.
sh-keyscan -t rsa1,rsa,dsa git-codecommit.eu-west-1.amazonaws.com >> ~/.ssh/known_hosts
And you’re done
Run npm install
on whatever private CodeCommit repository you have. As long as you’ve set up the hosts file for it, you’re sorted.