Terraform user_data, remote-exec & triggers
(example using aws ec2 instance)
user_data attribute is used to define custom initialization scripts or cloud-init scripts that are executed when launching an instance or a resource. This attribute is commonly used in cloud platform like AWS, Azure & Google Cloud.
remote-exec is a terraform provisioner that allows you to execute commands on a remote resource after it's created. This is commonly used with null_resource.
triggers are used to force recreation of a resource under certain conditions. One scenario can be to set trigger for stop/start an application or resource based on certain conditions.
We are going to demonstrate all three attributes by building an EC2 instance.
1.Below step creates a standard ec2 instance with user_data attribute for installing and starting an apache webserver. (Note: custom VPC, subnet is used in this case, we will go through this topic in another article )
# Step 1 - implement user_data
resource "aws_instance" "my_webserver" {
ami = var.my-ami
availability_zone = var.myaz
instance_type = var.my-instance-type
associate_public_ip_address = true
subnet_id = aws_subnet.my_subnet.id
vpc_security_group_ids = [aws_security_group.allow_ssh_http.id]
tags = {
Name = "${var.my-ec2-instance}"
}
user_data = <<-EOF
#!/bin/bash
sudo apt update
sudo apt install apache2 -y
echo "Hello from Srini" > /var/www/html/index.html
echo "Hi there !!"> /var/www/html/hi.html
echo "test webserver" > /var/www/html/test.html
sudo systemctl restart apache2
sudo systemctl enable apache2
EOF
}
Standard installation commands are written under user_data attribute which is represented within a <<-EOF ... EOF block.
Recommended by LinkedIn
2. null_resource is used for sending remote execution commands. In the below snippet, we establish a ssh connection using pem key with ec2 instance. using this provisioner commands can be passed to the instance like stopping apache instance or writing a log entry etc.
resource "null_resource" "test1" {
connection {
type = "ssh"
user = "ubuntu"
host = aws_instance.my_webserver.public_ip
private_key = file("C:\\terraform\\srini_ec2.pem")
}
provisioner "remote-exec" {
inline = ["echo 'Hello from Terraform ${timestamp()}' | sudo tee /var/www/html/test.html"]
}
}
In above snippet, two blocks are written, one for setting up ssh connection where a pem file is assigned to private_key. secondly, remote-exec provisioner used to pass comands in a list. Note, above command will execute once while setting up aws_instance.
3. trigger attribute is included in null_resource provisioner , based on the trigger condition, remote-exec command can be executed whenever terraform apply is issued.
resource "null_resource" "test1" {
triggers = {
always_run = "${timestamp()}"
}
...
In summary, user_data is primarily used for providing initialization scripts or cloud-init directives at instance launch.
remote-exec is used for running commands on a running instance after it has been created.
While user_data is more cloud-agnostic, remote-exec is often used in combination with cloud-specific provisioners.
Chief Information Officer | RHCI | SCI | Devops Consultant and Instructor | Ansible, Terraform, Kubernetes, CICD
1yKeep exploring more in DevOps
Keep it up