In this example we'll generate a ssh key pair and use terraform to create the following resources. The goal is to be able to ssh to a bastion host and run a terraform provisioner to the private instance.
- Network
- VPC
- Public Subnet
- Private Subnet
- Internet Gateway
- Elastic IP
- Nat Gateway
- Route tables
- Route table associations
- Security groups (ingress ssh and egress all)
- Ec2
- keypair
- Bastion host (public Subnet)
- Private Instance (Private Subnet)
- Terraform cli installed
- AWS account with permissions to create the above resources
- Open Terminal
- Paste the text below
ssh-keygen -m PEM -f terraform_aws_bastion_ssh -N ''
This will create the new ssh key
- In the same Terminal paste the text below subsituting your aws access key and secret access key.
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
export AWS_DEFAULT_REGION=ca-central-1
Typically we don't commit the .tfvars file to version control. For ease:
- Run the following command in the same Terminal
cp terraform.tfvars.example terraform.tfvars
- Run the following commands in the same Terminal
terraform init
terraform validate
terraform plan
- Review the planned changes and run the following command
terraform apply
- When prompted type yes
You will see that after the bastion host has been provisioned, the private instance will then be provisioned. The terraform provisioner will connect to the private instance via the bastion host and run the inline scripts to setup the LAMP stack. See the code snippet below.
provisioner "remote-exec" {
inline = [
"sudo yum update -y",
"sudo amazon-linux-extras install -y lamp-mariadb10.2-php7.2 php7.2",
"cat /etc/system-release",
"sudo yum install -y httpd mariadb-server",
"sudo systemctl start httpd",
"sudo systemctl enable httpd",
"sudo systemctl is-enabled httpd"
]
}
connection {
host = self.private_ip
type = "ssh"
user = "ec2-user"
private_key = file(var.ssh_private_key_path)
bastion_host = aws_instance.my_bastion_instance.public_ip
bastion_host_key = file(var.ssh_public_key_path)
}
- Run the following commands in the same Terminal
terraform destroy
- When prompted type yes