In one of previous posts we deployed Linux Amazon instance using Terraform, now we’ll deploy Windows Server. Unlike previous approach, now we’ll store AWS Access Keys in separate file.
I created terraform.tfvars and stored keys there
AWS_ACCESS_KEY="some key"
AWS_SECRET_KEY="some keys"
INSTANCE_PASSWORD="Passw0rd012345"
There i also put Windows Server password
File vars.tf contains variable and AMIs
variable "AWS_ACCESS_KEY" {}
variable "AWS_SECRET_KEY" {}
variable "AWS_REGION" {
default = "eu-west-1"
}
variable "WIN_AMIS" {
type = "map" default = {
us-east-1 = "ami-30540427"
us-west-2 = "ami-9f5efbff"
eu-west-1 = "ami-0f26101934dec146b"
}
}
variable "PATH_TO_PRIVATE_KEY" { default = "mykey" }
variable "PATH_TO_PUBLIC_KEY" { default = "mykey.pub"
}
variable "INSTANCE_USERNAME" { default = "admin" }
variable "INSTANCE_PASSWORD" { }
In order to find out Window server AMI in AWS console go to EC2-Launch instance-Community AMIs, in search box type Windows, scroll until you find desired image and locate AMI-put that value into vars.tf
in provider.tf i put reference to terraform.tfvars
provider "aws" {
access_key = "${var.AWS_ACCESS_KEY}"
secret_key = "${var.AWS_SECRET_KEY}"
region = "${var.AWS_REGION}" }
terraform {
required_version = ">= 0.12"
}
In windows-instance.tf is code for deploying Windows server:
resource "aws_key_pair" "mykey" {
key_name = "mykey"
public_key = file(var.PATH_TO_PUBLIC_KEY)
}
data "template_file" "userdata_win" {
template = <<EOF
<script>
echo "" > _INIT_STARTED_
net user ${var.INSTANCE_USERNAME} /add /y
net user ${var.INSTANCE_USERNAME} ${var.INSTANCE_PASSWORD}
net localgroup administrators ${var.INSTANCE_USERNAME} /add
echo ${base64encode(file("./test.txt"))} > tmp2.b64 && certutil -decode tmp2.b64 C:/test.txt
echo "" > _INIT_COMPLETE_
</script>
<persist>false</persist>
EOF
}
resource "aws_instance" "win-example" {
ami = var.WIN_AMIS[var.AWS_REGION]
instance_type = "t2.micro"
key_name = aws_key_pair.mykey.key_name
user_data = data.template_file.userdata_win.rendered
vpc_security_group_ids=["${aws_security_group.allow-all.id}"]
tags = {
Name = "Windows_Server"
}
}
output "ip" {
value="${aws_instance.win-example.public_ip}"
}
It will create key pair, set AMI, create security group and add EC2 instance to it.
In template_file
section, new local windows user will be created named terraform, and added to local administrators group, also local file test.txt will be copied to ec2 instance to C drive.
File sg.tf contain security group definition, i just allowed traffic to all ports from anywhere (not a good security practice)
resource "aws_security_group" "allow-all" {
name="allow-all"
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 0
to_port = 6556
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "allow_RDP"
}
}
Create key pair:
ssh-keygen -f mykey
Now test for errors and apply configuration :
terraform init && terraform plan && terraform apply
hi i follwed this code as it is but i could not spin up up an instance please guide me how to connect to this instance also
LikeLiked by 1 person
errors ?
LikeLiked by 1 person
Error: Unknown root level key: user_data
LikeLiked by 1 person
Check did you copy all lines in windows.tf file, just checked myself and it works
LikeLiked by 2 people
It does not work for me, well at least not completely.
aws_instance.win-example: Still creating… (9m30s elapsed)
aws_instance.win-example: Still creating… (9m40s elapsed)
aws_instance.win-example: Still creating… (9m50s elapsed)
aws_instance.win-example: Still creating… (10m0s elapsed)
aws_instance.win-example: Still creating… (10m10s elapsed)
aws_instance.win-example: Still creating… (10m20s elapsed)
Error: Error applying plan:
1 error(s) occurred:
* aws_instance.win-example: timeout – last error: unknown error Post http://34.210.16.221:5985/wsman: dial tcp 34.210.16.221:5985: i/o timeout
It deploys win server though. When I log in using aws console I see that win instance is there but not configured because of that error.
The only difference in my code is region “us-west-2” and of course ami “ami-c9deafb1” (win 2k16 server)
Any advice?
LikeLiked by 1 person
same here
LikeLike
Maybe to try increasing timeout period in connection settings ?
LikeLike
This happened to me only in case ec2 instance has no public IP (terraform cannot reach instance)
LikeLike
Also happens to me but my instance definitely has a public ip
LikeLike
Sorry for late reply, i fixed issues with WinRM timeout, removed provision block, i updated post.
LikeLike
Please see updated post, tested with terraform 0.12 and works fine.
LikeLike
Hallo,
i think it is nice but i search , how to join to a windows domain with Terraform.
Have anybody an idea?
Greating
Jan
LikeLike
you can write ansible playbook and specify in under user data section (search my blog under ansible section, i already wrote that playbook), for running playbook with terraform check out https://alex.dzyoba.com/blog/terraform-ansible/
LikeLike
Error: Error applying plan:
1 error(s) occurred:
* aws_instance.win-example: 1 error(s) occurred:
* unknown error Post http://13.235.95.54:5985/wsman: dial tcp 13.235.95.54:5985: i/o timeout
Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.
Any help is greatly appreciated
LikeLike
Should be fixed now, see updated post
LikeLike
vars.tf
type = “map” default = {
(was throwing an error, changed default ={ to be on a separate line)
sg.tf
tags {
(throwing an error, changed to tags = {)
LikeLiked by 1 person
Thanks for feedback, post updated
LikeLike
Hi,
I am trying to get the password of the ec2 instance once it is launched like the way you have described. How can I get it ? I am trying to do this command
`aws ec2 get-password-data –instance-id “id” –priv-launch-key ~/Downloads/.pem` How can I provide the .pem file for authorization?
LikeLike
go to private key you created with ssh-keygen -f mykey, (mykey) add extension.pem or copy mykey file to new file with pem.extension
LikeLike
In aws instance launch it states “requires vpc”. Does this provisioner assume vpc exists?
LikeLike
It assume that default VPC exists (unless you deleted it). One default VPC exists for each account.
LikeLike
Is there a clean way to specify a version of Windows Server (say Windows Server 2019 for instance) and just always use the latest released/patched version available instead of indicating a specific AMI?
LikeLike
I am working on terraform script for creating windows VM by having “C” & “D” Drive
Any sample repo for this
LikeLike
Thanks for sharing this, can be hacked to fit a current cluster build-out. Appreciated 🙂
LikeLike