Google Domains and Terraform

Two major updates recently

Firstly, as suspected, I finally got the notification saying that Google Domains’ registrations would be acquired by SquareSpace so all my registrations would be transferred over them should I not do anything. Obviously, I didn’t want that, so I transferred them over to AWS (Route 53) so now my domains are registered with AWS, but are DNS managed by Cloud DNS. I had some weirdness when trying to migrate all my domains in bulk, with respect to the auth code not being accepted on one of the domains when doing the bulk migration, but it was accepted when I did the migration on that one domain alone, so… go figure.

Next update is Terraform. In case you didn’t know, Hashicorp has changed the Terraform license and essentially made it no longer open source. This behaviour is similar to what Red Hat did with its RHEL offering and the backlash is just as bad.

Immediately I knew someone would fork it, and already, there’s the OpenTF Initiative and this is the key part:

Our request to HashiCorp: switch Terraform back to an open source license.

We ask HashiCorp to do the right thing by the community: instead of going forward with the BUSL license change, switch Terraform back to a truly open source license, and commit to keeping it that way forever going forward. That way, instead of fracturing the community, we end up with a single, impartial, reliable home for Terraform where the whole community can unite to keep building this amazing ecosystem.

Our fallback plan: fork Terraform into a foundation.

If HashiCorp is unwilling to switch Terraform back to an open source license, we propose to fork the legacy MPL-licensed Terraform and maintain the fork in the foundation. This is similar to how Linux and Kubernetes are managed by foundations (the Linux Foundation and the Cloud Native Computing Foundation, respectively), which are run by multiple companies, ensuring the tool stays truly open source and neutral, and not at the whim of any one company.

