I am trying to create a terraform that will create a windows server, linux machine in an aws vpc and then will save the Windows server and the admin password in a local file,
I Know that I will need the keypair in order to decrypt the password of the windows server, though, I am assuming that the indrastructure won’t have a key-pair on their end,
please find my terrform main.tf (as this is the only file for now):
### Creating a Dedicated VPC for the project
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
name = "Moc-Winsev"
cidr = "10.0.0.0/16"
azs = ["us-east-1a", "eu-east-1b"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
enable_nat_gateway = false
enable_vpn_gateway = false
tags = {
Terraform = "Yes"
Environment = "Dev"
}
}
### Creting windows server
module "ec2_instance" {
source = "terraform-aws-modules/ec2-instance/aws"
name = "windows-server"
instance_type = "t3a.xlarge"
key_name = "${aws_key_pair.kp.id}"
monitoring = false
vpc_security_group_ids = ["${module.windowserver_sg.security_group_id}"]
subnet_id = "${module.vpc.public_subnets[0]}"
ami = "ami-069c45f40acdfe41e"
tags = {
Terraform = "Yes"
Environment = "Dev"
}
}
## Creating Linux server
module "ec2_linux" {
source = "terraform-aws-modules/ec2-instance/aws"
name = "linux-instance"
instance_type = "t2.micro"
key_name = "${aws_key_pair.kp.id}"
monitoring = false
vpc_security_group_ids = ["${module.windowserver_sg.security_group_id}"]
subnet_id = "${module.vpc.public_subnets[0]}"
ami = "ami-05548f9cecf47b442"
tags = {
Terraform = "Yes"
Environment = "Dev"
}
}
#### Creating a Security Group that will allow RDP and SSH, Attaching this to both servers
module "windowserver_sg" {
source = "terraform-aws-modules/security-group/aws"
name = "windowserver"
description = "Security group made for moccing Windows server with forwarder"
vpc_id = "vpc-12345678"
ingress_cidr_blocks = ["0.0.0.0/0"]
ingress_rules = ["rdp-tcp", "ssh-tcp"]
}
##### Creating the Key Pair
resource "tls_private_key" "pk" {
algorithm = "RSA"
rsa_bits = 4096
}
resource "aws_key_pair" "kp" {
key_name = "winserver"
public_key = tls_private_key.pk.public_key_openssh
}
resource "local_file" "ssh_key" {
filename = "winserver.pem"
content = tls_private_key.pk.private_key_pem
}
#### Creating the Local file with all the credentials and details
resource "local_file" "needed_details" {
content = <<-EOT
Server IP:
${module.ec2_instance.public_ip}
Admin Password:
${rsadecrypt(module.ec2_instance.password_data, file("./${local_file.ssh_key.filename}"))}
EOT
filename = "./Windwos_details.txt"
depends_on = [ local_file.ssh_key ]
}
though, while trying to run (plan/apply) I get the follwing error:
╷
│ Error: Invalid function argument
│
│ on main.tf line 93, in resource "local_file" "needed_details":
│ 93: ${rsadecrypt(module.ec2_instance.password_data, file("./${local_file.ssh_key.filename}"))}
│ ├────────────────
│ │ while calling file(path)
│ │ local_file.ssh_key.filename is "winserver.pem"
│
│ Invalid value for "path" parameter: no file exists at "./winserver.pem"; this function works only with files that are distributed as part
│ of the configuration source code, so if this file will be created by a resource in this configuration you must instead obtain this result
│ from an attribute of that resource.
I was reading the error again and again but I don’t understand how to implement the requirement in my code, how should i obtain a result from an attribute of the local file resource,
I was searching online and didn’t find anything like that, so a reference will be helpful aswell
Thank you all!
2
Answers
So, after quite a while of thinking, the solution for my issue was basically to refer to the content of the file and not to the file itself and it seem to bypass the issue, and it sould look like this
now my problem is different which is that the password_data is no generated as it takes a while but this solution is easy by using a null resource or time_sleep
Thank you everyone for your help
You can’t do that. Your requirements have little sense. First you need to have a key, before you can create an instance using the key. You can’t do this the other way around.