Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@Qix-
Created January 23, 2019 16:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Qix-/6bc9a709b661a4f4defa7d822fb9d80a to your computer and use it in GitHub Desktop.
Save Qix-/6bc9a709b661a4f4defa7d822fb9d80a to your computer and use it in GitHub Desktop.
Example Terraform HTTP backend implementation for Node.js. Stores the state in a local object. Not meant for production, but more to show how one would go about implementing the HTTP api for it since it's not well documented.
terraform {
backend "http" {
address = "http://localhost:8080/tfstate"
lock_address = "http://localhost:8080/tfstate"
unlock_address = "http://localhost:8080/tfstate"
}
}
const URL = require('url');
const bodyParser = require('body-parser');
const express = require('express');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.text());
app.use((req, res, next) => {
req.uri = URL.parse(req.url, true);
req.uri
next();
});
app.use((req, res, next) => {
console.error('\x1b[47m\n\x1b[m');
console.error('------------');
console.error('%s %s', req.method, req.url);
console.error('');
console.error('HEADERS');
console.error('');
console.error(req.headers);
console.error('');
console.error('BODY');
console.error('');
console.error(req.body);
console.error('------------');
next();
});
let locked = null;
let state = null;
app.use('/tfstate', (req, res) => {
switch (req.method) {
case 'LOCK':
if (locked) {
console.error('FAIL: already locked');
return res.status(409).end('nice try, buckaroo - I already seen ye');
}
console.error('OK: lock');
locked = req.body.ID;
return res.status(200).end('as you wisharoo, buckaroo');
case 'UNLOCK':
if (locked && req.body.ID !== locked) {
console.error('FAIL: lock conflict (wrong ID)');
return res.status(409).end('uhwaiit, who are you again?');
}
console.error('OK: unlock');
locked = null;
return res.status(200).end('mischief managed, buckaroo');
case 'POST':
if (!locked || (locked && locked === req.uri.query['ID'])) {
console.error('OK: store');
state = req.body;
return res.status(200).end('gimme dat JSON, buckaroo');
}
console.error('FAIL: locked');
return res.status(423).end('not today, karen');
case 'GET':
console.error('OK: give state');
return res.status(200).end(state !== null && typeof state === 'object' ? JSON.stringify(state) : state || '');
default:
console.error('FAIL: unknown method');
return res.status(405).end('wat?');
}
});
app.get('/health', (req, res) => res.status(200).end('ok'));
app.listen(8080);
@Qix-
Copy link
Author

Qix- commented Jan 23, 2019

Note that you have to check if the state is an object if you're using an automatic body parser since some old versions of Terraform's state were plaintext.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment