Vijin
Vijin

Reputation: 447

How to manage ssh key file when we want to execute ansible command with github actions

I have a github repository, a docker repository and a Amazon ec2 instance. I am trying to create a CI/CD pipeline with these tools. The idea is to deploy a docker container to ec2 instance when a push happened to github repository master branch. I have used github actions to build the code, build docker image and push docker image to docker hub. Now I want to pull the latest image from docker hub to remote ec2 instance and run the same. For this I am trying to execute ansible command from github actions. But I need to specify .pem file as an argument to the ansible command. I tried to keep .pem file in github secretes, but it didn't work. I am really confused how to proceed with this. Here is my github workflow file

name: helloworld_cicd
on: 
  push:
    branches: 
      - master
jobs:

  build:
    name: Build
    runs-on: ubuntu-latest
    steps:

    - name: Check out code into the Go module directory
      uses: actions/checkout@v1

    - name: Go Build
      run: go build

    - name: Docker build
      run: docker build -t helloworld .

    - name: Docker login
      run: docker login --username=${{ secrets.docker_username }} --password=${{ secrets.docker_password }}

    - name: Docker tag
      run: docker tag helloworld vijinvv/helloworld:latest

    - name: Docker push
      run: docker push vijinvv/helloworld:latest

I tried to run something like

ansible all -i '3.15.152.219,' --private-key ${{ secrets.ssh_key }} -m rest of the command

but that didn't work. What would be the best way to solve this issue

Upvotes: 3

Views: 3300

Answers (2)

smac89
smac89

Reputation: 43206

I'm guessing what you meant by "it didn't work" is that ansible expects the private key to be a file, whereas you are supplying a string.

This page on github actions shows how to use secret files on github actions. The equivalent for your case would be to do the following steps:

Updated steps June 6th, 2024

Option 1

Fix your original command, by using bash's process substitution syntax:

ansible all -i '3.15.152.219,' --private-key <(echo -n '${{ secrets.ssh_key }}') -m rest of the command

In hindsight, I should have recommended this method to begin with, but I must have not thought of it, or was trying to be pedantic and follow what Github recommended.

Option 2

Store the key as a Github secret rather than as a file in your repo.

  1. gpg --symmetric --output - --cipher-algo AES256 my_private_key.pem | base64 --wrap=0 > my_private_key.pem.b64 (encrypts the secret file to base64)

  2. Choose a strong passphrase and save this passphrase as a secret in github secrets. Call it PRIVATE_KEY_PASSPHRASE

  3. Copy the contents of my_private_key.pem.b64 to a secret variable in Github. Call it PRIVATE_KEY

  4. Create a step in your actions that reads and base64-decodes this file. It could look something like:

    - name: Decrypt Pem
      run: gpg --quiet --batch --yes --decrypt --output $HOME/secrets/my_private_key.pem <(base64 --decode <<<'${{ secrets.PRIVATE_KEY }}') <<< '${{ secrets.PRIVATE_KEY_PASSPHRASE }}'
    
  5. Finally you can run your ansible command with ansible all -i '3.15.152.219,' --private-key $HOME/secrets/my_private_key.pem

Previous method

  1. gpg --symmetric --cipher-algo AES256 my_private_key.pem

  2. Choose a strong passphrase and save this passphrase as a secret in github secrets. Call it LARGE_SECRET_PASSPHRASE

  3. Commit your encrypted my_private_key.pem.gpg in git

  4. Create a step in your actions that decrypts this file. It could look something like:

    - name: Decrypt Pem
      run: gpg --quiet --batch --yes --decrypt --passphrase="$LARGE_SECRET_PASSPHRASE" --output $HOME/secrets/my_private_key.pem my_private_key.pem.gpg
      env:
       LARGE_SECRET_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }}
    
  5. Finally you can run your ansible command with ansible all -i '3.15.152.219,' --private-key $HOME/secrets/my_private_key.pem

Upvotes: 4

ahmad salimi
ahmad salimi

Reputation: 11

You can easily use webfactory/ssh-agent to add your ssh private key. You can see its documentation and add the following stage before running the ansible command.

# .github/workflows/my-workflow.yml
jobs:
  my_job:
    ...
    steps:
      - actions/checkout@v2
      # Make sure the @v0.5.2 matches the current version of the
      # action 
      - uses: webfactory/[email protected]
        with:
          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
      - ... other steps

SSH_PRIVATE_KEY must be the key that is registered in repository secrets. After that, run your ansible command without passing the private key file.

Upvotes: 1

Related Questions