Yup, it's that time of the year again when I talk about some issues I've had and couldn't find a solution on google so I wrote about it.
What is the problem?
If you're never used OVH and terraform, you'll know that standing up the instance using terraform is quite easy. But adding a second network adapter and getting that to get DHCP... No.
I've previously written about using cloud-init, see below, on local infrastructure.
But the difference here, is that the documentation is even worse!
I'm talking, like 3 different places saying something different.
If you're not here to read the entire blog, scroll to the bottom where I have the solution to getting cloud init to work on OVH
Let's start
So seeing as we're using terraform, our first call of action is to look at their documentation for cloud init, which uses a field called user_data
The part that annoys me here, is they make you use a provider called template_file
which is actually deprecated...
data "template_file" "user_data" {
template = file("../scripts/add-ssh-web-app.yaml")
}
so if you get an error like below, you're welcome
Provider registry.terraform.io/hashicorp/template v2.2.0 does not have a package available for your current platform, darwin_arm64.
I tried to run terraform in a docker container forcing amd64 (as I am on an M1 mac) - No luck :(
The resolution for this one was to use a new provider, called cloudinit_config
which looks a little something like this
data "cloudinit_config" "user_data" {
gzip = false
base64_encode = false
part {
content_type = "text/x-shellscript"
content = "baz"
filename = file("./cloudinit.cfg")
}
}
But for the life of me, could not get this working. I was passing it to the instance rendered.
I'd had enough and thought, well fuck this noise we can probably pass the file straight in... Surely?
user_data = file("./cloudinit.cfg")
This should work?
So I've tried it with the classic hello world
and it seemed to work.
Below is what ./cloudinit.cfg
looks like, if you're wondering
#cloud-config
runcmd:
- 'echo ============ Hello World ================'
Now on to the actual issue at hand - Network Interfaces
Because I am lazy I wont be doing a nifty for
loop, just going with a basic file that the instance calls.
Below is that file:
#cloud-config
runcmd:
- 'echo ============ Hello World ================'
network:
ethernets:
ens3:
dhcp4: true
ens4:
dhcp4: true
version: 2
I've saved this file as netplan.cfg
and kept the hello world, as this outputs to logs so hopefully, we can see if it actually applies or no!
It ran hello world, but the network interface ens4
isnt enabled and getting DHCP
:(
We can re-load our cloud init, whist logged in using
cloud-init -d init
Here's the error:
Looks like we need to fix the file
#cloud-config
write_files:
- path: /etc/cloud/cloud.cfg.d/99-custom-networking.cfg
permissions: '0644'
content: |
network: {config: disabled}
- path: /etc/netplan/my-new-config.yaml
permissions: '0644'
content: |
network:
version: 2
ethernets:
ens3:
dhcp4: true
ens4:
dhcp4: true
runcmd:
- rm /etc/netplan/50-cloud-init.yaml
- netplan generate
- netplan apply
- echo "=== hello === "
Becomes
#cloud-config
write_files:
- encoding: b64
content: bmV0d29yazoge2NvbmZpZzogZGlzYWJsZWR9Cg==
owner: root:root
path: /etc/cloud/cloud.cfg.d/99-custom-networking.cfg
permissions: '0644'
- encoding: b64
content: bmV0d29yazoKICBldGhlcm5ldHM6CiAgICBlbnMzOgogICAgICBkaGNwNDogdHJ1ZQogICAgZW5zNDoKICAgICAgZGhjcDQ6IHRydWUKICB2ZXJzaW9uOiAyCg==
owner: root:root
path: /etc/netplan/my-new-config.yaml
permissions: '0644'
runcmd:
- rm /etc/netplan/50-cloud-init.yaml
- netplan generate
- netplan apply
- echo "=== hello === "
final_message: "The system is finally up, after $UPTIME seconds"
And would you look at that, it worked!
The solution
- Base 64 encode both the new netplan file, and the disable auto-gen config file
- Use the above file
- Pull the file in under
user_data
netplan.yml
#cloud-config
write_files:
- encoding: b64
content: bmV0d29yazoge2NvbmZpZzogZGlzYWJsZWR9Cg==
owner: root:root
path: /etc/cloud/cloud.cfg.d/99-custom-networking.cfg
permissions: '0644'
- encoding: b64
content: bmV0d29yazoKICBldGhlcm5ldHM6CiAgICBlbnMzOgogICAgICBkaGNwNDogdHJ1ZQogICAgZW5zNDoKICAgICAgZGhjcDQ6IHRydWUKICB2ZXJzaW9uOiAyCg==
owner: root:root
path: /etc/netplan/my-new-config.yaml
permissions: '0644'
runcmd:
- rm /etc/netplan/50-cloud-init.yaml
- netplan generate
- netplan apply
- echo "=== hello === "
final_message: "The system is finally up, after $UPTIME seconds"
instance.tf
resource "openstack_compute_instance_v2" "zero-access" {
name = "zero-access"
flavor_name = "s1-2"
key_pair = openstack_compute_keypair_v2.key.name
image_name = "Ubuntu 18.04"
security_groups = [ "default" ]
user_data = file("./netplan.yml")
network {
name = "Ext-Net"
}
network {
name = openstack_networking_network_v2.vpc.name
}
This post is more of a brain dump than anything, hoping to help those with the issue I had: