Reputation: 1854
I'm creating an aws_instance
resource and run a provisioner but the SSH connection is never successful.
Here is my resource code:
resource "aws_instance" "pos" {
ami = "ami-c58c1dd3"
instance_type = "m4.xlarge"
subnet_id = "${var.subnet_id_1}"
key_name = "${var.key_name}"
connection {
type = "ssh"
user = "ec2-user"
private_key = "${file(var.private_key_path)}"
host = "aws_instance.instance.private_ip"
}
provisioner "remote-exec" {
inline = [
"sudo yum install nginx -y",
"sudo service nginx start"
]
}
}
During creation I get the following output repeated over and over:
aws_instance.pos (remote-exec): Connecting to remote host via SSH...
aws_instance.pos (remote-exec): Host: aws_instance.insance.private_ip
aws_instance.pos (remote-exec): User: ec2-user
aws_instance.pos (remote-exec): Password: false
aws_instance.pos (remote-exec): Private key: true
aws_instance.pos (remote-exec): Certificate: false
aws_instance.pos (remote-exec): SSH Agent: false
aws_instance.pos (remote-exec): Checking Host Key: false
aws_instance.pos: Still creating... [40s elapsed]
The SSH connection is never successful and eventually I must kill the command. However the EC2 instance is successfully created and I can SSH into from my local machine using the private key (PEM file).
I've also tried using self.public_ip
in the host field, but that produced the same result. How can I connect to the EC2 instance and provision it during creation?
Upvotes: 1
Views: 9362
Reputation: 56997
You aren't correctly interpolating the IP address output so are just using a string literal of "aws_instance.insance.private_ip"
.
Instead you want to interpolate this by wrapping it in ${}
. Unfortunately, if you do that you'll then get an error from Terraform saying that it can't find the resource aws_instance.instance
because you haven't defined it. Instead you should use the self
keyword to access attributes from the resource directly:
resource "aws_instance" "pos" {
ami = "ami-c58c1dd3"
instance_type = "m4.xlarge"
subnet_id = "${var.subnet_id_1}"
key_name = "${var.key_name}"
connection {
type = "ssh"
user = "ec2-user"
private_key = "${file(var.private_key_path)}"
host = "${self.private_ip}"
}
provisioner "remote-exec" {
inline = [
"sudo yum install nginx -y",
"sudo service nginx start"
]
}
}
Upvotes: 3
Reputation: 3201
You can try using the below code. It's working for me. Terraform was able to connect to the instance after creating it and ran the commands.
resource "aws_instance" "pos" {
ami = "ami-c58c1dd3"
instance_type = "m4.xlarge"
subnet_id = "${var.subnet_id_1}"
key_name = "XYZ"
provisioner "remote-exec" {
connection {
type = "ssh"
user = "ec2-user"
host = "${aws_instance.pos.public_ip}"
private_key = "${file("<Absolute-Path-to-file>/XYZ.pem")}"
agent = false
timeout = "2m"
}
inline = [
"sudo yum install nginx -y",
"sudo service nginx start"
]
}
}
Make sure key_name should be matching with the private_key file. This is to make sure that you are using the same key while connecting the instance which you used while creating the instance.
One more thing, allow port 22 in your security group which is being used by your instance.
Upvotes: 1