Giter VIP home page Giter VIP logo

home-assistant-watchdog's Introduction

Home-Assistant-WatchDog

An AWS-powered watchdog that alerts me when my HomeAssistant instance dies.

While this app has some stand-alone utilty - its existence mainly derives from my need for hands-on experience as I attempt to pass the various AWS certs, and as I attempt to improve my practical understanding of CI/CD technology generally.

Also, while HomeAssistant is the motivating problem, this Watchdog could be extended to any component that's capable of invoking a REST API.

Contents / Setup

The project comprises two stacks - one for the CI/CD apparatus, and the other for the app itself.

  • pipeline.yaml defines the CI/CD apparatus, which is a distinct stack. To get it working, simply instantiate the template with CloudFormation. Note - you may need to empty and then delete the S3 bucket, prior to running Create, assuming that it exists already (Updates seem to be unaffected / fine). You will also need to authorise the stack to talk to this GitHub repo (go get an OAuth token).
  • The application itself is a separate stack, and it should instantiate automatically from the CodePipeline object in the other Stack. It comprises two lambdas, a DyDB table (for state), a SNS topic (for alerting), and some IAM objects.

How the pipeline works

  • Source stage is a simple replication of what's in the GitHub repo (make sure you're on the correct branch!).
  • Production stage comprises build, computation of the change set, execution of the change set, and lastly - a smoke test (triggering the heartbeat API, then checking that the state is correctly set in the DyDB table).

screenshot

How the app works

  • The app presents a basic API for recording heartbeats (see the console / CodeBuild for its URL).
  • Once invoked - the app logs the datetime (1st lambda).
  • EventBridge then triggers the 2nd lambda to periodically check the last logged datetime, and notify me if the app has not heartbeat'd recently.
  • On the HomeAssistant side (not part of the repo), I have an AppDaemon daemon that invokes the API every x minutes. I give the URL to HomeAssistant statically in the code at the moment (sloppy, I know), but helpfully - AppDaemon detects such changes and restarts automatically.
  • The various waiting periods and notification endpoints - are parameterised into Environment Variables, EventBridge settings. My hope here is that these can thus be modified at runtime (I.e. without the need for a deployment).

Development off the main branch

Do the following:

  • Create a new branch (E.g. dev)

  • Create / change the software as you see fit.

  • Create the stack using the usual sam commands:

      sam build
      sam package --s3-bucket hawpl-codepl-astore
      sam deploy --s3-bucket hawpl-codepl-astore --stack-name test --capabilities CAPABILITY_NAMED_IAM CAPABILITY_IAM --parameter-overrides EnvironmentType=Dev
    
  • In the above ensure that:

    • Give the stack a disctinct name, like "test"
    • set the Environment Variable EnvironmentType to "Dev". This drives some conditional resource creation, and some distinct resource naming.
  • Iterate.

  • Merge changes to main.

  • Execute the steps in the prior sections.

Biggest todos

Obviously see the Issues, but in general:

  • Authentication of client to API (or similar).
  • Least privilege, generally (the various IAM objects are needlessly permissive).
  • More robust ARN inference code, by which I mean: I have written code that goes and fetches the 0'th SNS topic, etc. This works for now, but won't once I build more applications. I need to sandbox those searches to within the app itself.
  • It would be nice to add more robust testing to the pipeline.
  • Cleanup lambda - so that there's no need for manual activity (see above).
  • Client-side API end-point auto-URL-discovery (or something else that would render the URL static).

Things I found difficult / helpful

  • Most notably there's this helpful sample app, and video. I used this as a guide for designing the app. I especially love their idea of incorporating the pipeline and the app itself as separate stacks within a common repo. This idea is elegant, and I would never have thought to do it.
  • Creating the application components individualls in the console turned out to be pretty easy. On reflection the hard part for me was trying to learn CloudFormation, SAM and CodePipeline simulatenously. I probably made that harder for myself by insisting on defining everything statically, bottom-up from the CF template.

home-assistant-watchdog's People

Contributors

pa-wills avatar

Watchers

 avatar

home-assistant-watchdog's Issues

Additional lambda to do cleanup

Serverless' delete function doesn't remove everything. It leaves in place S3 buckets, and bits of SNS, and doubtless other things as well. I need to write something to clean up what it refuses to.

Refactor for new architecture

Source and build stages can remain essentially unchanged.

A staging / testing stage into a non prod account.

And a final production stage into the prod account.

Separate the deployment steps, put into CodeDeploy / CF

I've separated it into two additional steps - one for compiling a new change set, and one for executing the same. Remaining to do - need to find a home for the smoke test (which used to run in CodeBuild).....

This feels wrong somehow, but one way to do this would be to put an additional CodeBuild project in there. Hey - it worked the first time.

Multi environment

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/continuous-delivery-codepipeline-basic-walkthrough.html

So, I would like to have a test environment separate from the production environment.

The above walkthrough deals with the requirement in the following way:

  • 1 pipeline for everything.
  • 2 stacks, and 2 consecutive pipeline stages in order to deal with that.
  • Pauses and waits for approval prior to pushing to production. Deletes the test stack at that point.

I think this is the way to proceed.

Something else - how would I handle development off the master branch? Presumably by instantiating the stack separately. I.e. one pipeline instance per branch, and 2 envs per pipeline. I think this makes sense. I don't necessarily need to us the pipeline for the dev branch either - i could just get CF to build it directly from the GUI, or use sam on the console.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.