I am using Terraform to provision an EC2 instance on AWS. The Terraform file is able to provision the EC2-instance, however, when it gets to the provisioner section of the script, I get the error "host for provisioner cannot be empty" despite the host value being labelled.
instance.tf file
resource "aws_key_pair" "dove-key" {
key_name = "dovekey"
public_key = file("dovekey.pub")
}
resource "aws_instance" "dove-inst" {
ami = var.AMIS[var.REGION]
instance_type = "t2.micro"
availability_zone = var.ZONE1
key_name = aws_key_pair.dove-key.key_name
subnet_id = "subnet-00a20e364a10aed04"
vpc_security_group_ids = ["sg-0ddc62a99b3e5d75d"]
tags = {
Name = "Dove-Instance"
Project = "Dove"
}
provisioner "file" {
source = "web.sh"
destination = "/tmp/web.sh"
connection {
type = "ssh"
user = var.USER
password = ""
private_key = file("dovekey")
host = self.public_ip
}
}
provisioner "remote-exec" {
inline = [
"chmod u+x /tmp/web.sh",
"sudo /tmp/web.sh"
]
connection {
type = "ssh"
user = var.USER
password = ""
private_key = file("dovekey")
host = self.public_ip
}
}
}
vars.tf file
variable "REGION" {
default = "us-west-1"
}
variable "ZONE1" {
default = "us-west-1b"
}
variable "AMIS" {
type = map(any)
default = {
us-west-1 = "ami-09ab9d570789dfdd4"
us-east-1 = "ami-0e8a34246278c21e4"
}
}
variable "USER" {
default = "ec2-user"
}
I expected the script to ran completely without error
2
Answers
I suspect the issue is that the EC2 instance being launched is not allocated a public IP address (most likely due to subnet settings) therefore
self.public_ip
does not evaluate to a valid address, and thus terraform errors out.Fix your subnet so that the instance is given a public ip address.
You’re going to have tons of problems using a remote provisioner like this. Provisioners in Terraform are a "last resort" that you should only use if nothing else works. It is much more reliable to place those two commands in an EC2 User Data script.