Today I Learned

19 posts by bartłomiejdanek

for_each over tuples in terraform

Terraform does not allow to iterate through a tuple with for_each, but you can create one in the fly.

locals {
  cron_jobs = [
    {
      name    = "every-15-minutes"
      command = "rake send:sms:notification"
      cron    = "*/15 * * * * *"
    },
    {
      name    = "every-30-minutes"
      command = "rake send:email:notification"
      cron    = "*/30 * * * * *"
    }
  ]
}

resource "nomad_job" "cron_jobs" {
  for_each = { for cj in local.cron_jobs : cj.name => cj }

  jobspec = templatefile("cron_job.tpl", {
    name    = each.key
    command = each.value.command
    cron    = each.value.cron
  })
}

Enable diff-so-fancy for other git actions

[core]
  pager = diff-so-fancy | less -FXRi
[pager]
  add      = true
  diff     = true
  difftool = true
  log      = true
  show     = true

it would enable diff-so-fancy also for git add --patch command and others.

$ git add --patch .
─────────────────────────────────────────────────────────────
modified: main.go
─────────────────────────────────────────────────────────────
@ main.go:6 @ package main
import (
        "flag"
        "fmt"
        log "github.com/sirupsen/logrus"
        "io/ioutil"
        oldLog "log"
        "os"
        "strings"

        log "github.com/sirupsen/logrus"

        "github.com/juliosueiras/terraform-lsp/langserver"
        "github.com/spf13/pflag"
        "github.com/spf13/viper"

Modify Vault data through GitHub Actions and approle

on:
  push:
    branches:
      - master

env:
  CONTAINER_IMAGE: eu.gcr.io/gcp-project-id/image-name:${{ github.sha }}
  VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
  VAULT_VERSION: 1.3.4
  VAULT_SECRETS_STORE: staging

jobs:
  publish:
    name: Publish container image
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@master

      - name: Publish to Vault
        run: |
          curl -sO https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_linux_amd64.zip
          unzip vault_${VAULT_VERSION}_linux_amd64.zip
          export VAULT_TOKEN=$(./vault write -field=token auth/approle/login \
              role_id=${{ secrets.VAULT_ROLE_ID }} \
              secret_id=${{ secrets.VAULT_SECRET_ID }})
          ./vault kv patch backend/${VAULT_SECRETS_STORE} docker_image=${CONTAINER_IMAGE}

PosgreSQL "DROP DATABASE.." RTFM

I have had over 200 databases to move from server to a new one. When a testing “import” succeeded I was ready for a final-final production move.

But I had to clean up the server first and remove all existing databases from “the testing” stage, I even created a SQL function:

DO $$ DECLARE
    db RECORD;
BEGIN
    FOR db IN (SELECT datname FROM pg_database where datdba != 10 AND datdba != 16385 LOOP
        EXECUTE 'DROP DATABASE IF EXISTS ' || quote_ident(db.tablename) ;
    END LOOP;
END $$;

but it did not work as PostgreSQL does not allow to drop a database from a function 😂

Finally, I’ve used a shell script to trigger DROP DATABASE.

Validate privateKey, certificate and CSR files

$ openssl pkey -in privateKey -pubout -outform pem | sha256sum
# => f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2  -
$ openssl x509 -in certificate -pubkey -noout -outform pem | sha256sum 
# => f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2  -
openssl req -in CSR -pubkey -noout -outform pem | sha256sum
# => f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2  -

When all pairs match, you can be sure that you have the right set of files for your domain.

Arel basic use case

veg = Arel::Table.new(:vegetables)

query = veg[:created_at].gteq( 5.days.ago ).and(
  veg[:color].eq("green").or(
    veg[:gardener].eq("Susan")
  )
)

query.to_sql
#  "vegetables"."created_at" >= '2016-12-13 03:54:28.575342'
#    AND ("vegetables"."color" = 'green' OR "vegetables"."gardener" = 'Susan')

Vegetable.where( query )

Triggered by birthday-cake-top-consumer!

Custom nginx proxy host name

server {
    listen 80 default_server;
    server_name ~^(?<developer>.+)\.dev\.selleo\.com$;
    client_max_body_size 5M;
    root   /usr/share/nginx/html;

    location / {
      resolver 8.8.8.8;
      set $backend https://$developer-secret.app.selleo.com:443;
      proxy_pass $backend;
      proxy_set_header  X-Real-IP       $remote_addr;
      proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

resolver does the job here!