Automating The Automation

I just got Home Assistant running on my Raspberry Pi in my previous post. Unfortunately, trying to edit the configuration file on the device is a major pain. The good news is, with the magic of automation, we can make things more convenient.

We can put our configuration in a git repository, and set up Continuous Integration/Continuous Deployment to automatically update our configuration on the Raspberry Pi whenever we make changes from anywhere we want. Should be pretty slick.

First we need to install the SSH add-on via the HomeAassistant web GUI. First log in to the GUI at http://hassio.local:8123/ (or however yours is set up). Then click Hass.io on the left hand side menu. Select ADD-ON STORE and find the SSH Server add-on. Once the add-on is installed, go to it’s configuration page and paste your SSH public key into the configuration. Then click start.

Now you should be able to SSH into home assistant.

Then create a new project for your configuration files on Gitlab. SSH into Home Assistant and change directories to your configuration files (typically /config). Create a .gitignore file with just a *. I’m erring on the side of caution here to hopefully not expose anything that should be secret on accident.

Then do the following to get your configuration onto Gitlab. This probably misses some files that would be good to have in you repo, but I’d rather find that out later and add them as needed than accidentally add something that should have been kept private.

git init
git add -f .gitignore configuration.yaml groups.yaml automations.yaml scripts.yaml customize.yaml
git commit -m "Initial Commit"
git remote add origin YOUR_REPO_ADDRESS
git push -u origin master

Now that your configuration is on Gitlab, you can clone it onto whatever computer you would like and edit it there. Now we can set up CI to automatically test our configuration file any time we make changes.

Create a file named .gitlab-ci.yml and add the following contents.

stages:
  - test

test:
  stage: test
  image: homeassistant/amd64-homeassistant
  script:
    - hass --script check_config -c .

This will utilize Gitlab’s CI to check your configuration inside a Docker image for Home Assistant. Commit this file and push it back to Gitlab and it should automatically check your configuration. You can see the result in the CI/CD tab.

Next, we’ll have Gitlab automatically push our changes back to our Home Assistant server once the configuration check passes.

First, forward port 22 to your Home Assistant server. If you’re already using port 22 for something, you could pick a different one and add that as an option in the deploy script, but just make sure you have some way for the deploy script to SSH into your server. Note that also means your server should have a static IP address, and you either need a static IP address from your ISP, or a dynamic DNS service.

Now we need to generate the SSH key that the deploy script will use to connect to your server. Run the following command, then copy the public key generated into the SSH server config on you Home Assistant GUI, just like you did before (add it as a new one, not overwriting the old one), and set the contents of the private key as an environment variable for your Gitlab project. Once that is done you can delete the files, since you won’t need them anymore.

ssh-keygen -f deploykey

Next you need to add the keys from your server as a known host to the deploy server. Run the following command, using the public domain or IP that will be used to connect to your server. Then add what is echoed by that command as the value of another variable SSH_KNOWN_HOSTS in your Gitlab variables.

ssh-keyscan yourpublic.domain

Then add DEPLOY_USERDEPLOY_HOST and DEPLOY_PATH as Gitlab variables as well, so those won’t be public either. Now, modify your .gitlab-ci.yml file to contain the following contents.

stages:
  - test
  - deploy

test:
  stage: test
  image: homeassistant/amd64-homeassistant
  script:
    - hass --script check_config -c .

deploy:
  stage: deploy
  only:
- master
  before_script:
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts
script:
    - ssh $DEPLOY_USER@$DEPLOY_HOST "source ~/.bash_profile; cd '$DEPLOY_PATH'; git pull; hassio homeassistant restart"

The deploy part will set up your ssh keys on the server it runs on, then ssh into your home server, pull down your changes, and restart Home Assistant.

Some notes:

  • Your repository needs to be public. Private keys generated on your Home Assistant server are wiped out on reboot, so you can’t use ssh keys to authenticate to Gitlab
  • Your master branch needs to be protected and so do your variables. This way somebody can’t just push up a new branch with changes to your .gitlab-ci.yml file and have it echo back your private keys and stuff.

I put this together by mostly following this tutorial, which also sets up notifications pushed to your phone. If you want that to happen as well, go see that tutorial for the last bit. I might try this out later, but it just doesn’t seem necessary yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s