Search code examples
dockeramazon-ec2ansiblegithub-actions

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


Solution

  • 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