What is the best way to specify a FCOS image via Terraform?

What is the best way to accurately source the recommended AMI for a FCOS stream using terraform? The below sources the most recent next stream AMI, but it is not clear to me whether this could source AMIs prior to their official rollout being initiated, or in the case of rollbacks whether we could source potentially non-desirable AMIs.

Note that in the scenario where someone is re-generating Launch groups on a daily basis using terraform they are also likely disabling OS auto-updates and so if they sourced a now non-desirable AMI version they would run with it rather than be rolled back.

data "aws_ami" "fcos_next" {
  most_recent = true
  name_regex  = "^fedora-coreos-.*\\.1\\..*"
  owners      = ["125523088429"]

  # The filters get applied via API call to AWS.  The regex gets applied after
  # the API call so we need both for efficiency...
  filter {
    name   = "name"
    values = ["fedora-coreos-*"]
  }

  filter {
    name   = "architecture"
    values = ["x86_64"]
  }

  filter {
    name   = "root-device-type"
    values = ["ebs"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
}

Here’s how Dalton Hubble is doing it in typhoon:

But I think he is just grabbing the latest too, which is kind of what your question gets at. Ideally something parses our metadata (stable, testing, next) and uses that. It’s the source of truth essentially.

2 Likes

Thanks!

I think you’re right that I need to re-work this to use an http terraform provider to source the metadata and then drive ami selection from that. Will investigate this approach in due course and update the issue.

Separately, re Typhoon I only came across this as a potential FCOS k8s solution relatively recently as a result of a comment you posted on another issue. It is really a very interesting alternative to OKD and for me seems to present an easier migration path. Indeed I wondered whether it should appear more prominently in k8s-related FCOS documents.

Example terraform code that allows selection of the latest target FCOS AWS AMI image as defined by stream metadata - in this hard-coded example for the next stream and us-east-1 region.

Using this strategy will prevent front-running an OS upgrade by accidentally using a pre-positioned but ‘unreleased’ FCOS AWS AMI, and also prevents deploying an AMI that has been rolled back (the rolledback AMI would have a more recent timestamp but is not the ‘target’).

terraform {
    http = {
      source  = "hashicorp/http"
      version = "2.1.0"
    }
}

provider "http" {}

data "http" "next_metadata" {
  url = "https://builds.coreos.fedoraproject.org/streams/next.json"

  request_headers = {
    Accept = "application/json"
  }
}

# Lookup the x86 AWS image for us-east-1.
locals {
  fcos_next_metadata_defined_ami = lookup(jsondecode(data.http.next_metadata.body).architectures.x86_64.images.aws.regions, "us-east-1").image
}

Of course if you are creating AWS ASGs with static Launch Templates your Terraform script will only prevent the front-running / rollback issues at the point-in-time that it creates the Launch Template. Scheduling your terraform to re-apply frequently will reduce this issue but not eliminate it.

Also, in most cases with auto-OS updates enabled the rollback situation is not generally a concern because the OS will just downgrade shortly after provisioning.