0

We are working on a code that does the following using terraform (on AWS):

  1. Creates a core-os instance (1) with the cloud-config yaml file we provided
  2. Creates an AMI from that instance

The process works perfectly fine up till here.

When we launch an instance (2) from that AMI, through AWS console. The newly launched instance does not use the cloud-config file.

It (2) has services/systemd units that were created in the instance (1) through the cloud-config yaml file. But those services are dead. They work perfectly fine if we start them explicitly using systemctl

How do we make sure that ANY instance created from that AMI should have those services/systemd units started on startup or should load that cloud-config file?

(We have that cloud-config yaml saved at a location inside the machine too, if we run the cloud-config file manually through coreos-cloudinit --from-file=path/to/file/cloud-config.yaml, everything works perfectly fine. But we want it to work at startup without any manual step)

Here is our cloud-config file

#cloud-config
coreos:
  etcd2:
    # generate a new token for each unique cluster from https://discovery.etcd.io/new?size=3
    # specify the initial size of your cluster with ?size=X
    discovery: https://discovery.etcd.io/2cb27f1fecb57e14837016e04547aa32
    # multi-region and multi-cloud deployments need to use $public_ipv4
    advertise-client-urls: http://0.0.0.0:2379,http://0.0.0.0:4001
    initial-advertise-peer-urls: http://127.0.0.1:2380
    # listen on both the official ports and the legacy ports
    # legacy ports can be omitted if your application doesn't depend on them
    listen-client-urls: http://0.0.0.0:2379,http://0.0.0.0:4001
    listen-peer-urls: http://0.0.0.0:2380,http://0.0.0.0:7001
  units:
    - name: etcd2.service
      command: start
    - name: fleet.service
      command: start
    - name: hello.service
      command: start
      content: |
        [Unit]
        Description=hello_docker
        After=docker.service
        Requires=docker.service

        [Service]
        TimeoutStartSec=0
        ExecStartPre=-/usr/bin/docker rm busybox1
        ExecStartPre=/usr/bin/docker pull busybox
        ExecStart=/usr/bin/docker run --rm --name busybox1 busybox /bin/sh -c "while true; do echo Hello Docker; sleep 1; done"
        ExecStop=/usr/bin/docker stop busybox1
Hazim
  • 113
  • 7

2 Answers2

0

You shouldn't need to make your own AMI of a CoreOS box, just use the official CoreOS AMIs. Passing in the same cloud-config file to each box you want to create, and the units will be started. This makes your infrastructure more immutable than if you have to be snapshotting stuff.

Rob
  • 431
  • 2
  • 2
  • we're automating the whole process and its our requirement to do it that way. take a look at this: http://techblog.netflix.com/2016/03/how-we-build-code-at-netflix.html – Hazim Jun 02 '16 at 06:04
0

Thing I was missing was that, the first Instance (1) used a script as user-data which then ran the cloud-config through the cloud-init command.

Instead, I had to copy my cloud config in /usr/share/oem/ so that instance created by the AMI also use that cloud config by default.

Moreover, The following might help someone facing a similar issue, but it won't start on the first boot as mentioned.

You need to enable the services (make sure they have Install sections).

#cloud-config

coreos:
  units:
    - name: "example.service"
      enable: true
      content: |
        [Service]
        Type=oneshot
        ExecStart=/usr/bin/echo Hello World

        [Install]
        WantedBy=multi-user.target

This service won't start on the first boot (because the unit is enabled after systemd realizes multi-user.target) but it will run on subsequent boots.

Also, while taking a snapshot make sure you remove /etc/machine-id before. Otherwise, all of the machines will have the same ID.

reference: link

Hazim
  • 113
  • 7