Running Flatcar Container Linux on AWS EC2

    The current AMIs for all Flatcar Container Linux channels and EC2 regions are listed below and updated frequently. Using CloudFormation is the easiest way to launch a cluster, but it is also possible to follow the manual steps at the end of the article. Questions can be directed to the Flatcar Container Linux Matrix channel or user mailing list .

    At the end of the document there are instructions for deploying with Terraform.

    Release retention time

    After publishing, releases will remain available as public AMIs on AWS for 9 months. AMIs older than 9 months will be un-published in regular garbage collection sweeps. Please note that this will not impact existing AWS instances that use those releases. However, deploying new instances (e.g. in autoscaling groups pinned to a specific AMI) will not be possible after the AMI was un-published.

    Choosing a channel

    Flatcar Container Linux is designed to be updated automatically with different schedules per channel. You can disable this feature , although we don’t recommend it. Read the release notes for specific features and bug fixes.

    The Stable channel should be used by production clusters. Versions of Flatcar Container Linux are battle-tested within the Beta and Alpha channels before being promoted. The current version is Flatcar Container Linux 4593.2.1.

    View as json feed: amd64 arm64
    EC2 Region AMI Type AMI ID CloudFormation
    af-south-1 HVM (amd64) ami-04c24988136860379 Launch Stack
    HVM (arm64) ami-03a20d6278af06071 Launch Stack
    ap-east-1 HVM (amd64) ami-0169476bf78b4a3ef Launch Stack
    HVM (arm64) ami-037c40369d56ae32a Launch Stack
    ap-northeast-1 HVM (amd64) ami-017b1de61d6d14b2b Launch Stack
    HVM (arm64) ami-07706c268fbd4b76c Launch Stack
    ap-northeast-2 HVM (amd64) ami-06dc07139ae29f88c Launch Stack
    HVM (arm64) ami-02861ff18ad0d32f9 Launch Stack
    ap-south-1 HVM (amd64) ami-0097c6a92caf0d756 Launch Stack
    HVM (arm64) ami-033ac5bf0e83aaeb0 Launch Stack
    ap-southeast-1 HVM (amd64) ami-0c8c1f82c20278e91 Launch Stack
    HVM (arm64) ami-001c9851d4022d0f8 Launch Stack
    ap-southeast-2 HVM (amd64) ami-0e98f20ca99c64131 Launch Stack
    HVM (arm64) ami-0e30c9c4cf50ce7be Launch Stack
    ap-southeast-3 HVM (amd64) ami-08b758a8ef6c30880 Launch Stack
    HVM (arm64) ami-03535a39b1b31a862 Launch Stack
    ca-central-1 HVM (amd64) ami-0307464a7b587a7c1 Launch Stack
    HVM (arm64) ami-0378100a9cdcfda88 Launch Stack
    eu-central-1 HVM (amd64) ami-0067c9f512ba29408 Launch Stack
    HVM (arm64) ami-0b300d3cbddea696f Launch Stack
    eu-north-1 HVM (amd64) ami-025c19c5a086943f4 Launch Stack
    HVM (arm64) ami-0e39efa275116a1b6 Launch Stack
    eu-south-1 HVM (amd64) ami-055a9a5df314c3e33 Launch Stack
    HVM (arm64) ami-0c84fe89b91fbf4e5 Launch Stack
    eu-west-1 HVM (amd64) ami-0a9f4e2b02cabead7 Launch Stack
    HVM (arm64) ami-0befacd33a4be3f76 Launch Stack
    eu-west-2 HVM (amd64) ami-04b0511265f6b898d Launch Stack
    HVM (arm64) ami-00b04f07e0ddb2227 Launch Stack
    eu-west-3 HVM (amd64) ami-055ee9d79aedc0c90 Launch Stack
    HVM (arm64) ami-02905573b7b4501a3 Launch Stack
    sa-east-1 HVM (amd64) ami-08b8d52765de877aa Launch Stack
    HVM (arm64) ami-05f0e25bd12355616 Launch Stack
    us-east-1 HVM (amd64) ami-014b11e8a5507c680 Launch Stack
    HVM (arm64) ami-016df8a66ee6b4666 Launch Stack
    us-east-2 HVM (amd64) ami-03ef56184a33dd392 Launch Stack
    HVM (arm64) ami-0a97df0ce509d3fa4 Launch Stack
    us-west-1 HVM (amd64) ami-0821adffd6ca7e419 Launch Stack
    HVM (arm64) ami-001f628b43a3f333b Launch Stack
    us-west-2 HVM (amd64) ami-0c0c27d08ecab706a Launch Stack
    HVM (arm64) ami-08b3a16895a1f5b83 Launch Stack

    The Beta channel consists of promoted Alpha releases. The current version is Flatcar Container Linux 4628.1.1.

    View as json feed: amd64 arm64
    EC2 Region AMI Type AMI ID CloudFormation
    af-south-1 HVM (amd64) ami-09903d2f5187a7d04 Launch Stack
    HVM (arm64) ami-0b048ad2cd990d8f8 Launch Stack
    ap-east-1 HVM (amd64) ami-0943c45900f98c212 Launch Stack
    HVM (arm64) ami-09e39e97522ef0440 Launch Stack
    ap-northeast-1 HVM (amd64) ami-03c7fa87c2a66b811 Launch Stack
    HVM (arm64) ami-00b85246449e2f43f Launch Stack
    ap-northeast-2 HVM (amd64) ami-04413d08b83f00a74 Launch Stack
    HVM (arm64) ami-059d95e2389737a79 Launch Stack
    ap-south-1 HVM (amd64) ami-0ccdca18d5b85d820 Launch Stack
    HVM (arm64) ami-03402d0d8814140a4 Launch Stack
    ap-southeast-1 HVM (amd64) ami-001c2b5b6022742fa Launch Stack
    HVM (arm64) ami-0239907eedc84a10c Launch Stack
    ap-southeast-2 HVM (amd64) ami-01dabf3dbb9c57545 Launch Stack
    HVM (arm64) ami-0dabda959fc212613 Launch Stack
    ap-southeast-3 HVM (amd64) ami-009320354b1fae1b0 Launch Stack
    HVM (arm64) ami-0a1609fcc35f033ea Launch Stack
    ca-central-1 HVM (amd64) ami-0b9b43e988c7e763f Launch Stack
    HVM (arm64) ami-0b1788425eca73340 Launch Stack
    eu-central-1 HVM (amd64) ami-0f17f74422231bc7e Launch Stack
    HVM (arm64) ami-0521fbe9f388035a7 Launch Stack
    eu-north-1 HVM (amd64) ami-036923a1d479d87e7 Launch Stack
    HVM (arm64) ami-0e78bc9d6ba500695 Launch Stack
    eu-south-1 HVM (amd64) ami-09b218e656a249ee2 Launch Stack
    HVM (arm64) ami-0a882e1e493fd1293 Launch Stack
    eu-west-1 HVM (amd64) ami-037eda480ceb75f2a Launch Stack
    HVM (arm64) ami-065a3de0c0cac012c Launch Stack
    eu-west-2 HVM (amd64) ami-0685ece8ebcc59b28 Launch Stack
    HVM (arm64) ami-0500714d7c532f70b Launch Stack
    eu-west-3 HVM (amd64) ami-0f2530f3e79ad4c29 Launch Stack
    HVM (arm64) ami-0447c1cacaaa9847d Launch Stack
    sa-east-1 HVM (amd64) ami-06a5d0e56c6446f6d Launch Stack
    HVM (arm64) ami-0aa4cd42499c2c5a7 Launch Stack
    us-east-1 HVM (amd64) ami-0d0866f5dcbc1b106 Launch Stack
    HVM (arm64) ami-058e6a24d9158c866 Launch Stack
    us-east-2 HVM (amd64) ami-0b30e5354f9202cfc Launch Stack
    HVM (arm64) ami-086b3353ca2fa1faf Launch Stack
    us-west-1 HVM (amd64) ami-0503f1bc3ba9d610f Launch Stack
    HVM (arm64) ami-034f20b3a7ef7bcf5 Launch Stack
    us-west-2 HVM (amd64) ami-084896eb6ad67dcb4 Launch Stack
    HVM (arm64) ami-0742bb8e1eea4db09 Launch Stack

    The Alpha channel closely tracks master and is released frequently. The newest versions of system libraries and utilities will be available for testing. The current version is Flatcar Container Linux 4694.0.0.

    View as json feed: amd64 arm64
    EC2 Region AMI Type AMI ID CloudFormation
    af-south-1 HVM (amd64) ami-038bdc06e84785b25 Launch Stack
    HVM (arm64) ami-0050056670a3a3bad Launch Stack
    ap-east-1 HVM (amd64) ami-036b2e3f92a0718de Launch Stack
    HVM (arm64) ami-0ee33e75d3e63426b Launch Stack
    ap-northeast-1 HVM (amd64) ami-0938be1bda0eedee0 Launch Stack
    HVM (arm64) ami-0a687256c5d368dc8 Launch Stack
    ap-northeast-2 HVM (amd64) ami-0832bd6ac4d6b4d6b Launch Stack
    HVM (arm64) ami-0d45dd5494982408d Launch Stack
    ap-south-1 HVM (amd64) ami-03864f0ae5cbe4812 Launch Stack
    HVM (arm64) ami-0e1811231f85caf52 Launch Stack
    ap-southeast-1 HVM (amd64) ami-0095b07164204b00b Launch Stack
    HVM (arm64) ami-0318bf7053d931e48 Launch Stack
    ap-southeast-2 HVM (amd64) ami-01e08bc5b800f9764 Launch Stack
    HVM (arm64) ami-0ff83b6f5a5286ba0 Launch Stack
    ap-southeast-3 HVM (amd64) ami-05e2f6781f628f588 Launch Stack
    HVM (arm64) ami-086c19cbc7ef2b781 Launch Stack
    ca-central-1 HVM (amd64) ami-03601fc3da7e553d7 Launch Stack
    HVM (arm64) ami-0adf64d1d1c37ebdb Launch Stack
    eu-central-1 HVM (amd64) ami-074660e1a38d8ee1c Launch Stack
    HVM (arm64) ami-092d67f64d2677127 Launch Stack
    eu-north-1 HVM (amd64) ami-09ac54e854bca5015 Launch Stack
    HVM (arm64) ami-075a718070eca2d6e Launch Stack
    eu-south-1 HVM (amd64) ami-073ac9d030c05a365 Launch Stack
    HVM (arm64) ami-0978f9ab73a9a1cb4 Launch Stack
    eu-west-1 HVM (amd64) ami-0e0f743a96f2f01d6 Launch Stack
    HVM (arm64) ami-0d7179225a18913f9 Launch Stack
    eu-west-2 HVM (amd64) ami-056143279604d5146 Launch Stack
    HVM (arm64) ami-09331b66bbe5a6770 Launch Stack
    eu-west-3 HVM (amd64) ami-0c1812ba6232fd65e Launch Stack
    HVM (arm64) ami-0d89c40debfaa14d9 Launch Stack
    sa-east-1 HVM (amd64) ami-09d38d21ddf24bd43 Launch Stack
    HVM (arm64) ami-0a7c8911beb8ec533 Launch Stack
    us-east-1 HVM (amd64) ami-03e30902e328b1672 Launch Stack
    HVM (arm64) ami-03faae768ca0a8773 Launch Stack
    us-east-2 HVM (amd64) ami-07eddbcff549be11e Launch Stack
    HVM (arm64) ami-059073415e4254fc3 Launch Stack
    us-west-1 HVM (amd64) ami-0d8a38910a89ed740 Launch Stack
    HVM (arm64) ami-00be1f74d08816551 Launch Stack
    us-west-2 HVM (amd64) ami-0120229cc576838e7 Launch Stack
    HVM (arm64) ami-0877ad35270c07455 Launch Stack

    LTS release streams are maintained for an extended lifetime of 18 months. The yearly LTS streams have an overlap of 6 months. The current version is Flatcar Container Linux 4081.3.7.

    View as json feed: amd64 arm64
    EC2 Region AMI Type AMI ID CloudFormation
    af-south-1 HVM (amd64) ami-00bde772472b08beb Launch Stack
    HVM (arm64) ami-0e49bee00bc9e8ac4 Launch Stack
    ap-east-1 HVM (amd64) ami-0c1c2cdecf0eae1c1 Launch Stack
    HVM (arm64) ami-09c0e91085a9e5cb1 Launch Stack
    ap-northeast-1 HVM (amd64) ami-02f8ef5b1e101a694 Launch Stack
    HVM (arm64) ami-00b4755a8f082af4d Launch Stack
    ap-northeast-2 HVM (amd64) ami-093e93a462e7bad25 Launch Stack
    HVM (arm64) ami-03425aadf32e1d567 Launch Stack
    ap-south-1 HVM (amd64) ami-067c6fab2f9ac9265 Launch Stack
    HVM (arm64) ami-0c437f511234770d7 Launch Stack
    ap-southeast-1 HVM (amd64) ami-05fdc190a1c53e0e1 Launch Stack
    HVM (arm64) ami-0369732bbf7d00283 Launch Stack
    ap-southeast-2 HVM (amd64) ami-0bffe7305ae7e03d4 Launch Stack
    HVM (arm64) ami-093fe1d0ba89cba03 Launch Stack
    ap-southeast-3 HVM (amd64) ami-011a5840197208be5 Launch Stack
    HVM (arm64) ami-0c4e4d5d333059632 Launch Stack
    ca-central-1 HVM (amd64) ami-0332d68c9aad9072d Launch Stack
    HVM (arm64) ami-0255bf9dba3103632 Launch Stack
    eu-central-1 HVM (amd64) ami-004a962d9b75db8fa Launch Stack
    HVM (arm64) ami-094164bf9361aa0aa Launch Stack
    eu-north-1 HVM (amd64) ami-08644419ce33265c6 Launch Stack
    HVM (arm64) ami-05d8e27c6899aca22 Launch Stack
    eu-south-1 HVM (amd64) ami-08a7acc9ba672688f Launch Stack
    HVM (arm64) ami-0451f86c5064ec97f Launch Stack
    eu-west-1 HVM (amd64) ami-03eb21068807067d6 Launch Stack
    HVM (arm64) ami-0ee48705f5a6bf37b Launch Stack
    eu-west-2 HVM (amd64) ami-0ad04c73680f4e622 Launch Stack
    HVM (arm64) ami-0612dcb539422e4e7 Launch Stack
    eu-west-3 HVM (amd64) ami-0caf9249931005f8a Launch Stack
    HVM (arm64) ami-0e2bf1dcbe15b6269 Launch Stack
    sa-east-1 HVM (amd64) ami-0c0f1286ebdbe11be Launch Stack
    HVM (arm64) ami-07d4f3a6ef02ba008 Launch Stack
    us-east-1 HVM (amd64) ami-01dbacc5d7f623ef1 Launch Stack
    HVM (arm64) ami-0c2e9d254b450a823 Launch Stack
    us-east-2 HVM (amd64) ami-0036fb59b1a3d4e57 Launch Stack
    HVM (arm64) ami-0d83fbab14a0bf371 Launch Stack
    us-west-1 HVM (amd64) ami-0ae9d555b50216318 Launch Stack
    HVM (arm64) ami-085cc4f46e4cbd4e8 Launch Stack
    us-west-2 HVM (amd64) ami-06a3c3af393774fbd Launch Stack
    HVM (arm64) ami-0d0ab6da4b92f0fd8 Launch Stack

    Butane Configs

    Flatcar Container Linux allows you to configure machine parameters, configure networking, launch systemd units on startup, and more via Butane Configs. These configs are then transpiled into Ignition configs and given to booting machines. Head over to the docs to learn about the supported features .

    You can provide a raw Ignition JSON config to Flatcar Container Linux via the Amazon web console or via the EC2 API .

    As an example, this Butane YAML config will start an NGINX Docker container:

    variant: flatcar
    version: 1.0.0
    systemd:
      units:
        - name: nginx.service
          enabled: true
          contents: |
            [Unit]
            Description=NGINX example
            After=docker.service
            Requires=docker.service
            [Service]
            TimeoutStartSec=0
            ExecStartPre=-/usr/bin/docker rm --force nginx1
            ExecStart=/usr/bin/docker run --name nginx1 --pull always --log-driver=journald --net host docker.io/nginx:1
            ExecStop=/usr/bin/docker stop nginx1
            Restart=always
            RestartSec=5s
            [Install]
            WantedBy=multi-user.target
    

    Transpile it to Ignition JSON:

    cat cl.yaml | docker run --rm -i quay.io/coreos/butane:latest > ignition.json
    

    Instance storage

    Ephemeral disks and additional EBS volumes attached to instances can be mounted with a .mount unit. Amazon’s block storage devices are attached differently depending on the instance type . Here’s the Butane Config to format and mount the first ephemeral disk, xvdb, on most instance types:

    variant: flatcar
    version: 1.0.0
    storage:
      filesystems:
        - device: /dev/xvdb
          format: ext4
          wipe_filesystem: true
          label: ephemeral
    systemd:
      units:
        - name: media-ephemeral.mount
          enabled: true
          contents: |
            [Mount]
            What=/dev/disk/by-label/ephemeral
            Where=/media/ephemeral
            Type=ext4
    
            [Install]
            RequiredBy=local-fs.target
    

    For more information about mounting storage, Amazon’s own documentation is the best source. You can also read about mounting storage on Flatcar Container Linux .

    Adding more machines

    To add more instances to the cluster, just launch more with the same Butane Config, the appropriate security group and the AMI for that region. New instances will join the cluster regardless of region if the security groups are configured correctly.

    SSH to your instances

    Flatcar Container Linux is set up to be a little more secure than other cloud images. By default, it uses the core user instead of root and doesn’t use a password for authentication. You’ll need to add an SSH key(s) via the AWS console or add keys/passwords via your Butane Config in order to log in.

    To connect to an instance after it’s created, run:

    ssh core@<ip address>
    

    Multiple clusters

    If you would like to create multiple clusters you will need to change the “Stack Name”. You can find the direct template file on S3 .

    Manual setup

    TL;DR: launch three instances of ami-03e30902e328b1672 (amd64) in us-east-1 with a security group that has open port 22, 2379, 2380, 4001, and 7001 and the same “User Data” of each host. SSH uses the core user and you have etcd and Docker to play with.

    Creating the security group

    You need open port 2379, 2380, 7001 and 4001 between servers in the etcd cluster. Step by step instructions below.

    Note: This step is only needed once

    First we need to create a security group to allow Flatcar Container Linux instances to communicate with one another.

    1. Go to the security group page in the EC2 console.
    2. Click “Create Security Group”
      • Name: flatcar-testing
      • Description: Flatcar Container Linux instances
      • VPC: No VPC
      • Click: “Yes, Create”
    3. In the details of the security group, click the Inbound tab
    4. First, create a security group rule for SSH
      • Create a new rule: SSH
      • Source: 0.0.0.0/0
      • Click: “Add Rule”
    5. Add two security group rules for etcd communication
      • Create a new rule: Custom TCP rule
      • Port range: 2379
      • Source: type “flatcar-testing” until your security group auto-completes. Should be something like “sg-8d4feabc”
      • Click: “Add Rule”
      • Repeat this process for port range 2380, 4001 and 7001 as well
    6. Click “Apply Rule Changes”

    Launching a test cluster

    We will be launching three instances, with a few parameters in the User Data, and selecting our security group.

    • Open the quick launch wizard to boot: Alpha ami-03e30902e328b1672 (amd64), Beta ami-0d0866f5dcbc1b106 (amd64), or Stable ami-014b11e8a5507c680 (amd64)
    • On the second page of the wizard, launch 3 servers to test our clustering
      • Number of instances: 3, “Continue”
    • Paste your Ignition JSON config in the EC2 dashboard into the “User Data” field, “Continue”
    • Storage Configuration, “Continue”
    • Tags, “Continue”
    • Create Key Pair: Choose a key of your choice, it will be added in addition to the one in the gist, “Continue”
    • Choose one or more of your existing Security Groups: “flatcar-testing” as above, “Continue”
    • Launch!

    Installation from a VMDK image

    One of the possible ways of installation is to import the generated VMDK Flatcar image as a snapshot. The image file will be in https://${CHANNEL}.release.flatcar-linux.net/${ARCH}-usr/${VERSION}/flatcar_production_ami_vmdk_image.vmdk.bz2. Make sure you download the signature (it’s available in https://${CHANNEL}.release.flatcar-linux.net/${ARCH}-usr/${VERSION}/flatcar_production_ami_vmdk_image.vmdk.bz2.sig) and check it before proceeding.

    $ wget https://alpha.release.flatcar-linux.net/amd64-usr/current/flatcar_production_ami_vmdk_image.vmdk.bz2
    $ wget https://alpha.release.flatcar-linux.net/amd64-usr/current/flatcar_production_ami_vmdk_image.vmdk.bz2.sig
    $ gpg --verify flatcar_production_ami_vmdk_image.vmdk.bz2.sig
    gpg: assuming signed data in 'flatcar_production_ami_vmdk_image.vmdk.bz2'
    gpg: Signature made Thu 15 Mar 2018 10:27:57 AM CET
    gpg:                using RSA key A621F1DA96C93C639506832D603443A1D0FC498C
    gpg: Good signature from "Flatcar Buildbot (Official Builds) <[email protected]>" [ultimate]
    

    Then, follow the instructions in Importing a Disk as a Snapshot Using VM Import/Export . You’ll need to upload the uncompressed vmdk file to S3.

    After the snapshot is imported, you can go to “Snapshots” in the EC2 dashboard, and generate an AMI image from it. To make it work, use /dev/sda2 as the “Root device name” and you probably want to select “Hardware-assisted virtualization” as “Virtualization type”.

    Using Flatcar Container Linux

    Now that you have a machine booted it is time to play around. Check out the Flatcar Container Linux Quickstart guide or dig into more specific topics .

    Terraform

    The aws Terraform Provider allows to deploy machines in a declarative way. Read more about using Terraform and Flatcar here .

    The following Terraform v0.13 module may serve as a base for your own setup. It will also take care of registering your SSH key at AWS EC2 and managing the network environment with Terraform.

    You can clone the setup from the Flatcar Terraform examples repository or create the files manually as we go through them and explain each one.

    git clone https://github.com/flatcar/flatcar-terraform.git
    # From here on you could directly run it, TLDR:
    cd aws
    export AWS_ACCESS_KEY_ID=...
    export AWS_SECRET_ACCESS_KEY=...
    terraform init
    # Edit the server configs or just go ahead with the default example
    terraform plan
    terraform apply
    

    Start with a aws-ec2-machines.tf file that contains the main declarations:

    terraform {
      required_version = ">= 0.13"
      required_providers {
        ct = {
          source  = "poseidon/ct"
          version = "0.7.1"
        }
        template = {
          source  = "hashicorp/template"
          version = "~> 2.2.0"
        }
        null = {
          source  = "hashicorp/null"
          version = "~> 3.0.0"
        }
        aws = {
          source  = "hashicorp/aws"
          version = "~> 3.19.0"
        }
      }
    }
    
    provider "aws" {
      region = var.aws_region
    }
    
    resource "aws_vpc" "network" {
      cidr_block = var.vpc_cidr
    
      tags = {
        Name = var.cluster_name
      }
    }
    
    resource "aws_subnet" "subnet" {
      vpc_id     = aws_vpc.network.id
      cidr_block = var.subnet_cidr
    
      tags = {
        Name = var.cluster_name
      }
    }
    
    resource "aws_internet_gateway" "gateway" {
      vpc_id = aws_vpc.network.id
    
      tags = {
        Name = var.cluster_name
      }
    }
    
    resource "aws_route_table" "default" {
      vpc_id = aws_vpc.network.id
    
      route {
        cidr_block = "0.0.0.0/0"
        gateway_id = aws_internet_gateway.gateway.id
      }
    
      tags = {
        Name = var.cluster_name
      }
    }
    
    resource "aws_route_table_association" "public" {
      route_table_id = aws_route_table.default.id
      subnet_id      = aws_subnet.subnet.id
    }
    
    resource "aws_security_group" "securitygroup" {
      vpc_id = aws_vpc.network.id
    
      tags = {
        Name = var.cluster_name
      }
    }
    
    resource "aws_security_group_rule" "outgoing_any" {
      security_group_id = aws_security_group.securitygroup.id
      type              = "egress"
      from_port         = 0
      to_port           = 0
      protocol          = "-1"
      cidr_blocks       = ["0.0.0.0/0"]
    }
    
    resource "aws_security_group_rule" "incoming_any" {
      security_group_id = aws_security_group.securitygroup.id
      type              = "ingress"
      from_port         = 0
      to_port           = 0
      protocol          = "-1"
      cidr_blocks       = ["0.0.0.0/0"]
    }
    
    resource "aws_key_pair" "ssh" {
      key_name   = var.cluster_name
      public_key = var.ssh_keys.0
    }
    
    data "aws_ami" "flatcar_stable_latest" {
      most_recent = true
      owners      = ["aws-marketplace"]
    
      filter {
        name   = "architecture"
        values = ["x86_64"]
      }
    
      filter {
        name   = "virtualization-type"
        values = ["hvm"]
      }
    
      filter {
        name   = "name"
        values = ["Flatcar-stable-*"]
      }
    }
    
    resource "aws_instance" "machine" {
      for_each      = toset(var.machines)
      instance_type = var.instance_type
      user_data     = data.ct_config.machine-ignitions[each.key].rendered
      ami           = data.aws_ami.flatcar_stable_latest.image_id
      key_name      = aws_key_pair.ssh.key_name
    
      associate_public_ip_address = true
      subnet_id                   = aws_subnet.subnet.id
      vpc_security_group_ids      = [aws_security_group.securitygroup.id]
    
      tags = {
        Name = "${var.cluster_name}-${each.key}"
      }
    }
    
    data "ct_config" "machine-ignitions" {
      for_each = toset(var.machines)
      content  = data.template_file.machine-configs[each.key].rendered
    }
    
    data "template_file" "machine-configs" {
      for_each = toset(var.machines)
      template = file("${path.module}/cl/machine-${each.key}.yaml.tmpl")
    
      vars = {
        ssh_keys = jsonencode(var.ssh_keys)
        name     = each.key
      }
    }
    

    Create a variables.tf file that declares the variables used above:

    variable "machines" {
      type        = list(string)
      description = "Machine names, corresponding to cl/machine-NAME.yaml.tmpl files"
    }
    
    variable "cluster_name" {
      type        = string
      description = "Cluster name used as prefix for the machine names"
    }
    
    variable "ssh_keys" {
      type        = list(string)
      description = "SSH public keys for user 'core'"
    }
    
    variable "aws_region" {
      type        = string
      default     = "us-east-2"
      description = "AWS Region to use for running the machine"
    }
    
    variable "instance_type" {
      type        = string
      default     = "t3.medium"
      description = "Instance type for the machine"
    }
    
    variable "vpc_cidr" {
      type    = string
      default = "172.16.0.0/16"
    }
    
    variable "subnet_cidr" {
      type    = string
      default = "172.16.10.0/24"
    }
    

    An outputs.tf file shows the resulting IP addresses:

    output "ip-addresses" {
      value = {
        for key in var.machines :
        "${var.cluster_name}-${key}" => aws_instance.machine[key].public_ip
      }
    }
    

    Now you can use the module by declaring the variables and a Container Linux Configuration for a machine. First create a terraform.tfvars file with your settings:

    cluster_name           = "mycluster"
    machines               = ["mynode"]
    ssh_keys               = ["ssh-rsa AA... [email protected]"]
    

    The machine name listed in the machines variable is used to retrieve the corresponding Container Linux Config . For each machine in the list, you should have a machine-NAME.yaml.tmpl file with a corresponding name.

    For example, create the configuration for mynode in the file machine-mynode.yaml.tmpl (The SSH key used there is not really necessary since we already set it as VM attribute):

    ---
    passwd:
      users:
        - name: core
          ssh_authorized_keys:
            - ${ssh_keys}
    storage:
      files:
        - path: /home/core/works
          filesystem: root
          mode: 0755
          contents:
            inline: |
              #!/bin/bash
              set -euo pipefail
               # This script demonstrates how templating and variable substitution works when using Terraform templates for Container Linux Configs.
              hostname="$(hostname)"
              echo My name is ${name} and the hostname is $${hostname}
    

    Finally, run Terraform v0.13 as follows to create the machine:

    export AWS_ACCESS_KEY_ID=...
    export AWS_SECRET_ACCESS_KEY=...
    terraform init
    terraform apply
    

    Log in via ssh core@IPADDRESS with the printed IP address (maybe add -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null).

    When you make a change to machine-mynode.yaml.tmpl and run terraform apply again, the machine will be replaced.

    You can find this Terraform module in the repository for Flatcar Terraform examples .