Deploying Windows EC2 instance using Terraform

Posted: January 8, 2018 in Amazon Web Services (AWS), AWS, Linux, terraform

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

1.png

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
2.png
Capture.PNG
Comments
  1. santhosh kumar says:

    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

    Liked by 1 person

  2. Kent says:

    Error: Unknown root level key: user_data

    Liked by 1 person

  3. Luk says:

    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?

    Liked by 1 person

  4. Kraemer says:

    Hallo,
    i think it is nice but i search , how to join to a windows domain with Terraform.
    Have anybody an idea?
    Greating
    Jan

    Like

  5. Anish says:

    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

    Like

  6. JC says:

    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 = {)

    Liked by 1 person

  7. RS says:

    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?

    Like

  8. Chris Topinka says:

    In aws instance launch it states “requires vpc”. Does this provisioner assume vpc exists?

    Like

  9. Justin Rousseau says:

    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?

    Like

  10. kirupakaran says:

    I am working on terraform script for creating windows VM by having “C” & “D” Drive
    Any sample repo for this

    Like

  11. nickb says:

    Thanks for sharing this, can be hacked to fit a current cluster build-out. Appreciated 🙂

    Like

Leave a comment