I have created a aws infrastructure with network acls, security group, subnets, etc [code attached at the bottom]. in the free tier. I have also established ssh connection with my ec2 instance and I can also download manually packages when logged to the instance.
However, since I want to fully utilize Terraform, I would like to pre-install some stuff while Terraform creates the instance.
The commands I want to execute are quite simple (install jdk, python, docker),
user_data= <<-EOF
#! /bin/bash
echo "Installing modules..."
sudo apt-get update
sudo apt-get install -y openjdk-8-jdk
sudo apt install -y python2.7 python-pip
sudo apt install -y docker.io
sudo systemctl start docker
sudo systemctl enable docker
pip install setuptools
echo "Modules installed via Terraform"
EOF
My first approach was to utilize user_data parameter. Even though ec2 instance has access to the internet, none of the modules specified have been installed. Then I utilized the remote-exec block along with the connection block provided by terraform. But as many of us experienced before, terraform can't establish a successful connection to host, giving back the following messages,
remote-exec block
connection {
type = "ssh"
host = aws_eip.prod_server_public_ip.public_ip //Error: host for provisioner cannot be empty -> https://github.com/hashicorp/terraform-provider-aws/issues/10977
user = "ubuntu"
private_key = "${chomp(tls_private_key.ssh_key_prod.private_key_pem)}"
timeout = "1m"
}
provisioner "remote-exec" {
inline = [
"echo 'Installing modules...'",
"sudo apt-get update",
"sudo apt-get install -y openjdk-8-jdk",
"sudo apt install -y python2.7 python-pip",
"sudo apt install -y docker.io",
"sudo systemctl start docker",
"sudo systemctl enable docker",
"pip install setuptools",
"echo 'Modules installed via Terraform'"
]
on_failure = fail
}
message of i/o timeout
Connecting to remote host via SSH...
module.virtual_machines.null_resource.install_modules (remote-exec): Host: 3.137.111.207
module.virtual_machines.null_resource.install_modules (remote-exec): User: ubuntu
module.virtual_machines.null_resource.install_modules (remote-exec): Password: false
module.virtual_machines.null_resource.install_modules (remote-exec): Private key: true
module.virtual_machines.null_resource.install_modules (remote-exec): Certificate: false
module.virtual_machines.null_resource.install_modules (remote-exec): SSH Agent: false
module.virtual_machines.null_resource.install_modules (remote-exec): Checking Host Key: false
module.virtual_machines.null_resource.install_modules (remote-exec): Target Platform: unix
timeout - last error: dial tcp 52.15.178.40:22: i/o timeout
One root of the problem that I could think of, is that I allow only 2 specific ip addresses to pass form the inbound routing of security group. So when terraform tries to connect it does so from an unknown ip to the security group. If that's the case, which is the IP address that would allow terraform to connect to my vm and pre-install packages?
Terraform code for the infrastructure.
/var/log/syslog
and/var/log/user-data.log
. Also, adding user-data to an existing EC2 instance doesn't really do anything. It is a script that runs when the server is created. – Mark B