I'm writing this tutorial because I found the bitbucket documentation a little bit confusing explaining the configuration of ssh keys in pipelines. I hope you will find this tutorial useful.
N.B.: to follow this tutorial you must already have a bitbucket repository where pipeline exists (no needs to be a complex pipeline) or is at least enabled. I assume you have a basic knowledge of pipelines and git.
In some of my pipelines I needed to connect to my remote server and run commands/scripts. Bitbucket pipeline allows you to do that. You're on a docker container, based on the image indicated in the pipeline file (tipically ubuntu or another linux distro based) so you can install ssh package on the image, run ssh command to connect to the server and execute commands/scripts directly on the server.
I know you can automate the login passing your password to ssh command but I don't recommend it.
When the pipeline starts, you can't type password or run commands.
SSH Keys avoid you typing password each time you connect to the server and above all are more secure than passwords.
You can setup ssh keys in your pipeline in two ways:
- Single key
- Multiple keys
The difference between choosing single key or multiple keys depends on how you're working.
Usually I associate each branch of the repository with a specific virtual host on my server and I prefer to have multiple keys due to security reasons.
Single key is automatically injected into the docker container when the pipeline starts.
For multiple keys instead, you need to configure the keys manually through little differents steps.
But don't worry and let's start with the single key.
Login into your remote server and cd into the hidden ssh folder in the user's home
Take the public key generated previously and copy it into a file called authorized_keys on the server in the .ssh folder
Return to Repository Settings -> SSH Keys.
In the Known Hosts section, type Host address then click FETCH and wait for response.
When you got response (the fingerprint of server) click the blue button ADD HOST.
IMPORTANT: if your server uses a different port than default (22) to connect via ssh you can type SERVERIP:PORT in the Host address field
Bitbucket automatically injects in the known_host file of docker container the fingerprint of the server and bypass the message below while connecting via ssh for the first time (remember: when pipeline has already started you cannot type or accept anything).
Now in your pipeline file you can use ssh to connect to your server.
Between quotes you can add one or more commands you want to run on your server.
ssh -u USERNAME -h SERVER -p 22 'echo "hello from $USER on remote server"'
Sometimes you may need to pull changes from the repository using git pull. In order to do this, login into your server through the terminal and run the command below to generate private and public keys for your server.
Press enter for all questions (filename, passphrase)
Copy all the content of id_rsa.pub file (public key) and paste it into the key field in Repository Settings -> Access Keys -> Add Key
Finally test the connection running this command on your server.
ssh -T email@example.com
You should see an output says:
authenticated via a deploy key.
You can use git to connect to Bitbucket. Shell access is disabled.
This deploy key has read access to the following repositories:
You saw how to configure single ssh key, now let's see how to setup multiple ssh keys.
Login in your server through terminal and generate ssh keys pair by running this command.
Convert the private key (id_rsa) in base64 format, because the bitbucket repository variables don't accept break lines
base64 -w 0 < id_rsa
Take the output, paste it into a repository variable (named SSH_KEY) in Repository Settings -> Deployments -> your deployment environment, let Secured checked and click ADD.
Repository variables are useful, because in your pipeline file you don't need to write sensitive data like server ip, username, port etc...
Add 3 variables (keep the secured checkbox checked):
- USER with user
- SERVER with serverIp
- PORT with serverPort
More informations about repository variables:
Return to Repository Settings -> SSH Keys.
In the Known Hosts section, type Host address then click FETCH and after response appears click ADD HOST.
Setup your bitbucket-pipelines.yml like the code below:
- in deployment type name of your deployment environment where you previously added the base64 string variable (in my case test)
- in script add the umask string and the ssh command to test connection.
image: atlassian/default-image:latest pipelines: default: - step: name: Deploy to test deployment: test script: # Decode base64 private ssh key string variable and put content in the private key file on docker container - (umask 077 ; echo $SSH_KEY | base64 --decode > ~/.ssh/id_rsa) # Test ssh connection - ssh $USER@$SERVER -p$PORT 'echo "hello from $USER on remote server"'
Follow the single key procedure about Pulling changes if you need to pull changes from repository using git pull.
You can repeat multiple times the steps for multiple keys.
You can change deployment environment with different variables and connect to another server (remember: you need to duplicate the code after default keyword in pipeline file and change data).
Bitbucket doesn't allow you to use the same deployment environment in a different step.
With bitbucket free plan you can add up to 10 deployment environments.
I'll be happy to help you out if something went wrong 😄