OpenTF Initiative (https://opentf.org/)

Essentially, make Terraform open source again, or a fork from the MPL version will be made and maintained separately from Hashicorp’s version. This will essentially lead to two, potentially diverging versions of Terraform, one BUSL and one MPL licensed

I’m already looking at alternatives and the two currently that I’m looking at are Ansible and Pulumi

Ansible I’ve had experience in , but there’s two main issues with it:

  • It’s underused compared to Terraform and the providers are woefully undersupported and undermaintained
  • It’s Red Hat

Pulumi I’ve heard lots of good things about, but its a new technology, and I don’t know if it is can “Import” existing infrastructure.

Guess a “spike” is worth doing for it.

Updates

It’s been quite a long time since I did any updates on this blog so a couple of updates are in order

House

I’ve now been living in the new place for just over a year. Generally everything is good, we’ve started putting in a lawn and currently letting it get its roots in before we try to cut it

Twitter

Oh, boy, what an absolute train wreck. I’ve tolerated Elon’s presence at Twitter because most of the stuff he did wasn’t far off what Jack was doing prior. But cutting off all third party clients, forcing everyone onto the new TweetDeck (which likely will be paywalled too) has literally driven users away. Twitter has been losing users and revenue constantly, and it is totally unsurprising.

I’ve disabled my two TweetDeck profiles (a professional one, and a casual one) from Ferdium. But I doubt I will be going back any time soon.

Red Hat

Another train wreck of a situation. Red Hat’s decision to first kill CentOS’s stability, then for RHEL sources to only be accessible behind a subscription has pissed of a lot of users, even if it’s not strictly speaking against license.

The only one left in its sights will be Fedora so that leads me onto the next update

Manjaro & Archlinux

I’ve been tinkering with Manjaro more and more lately, with its rolling release schedule meaning I never need to upgrade from a major version to another major version.

It’s downside I’m finding is that some packages, especially those in the AUR are essentially “compile from source” packages which does the build on your machine during the install. This can take a varying amount of time depending on the code. With my RSS reader of choice: QuiteRSS, this build takes a mind numbing 2.5 hours to do, even on a high spec machine.

That’s where I found out about setting up your own Arch repo. I’ve been tinkering with that, setting it up on GCP and fronted by a CDN. This works pretty well, but I still need to find how I can do scheduled builds to keep that up to date, but it looks like I’ll be switching to Manjaro at some point in the near future. Sound works fine, using lyncolnmd‘s work.

Another downside with Manjaro, however is that its btrfs filesystem, my home directory backup, and CloneZilla don’t seem to want to work well together

WordPress & Domains

One final update, I will likely be transferring out the blenderfox.com domain out of WordPress, while I had this registered as part of the blog, I’m finding it much harder to maintain this domain using WordPress’s very limited DNS management tools. I will likely transfer it out to Google Domains, even though there’s talk of them shuttering that service. Secondary service would be AWS.

Training in Quarantine – Day 179

Late out today — my phone wanted to upgrade so I attempted it (it was an upgrade from Android 9 to Android 10), and it didn’t work, and I ended up having to factory reset and install from scratch. I did have some Titanium Backup backups, but they didn’t seem to work a lot of the time :/

So for the most part, I just reinstalled all the apps I remember using and logged in. For most, that was fine. But I lost the MFA codes on Google Authenticator, meaning I had to remove and setup:

  • AWS
  • LastPass
  • WordPress
  • GitLab

all over again

AWS was quick and painless after a security check to confirm I was who I said I was and they called me on the number on the account.

WordPress was painless too — I was already logged in, so just removed MFA and set it up again, then logged in again. Similarly with LastPass

GitLab however, is proving to be more of a pain. They no longer accept MFA removal requests for people on the Free plan. So I wonder if they will accept me going to a subscription model so I _can_ then request the MFA removal. I think it is better anyway, since I’m hitting the 400 minute CI limit pretty regularly. The 2000 minute CI limit would be better. At least until I can get my own GitLab install working.

As for the run, yes, it was a run — well, more of a jog, anyway. Still did the 3km lap, doing it in 20 mins rather than the 30 mins it normally takes me when I walk it.

How to using S3 as a RWM/NFS-like store in Kubernetes

Let’s assume you have an application that runs happily on its own and is stateless. No problem. You deploy it onto Kubernetes and it works fine. You kill the pod and it respins, happily continuing where it left off.

Let’s add three replicas to the group. That also is fine, since its stateless.

Let’s now change that so that the application is now stateful and requires storage of where it is in between runs. So you pre-provision a disk using EBS and hook that up into the pods, and convert the deployment to a stateful set. Great, it still works fine. All three will pick up where they left off.

Now, what if we wanted to share the same state between the replicas?

For example, what if these three replicas were frontend boxes to a website? Having three different disks is a bad idea unless you can guarantee they will all have the same content. Even if you can, there’s guaranteed to be a case where one or more of the boxes will be either behind or ahead of the other boxes, and consequently have a case where one or more of the boxes will serve the wrong version of content.

There are several options for shared storage, NFS is the most logical but requires you to pre-provision a disk that will be used and also to either have an NFS server outside the cluster or create an NFS pod within the cluster. Also, you will likely over-provision your disk here (100GB when you only need 20GB for example)

Another alternative is EFS, which is Amazon’s NFS storage, where you mount an NFS and only pay for the amount of storage you use. However, even when creating a filesystem in a public subnet, you get a private IP which is useless if you are not DirectConnected into the VPC.

Another option is S3, but how do you use that short of using “s3 sync” repeatedly?

One answer is through the use of s3fs and sshfs

We use s3fs to mount the bucket into a pod (or pods), then we can use those mounts via sshfs as an NFS-like configuration.

The downside to this setup is the fact it will be slower than locally mounted disks.

So here’s the yaml for the s3fs pods (change values within {…} where applicable) — details at Docker Hub here: https://hub.docker.com/r/blenderfox/s3fs/

(and yes, I could convert the environment variables into secrets and reference those, and I might do a follow up article for that)

---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: s3fs
  namespace: default
  labels:
    k8s-app: s3fs
  annotations: {}
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: s3fs
  template:
    metadata:
      name: s3fs
      labels:
        k8s-app: s3fs
    spec:
      containers:
      - name: s3fs
        image: blenderfox/s3fs
        env:
        - name: S3_BUCKET
          value: {...}
        - name: S3_REGION
          value: {...}
        - name: AWSACCESSKEYID
          value: {...}
        - name: AWSSECRETACCESSKEY
          value: {...}
        - name: REMOTEKEY
          value: {...}
        - name: BUCKETUSERPASSWORD
          value: {...}
        resources: {}
        imagePullPolicy: Always
        securityContext:
          privileged: true
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      dnsPolicy: ClusterFirst
      securityContext: {}
      schedulerName: default-scheduler
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600
---
kind: Service
apiVersion: v1
metadata:
  name: s3-service
  annotations:
    external-dns.alpha.kubernetes.io/hostname: {hostnamehere}
service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "3600"
  labels:
    name: s3-service
spec:
  ports:
  - protocol: TCP
    name: ssh
    port: 22
    targetPort: 22
  selector:
    k8s-app: s3fs
  type: LoadBalancer
  sessionAffinity: None
  externalTrafficPolicy: Cluster

This will create a service and a pod

If you have external DNS enabled, the hostname will be added to Route 53.

SSH into the service and verify you can access the bucket mount

ssh bucketuser@dns-name ls -l /mnt/bucket/

(This should give you the listing of the bucket and also should have user:group set on the directory as “bucketuser”)

You should also be able to rsync into the bucket using this

rsync -rvhP /source/path bucketuser@dns-name:/mnt/bucket/

Or sshfs using a similar method


sshfs bucketuser@dns-name:/mnt/bucket/ /path/to/local/mountpoint

Edit the connection timeout annotation if needed

Now, if you set up a pod that has three replicas and all three sshfs to the same service, you essentially have an NFS-like storage.