user_data doesn't run after a terraform application

11/25/2020

I am working with Terraform to luanch an Ec2 instance, where I want to execute some commands. I put a bash file in user_data on aws_instance resource, but the file is not executed.

...
resource "aws_instance" "master" {
  ami           = lookup(var.amis, var.region)
  instance_type = var.master_instance_type
  key_name      = "id_rsa_sdtd"
  security_groups = [aws_security_group.SDTD_VPC_Security_Group.id]
  subnet_id = aws_subnet.SDTD_VPC_Subnet.id
  iam_instance_profile = "k8s-cluster-iam-master-role"
  user_data = file("./master_config.sh")

}
...

Terraform plan

...
 + tenancy                      = (known after apply)
 + user_data                    = "def16ed029e3ecb79f09f750c548beed53d7f60d"
 + volume_tags                  = (known after apply)
...

my bash file

#!/bin/bash
# Install kubeadm and Docker
sudo apt update && sudo apt -y upgrade
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
sudo bash -c 'echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" > /etc/apt/sources.list.d/kubernetes.list'
sudo apt update
sudo apt install -y docker-ce kubelet kubeadm kubectl
...
-- nalou
amazon-ec2
bash
kubernetes
terraform
ubuntu

1 Answer

11/25/2020

There is no word in your question confirming master_config.sh hasnt been executed.

Below line doesnt mean it hasnt been executed. If it doesnt work - you should definitely see a log /var/log/cloud-init-output.log as suggested in the comments + user_data = "def16ed029e3ecb79f09f750c548beed53d7f60d"

From the solutions that comes to my mind:

  • use full path in below format, not simple file("./master_config.sh"). Maybe you wrapped in incorrectly.
resource "aws_instance" "..." {
  user_data = "${file("/../../master_config.sh")}"
  ...
}
  • I would recommend you to use templates_file for such activities and then refer it in your configuration.
data "template_file" "user_data" {
  template = "${file("/../../master_config.sh")}"
  ...
}


resource "aws_instance" "master" {
  user_data = "${data.template_file.user_data.rendered}"
  ...
}
-- Vit
Source: StackOverflow