skip to Main Content

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


  1. Chosen as BEST ANSWER

    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

    #### 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, local_file.ssh_key.content))} 
            EOT
      filename = "./Windwos_details.txt"
    
      depends_on = [ local_file.ssh_key ]
    }
    
    
    

    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


  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search