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 Discord server 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.3.

    View as json feed: amd64 arm64
    EC2 Region AMI Type AMI ID CloudFormation
    af-south-1 HVM (amd64) ami-036c1422a6ccdead2 Launch Stack
    HVM (arm64) ami-026079c67728435a8 Launch Stack
    ap-east-1 HVM (amd64) ami-0aaa1e3b70b410fbe Launch Stack
    HVM (arm64) ami-09347d764f7547450 Launch Stack
    ap-northeast-1 HVM (amd64) ami-0a56d11c8d5e8e4c4 Launch Stack
    HVM (arm64) ami-009c58e0022d87144 Launch Stack
    ap-northeast-2 HVM (amd64) ami-0c2792579ba01cbe8 Launch Stack
    HVM (arm64) ami-0c543e1c714fc7916 Launch Stack
    ap-south-1 HVM (amd64) ami-08a6e3d505e10e18f Launch Stack
    HVM (arm64) ami-05e44b3db99df7178 Launch Stack
    ap-southeast-1 HVM (amd64) ami-09919883d72397df5 Launch Stack
    HVM (arm64) ami-072bcfae51e30e7d2 Launch Stack
    ap-southeast-2 HVM (amd64) ami-0a5fb018a986a52d4 Launch Stack
    HVM (arm64) ami-00eddf835b3d0350d Launch Stack
    ap-southeast-3 HVM (amd64) ami-0b05129b61ac2206d Launch Stack
    HVM (arm64) ami-022e98452fb6bbcd2 Launch Stack
    ca-central-1 HVM (amd64) ami-04232814c814b093c Launch Stack
    HVM (arm64) ami-0ad6577e62df8e1e3 Launch Stack
    eu-central-1 HVM (amd64) ami-09e1dc8e789f662e1 Launch Stack
    HVM (arm64) ami-08a554ef591f159e2 Launch Stack
    eu-north-1 HVM (amd64) ami-09c7ac330c15acb1c Launch Stack
    HVM (arm64) ami-0c3a22bd42b5ec4b6 Launch Stack
    eu-south-1 HVM (amd64) ami-03446d88c22b62fc3 Launch Stack
    HVM (arm64) ami-05b423cdfdeca186a Launch Stack
    eu-west-1 HVM (amd64) ami-0d2dd6d08b24f76cb Launch Stack
    HVM (arm64) ami-0565efd77a955ad29 Launch Stack
    eu-west-2 HVM (amd64) ami-0d1149fc3aa67000c Launch Stack
    HVM (arm64) ami-0d1d5495eb3fd1122 Launch Stack
    eu-west-3 HVM (amd64) ami-07ccbf5b36a52d063 Launch Stack
    HVM (arm64) ami-02173402feece3077 Launch Stack
    sa-east-1 HVM (amd64) ami-026de5b7049ba69a5 Launch Stack
    HVM (arm64) ami-04158743e9e5f5e7d Launch Stack
    us-east-1 HVM (amd64) ami-0defcddfcd325fb1b Launch Stack
    HVM (arm64) ami-02807d9e71a69934c Launch Stack
    us-east-2 HVM (amd64) ami-0fdeafbcf9739b626 Launch Stack
    HVM (arm64) ami-06c7798efb6231748 Launch Stack
    us-west-1 HVM (amd64) ami-07b879c3a3720bf65 Launch Stack
    HVM (arm64) ami-0cfd44a0172026f04 Launch Stack
    us-west-2 HVM (amd64) ami-0ca01755a9970e8a2 Launch Stack
    HVM (arm64) ami-0a7166a970b570f2a Launch Stack

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

    View as json feed: amd64 arm64
    EC2 Region AMI Type AMI ID CloudFormation
    af-south-1 HVM (amd64) ami-0f12b0a0e1d17d4d9 Launch Stack
    HVM (arm64) ami-0fff5b4359dbf40bc Launch Stack
    ap-east-1 HVM (amd64) ami-016bb5415ed736408 Launch Stack
    HVM (arm64) ami-0816f2a3afb7e0a86 Launch Stack
    ap-northeast-1 HVM (amd64) ami-04dafe2f33c2f6d0d Launch Stack
    HVM (arm64) ami-03ecae872ac7b16ff Launch Stack
    ap-northeast-2 HVM (amd64) ami-0ef5ecb94fb5c9fe2 Launch Stack
    HVM (arm64) ami-05be1c7a18b08cf17 Launch Stack
    ap-south-1 HVM (amd64) ami-01197a12cc6442390 Launch Stack
    HVM (arm64) ami-02550d783084c35f6 Launch Stack
    ap-southeast-1 HVM (amd64) ami-0adeb450c2bfa02ca Launch Stack
    HVM (arm64) ami-0657eedde11a7371c Launch Stack
    ap-southeast-2 HVM (amd64) ami-0049cc214ca77b696 Launch Stack
    HVM (arm64) ami-049b1d71c0ff3ded6 Launch Stack
    ap-southeast-3 HVM (amd64) ami-04ae60f1132dc04b4 Launch Stack
    HVM (arm64) ami-024b6d295f8342287 Launch Stack
    ca-central-1 HVM (amd64) ami-0827e8eb1723cfe5d Launch Stack
    HVM (arm64) ami-07559078b43992b5f Launch Stack
    eu-central-1 HVM (amd64) ami-00eac95271746ab23 Launch Stack
    HVM (arm64) ami-06bddbf17724f5c4d Launch Stack
    eu-north-1 HVM (amd64) ami-0da483ae7cd37a1b2 Launch Stack
    HVM (arm64) ami-090b55eb54bc30438 Launch Stack
    eu-south-1 HVM (amd64) ami-0e13806787ba21345 Launch Stack
    HVM (arm64) ami-0db611235fce385d5 Launch Stack
    eu-west-1 HVM (amd64) ami-0ae39cd8c390744c0 Launch Stack
    HVM (arm64) ami-09ad93256c256a41e Launch Stack
    eu-west-2 HVM (amd64) ami-0af49ec3c5008344b Launch Stack
    HVM (arm64) ami-065fda6b078e9e813 Launch Stack
    eu-west-3 HVM (amd64) ami-0eac0523df01313fc Launch Stack
    HVM (arm64) ami-03d9da51cb3f91bc7 Launch Stack
    sa-east-1 HVM (amd64) ami-076c020986d0e5fc7 Launch Stack
    HVM (arm64) ami-069d960d747a8d71d Launch Stack
    us-east-1 HVM (amd64) ami-0b4c1eb7e85036a6f Launch Stack
    HVM (arm64) ami-05156e70d240dbf60 Launch Stack
    us-east-2 HVM (amd64) ami-0b08af0407b4af589 Launch Stack
    HVM (arm64) ami-007c650fd1445ab04 Launch Stack
    us-west-1 HVM (amd64) ami-02e926de888acbff1 Launch Stack
    HVM (arm64) ami-067b59e48a9227b6b Launch Stack
    us-west-2 HVM (amd64) ami-04bb017ae22aba3de Launch Stack
    HVM (arm64) ami-0ea56157203482745 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 4722.0.0.

    View as json feed: amd64 arm64
    EC2 Region AMI Type AMI ID CloudFormation
    af-south-1 HVM (amd64) ami-005c41c16e6cdcd6d Launch Stack
    HVM (arm64) ami-0ecd85e2d0d25c259 Launch Stack
    ap-east-1 HVM (amd64) ami-07582280e7cb78664 Launch Stack
    HVM (arm64) ami-09e4f44e92eb40a9a Launch Stack
    ap-northeast-1 HVM (amd64) ami-0eb79067dc9d8ee33 Launch Stack
    HVM (arm64) ami-0b7fa1f3a1d2aceb3 Launch Stack
    ap-northeast-2 HVM (amd64) ami-0ed3f72c53c052e9e Launch Stack
    HVM (arm64) ami-006725a8bf1a57e21 Launch Stack
    ap-south-1 HVM (amd64) ami-0a8c5c84a5530041a Launch Stack
    HVM (arm64) ami-0da3c0212fc0f5d2e Launch Stack
    ap-southeast-1 HVM (amd64) ami-084b1dfa7cd3cd3d0 Launch Stack
    HVM (arm64) ami-021833882c5ff6284 Launch Stack
    ap-southeast-2 HVM (amd64) ami-0723ca18ef30f12e4 Launch Stack
    HVM (arm64) ami-0c3c26da5bc338da7 Launch Stack
    ap-southeast-3 HVM (amd64) ami-0da004bb40b70025c Launch Stack
    HVM (arm64) ami-012c117d6ef5ad143 Launch Stack
    ca-central-1 HVM (amd64) ami-0bb2803a1ea984497 Launch Stack
    HVM (arm64) ami-0e67d68eab3535949 Launch Stack
    eu-central-1 HVM (amd64) ami-0fc5f1a06aaa596f6 Launch Stack
    HVM (arm64) ami-01edf849934b89fab Launch Stack
    eu-north-1 HVM (amd64) ami-0657a42365fbdac99 Launch Stack
    HVM (arm64) ami-08dd12fb215a0b99c Launch Stack
    eu-south-1 HVM (amd64) ami-0fc94c374d61f28ee Launch Stack
    HVM (arm64) ami-08e47846f115e21be Launch Stack
    eu-west-1 HVM (amd64) ami-0d475ef0f4effcbec Launch Stack
    HVM (arm64) ami-062b54606d615b42d Launch Stack
    eu-west-2 HVM (amd64) ami-07c767176bc46e132 Launch Stack
    HVM (arm64) ami-0cc1224c32db4a3f7 Launch Stack
    eu-west-3 HVM (amd64) ami-0ae1b361b4be2dd20 Launch Stack
    HVM (arm64) ami-0d6b1c74155a69163 Launch Stack
    sa-east-1 HVM (amd64) ami-07e77fed6b1bff116 Launch Stack
    HVM (arm64) ami-0868a0f8d052bd96f Launch Stack
    us-east-1 HVM (amd64) ami-0e2a3997e3e6ae944 Launch Stack
    HVM (arm64) ami-0fe5e5b9b64a504dc Launch Stack
    us-east-2 HVM (amd64) ami-04060cebed92ebeea Launch Stack
    HVM (arm64) ami-0e9068875540bbb6c Launch Stack
    us-west-1 HVM (amd64) ami-068db5eab82823bae Launch Stack
    HVM (arm64) ami-031bb76c0c776c003 Launch Stack
    us-west-2 HVM (amd64) ami-069e0fa52deeae4b4 Launch Stack
    HVM (arm64) ami-0e76d9fbc756e94f0 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.8.

    View as json feed: amd64 arm64
    EC2 Region AMI Type AMI ID CloudFormation
    af-south-1 HVM (amd64) ami-002faba1299c9d171 Launch Stack
    HVM (arm64) ami-0f85e291c3ba8da2b Launch Stack
    ap-east-1 HVM (amd64) ami-0ec58fd9f3e175892 Launch Stack
    HVM (arm64) ami-0e22ec3d91149b445 Launch Stack
    ap-northeast-1 HVM (amd64) ami-0ab5fcc5c3eba9142 Launch Stack
    HVM (arm64) ami-09584b3e7880b8163 Launch Stack
    ap-northeast-2 HVM (amd64) ami-02bf78fccd8858eb1 Launch Stack
    HVM (arm64) ami-0635743e467a54117 Launch Stack
    ap-south-1 HVM (amd64) ami-0666dc95f12549115 Launch Stack
    HVM (arm64) ami-0904c395fcfd25b2e Launch Stack
    ap-southeast-1 HVM (amd64) ami-091bbac1c17623999 Launch Stack
    HVM (arm64) ami-01b54ed5c11c0f1a1 Launch Stack
    ap-southeast-2 HVM (amd64) ami-0d81b8654d5a95a36 Launch Stack
    HVM (arm64) ami-071dcefe0c6f8f182 Launch Stack
    ap-southeast-3 HVM (amd64) ami-0fffaad53f287cf8b Launch Stack
    HVM (arm64) ami-0bd5be8bb1eb8217f Launch Stack
    ca-central-1 HVM (amd64) ami-076253f7aaeb99fbd Launch Stack
    HVM (arm64) ami-0f0fe3c60ee457abe Launch Stack
    eu-central-1 HVM (amd64) ami-00941fd85c51de87d Launch Stack
    HVM (arm64) ami-0f09843d1dbda294d Launch Stack
    eu-north-1 HVM (amd64) ami-03220e081ea889aa1 Launch Stack
    HVM (arm64) ami-0f092ecdeffd26012 Launch Stack
    eu-south-1 HVM (amd64) ami-0b8a9ecaea16b551a Launch Stack
    HVM (arm64) ami-0e332b4c9d789af7b Launch Stack
    eu-west-1 HVM (amd64) ami-07c9286169c417e10 Launch Stack
    HVM (arm64) ami-04a74ac87bffc879c Launch Stack
    eu-west-2 HVM (amd64) ami-0bc4c32639f21ced7 Launch Stack
    HVM (arm64) ami-08c259e5d6e8b1a58 Launch Stack
    eu-west-3 HVM (amd64) ami-087ffeb3e8f475aff Launch Stack
    HVM (arm64) ami-0691947d196014530 Launch Stack
    sa-east-1 HVM (amd64) ami-0ed97e413812ec601 Launch Stack
    HVM (arm64) ami-0e80a790f81ce789f Launch Stack
    us-east-1 HVM (amd64) ami-041cf8d6efa04375b Launch Stack
    HVM (arm64) ami-0e4b99bc7e84efe61 Launch Stack
    us-east-2 HVM (amd64) ami-0f8e0d863a34e02d4 Launch Stack
    HVM (arm64) ami-0f104b58b1f1b8587 Launch Stack
    us-west-1 HVM (amd64) ami-0f2c9d46a362171e1 Launch Stack
    HVM (arm64) ami-0df0131e021246566 Launch Stack
    us-west-2 HVM (amd64) ami-0cfeb0bc5774c945a Launch Stack
    HVM (arm64) ami-0fafe1a64e8c3eebf 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-0e2a3997e3e6ae944 (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-0e2a3997e3e6ae944 (amd64), Beta ami-0b4c1eb7e85036a6f (amd64), or Stable ami-0defcddfcd325fb1b (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 .