├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── aws-asg-chef ├── asg_user_data.tpl ├── main.tf └── variables.tf ├── aws-ebs-mount ├── ebs │ ├── main.tf │ ├── outputs.tf │ └── vars.tf └── instance │ ├── main.tf │ ├── outputs.tf │ └── vars.tf ├── aws-winrm-instance ├── main.tf ├── outputs.tf └── variables.tf └── choco-selenium-grid ├── hub ├── main.tf ├── outputs.tf └── variables.tf └── nodes ├── asg_user_data.tpl ├── main.tf └── variables.tf /.gitignore: -------------------------------------------------------------------------------- 1 | # HashCorp 2 | terraform.tfvar 3 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at dennis.hoer@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Getting Involved 2 | 3 | New contributors are always welcome, when it doubt please ask questions. We strive to be an open and welcoming 4 | community. Please be nice to one another. 5 | 6 | ### Coding 7 | 8 | * Pick a task: 9 | * Offer feedback on open [pull requests](https://github.com/dhoer/terraform_examples/pulls). 10 | * Review open [issues](https://github.com/dhoer/terraform_examples/issues) for things to help on. 11 | * [Create an issue](https://github.com/dhoer/terraform_examples/issues/new) to start a discussion on additions or features. 12 | * Fork the project, add your changes and tests to cover them in a topic branch. 13 | * Commit your changes and rebase against `dhoer/terraform_examples` to ensure everything is up to date. 14 | * [Submit a pull request](https://github.com/dhoer/terraform_examples/compare/). 15 | 16 | ### Non-Coding 17 | 18 | * Offer feedback on open [issues](https://github.com/dhoer/terraform_examples/issues). 19 | * Organize or volunteer at events. 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2015-2017 Dennis Hoer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Terraform Examples 2 | 3 | These are the missing Terraform AWS Windows examples. 4 | Other Terraform examples can be found here: https://github.com/terraform-aws-modules. 5 | 6 | ## AWS Windows 7 | 8 | ### aws-asg-chef 9 | 10 | Shows how to use `user_data` to provision an ASG server instance with Chef. 11 | 12 | The user_data script does the following: 13 | - downloads and install chef-client 14 | - downloads s3://mybucket/chef-validator.pem and s3://mybucket/encrypted_data_bag_secret 15 | - applies provisioning tag to instance 16 | - runs chef-client with provided runlist and environment && if successful will apply tags 17 | (Note that Name tag and Chef node/client names will be name appended with the instance id e.g. example-i-a1b2c3d4) 18 | - removes provisioning tag 19 | 20 | Note that IAM must be setup to allow access to Chef server and s3. This example also expects Chef's chef-validator and 21 | encrypted_data_bag_secret to be downloadable from an S3 bucket. Be sure to change s3 paths accordingly. 22 | 23 | ### aws-winrm-instance 24 | 25 | Shows how to use `user_data` to configure WinRM, open firewall, and set the Administrator 26 | password for AWS Window 2012R2 Base image. 27 | 28 | ### aws-ebs-mount 29 | 30 | Shows how to use `user_data` to bring a persistent ebs volume (as D: drive) online. 31 | 32 | ### choco-selenium-grid 33 | 34 | Shows how to use chocolatey to install a selenium-grid on windows server. 35 | 36 | #### hub 37 | 38 | Shows how to use `user_data` and chocolatey to install and configure a selenium hub. 39 | 40 | 41 | #### nodes 42 | 43 | Shows how to use `user_data` and chocolatey to install and configure a selenium nodes at a higher screen resolution than 1024x768 default. 44 | -------------------------------------------------------------------------------- /aws-asg-chef/asg_user_data.tpl: -------------------------------------------------------------------------------- 1 | 53 | -------------------------------------------------------------------------------- /aws-asg-chef/main.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = "${var.aws_region}" 3 | } 4 | 5 | data "template_file" "asg_user_data" { 6 | template = "asg_user_data.tpl" 7 | 8 | vars { 9 | name = "example" 10 | environment = "default" 11 | run_list = "nginx" 12 | } 13 | } 14 | 15 | # Lookup the correct AMI based on the region specified 16 | data "aws_ami" "amazon_windows_2012R2" { 17 | most_recent = true 18 | owners = ["amazon"] 19 | 20 | filter { 21 | name = "name" 22 | values = ["Windows_Server-2012-R2_RTM-English-64Bit-Base-*"] 23 | } 24 | } 25 | 26 | resource "aws_launch_configuration" "example" { 27 | name = "example" 28 | image_id = "${data.aws_ami.amazon_windows_2012R2.image_id}" 29 | instance_type = "m1.small" 30 | 31 | key_name = "mykey" 32 | iam_instance_profile = "chef-provisioning-role" 33 | 34 | root_block_device { 35 | volume_size = "50" 36 | } 37 | 38 | user_data = "${data.template_file.asg_user_data.rendered}" 39 | } 40 | 41 | resource "aws_autoscaling_group" "example" { 42 | name = "example" 43 | availability_zones = ["us-east-1a", "us-east-1c"] 44 | vpc_zone_identifier = ["subnet-a1b2c3d4e5", "subnet-1a2b3c4d5e"] 45 | max_size = 2 46 | min_size = 2 47 | desired_capability = 2 48 | health_check_grace_period = 300 49 | health_check_type = "EC2" 50 | default_cooldown = 300 51 | force_delete = true 52 | launch_configuration = "${aws_launch_configuration.example.name}" 53 | 54 | tag { 55 | key = "Name" 56 | value = "example" 57 | propagate_at_launch = true 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /aws-asg-chef/variables.tf: -------------------------------------------------------------------------------- 1 | variable "key_name" { 2 | description = "Name of the SSH keypair to use in AWS." 3 | } 4 | 5 | variable "aws_region" { 6 | description = "AWS region to launch servers." 7 | default = "us-east-1" 8 | } 9 | -------------------------------------------------------------------------------- /aws-ebs-mount/ebs/main.tf: -------------------------------------------------------------------------------- 1 | # Specify the provider and access details 2 | provider "aws" { 3 | region = "${var.aws_region}" 4 | } 5 | 6 | # Create ebs volume with Name tag set 7 | resource "aws_ebs_volume" "ebs" { 8 | availability_zone = "${var.availability_zone}" 9 | size = "${var.ebs_size}" 10 | type = "gp2" 11 | 12 | tags { 13 | Name = "${var.ebs_name}" 14 | } 15 | 16 | lifecycle { 17 | ignore_changes = ["tags"] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /aws-ebs-mount/ebs/outputs.tf: -------------------------------------------------------------------------------- 1 | output "availability_zone" { 2 | value = "${aws_ebs_volume.ebs.availability_zone}" 3 | } 4 | 5 | output "id" { 6 | value = "${aws_ebs_volume.ebs.id}" 7 | } 8 | 9 | output "size" { 10 | value = "${aws_ebs_volume.ebs.size}" 11 | } 12 | -------------------------------------------------------------------------------- /aws-ebs-mount/ebs/vars.tf: -------------------------------------------------------------------------------- 1 | variable "aws_region" { 2 | default = "us-east-1" 3 | } 4 | 5 | variable "ebs_name" { 6 | default = "terraform_ebs_example" 7 | } 8 | 9 | variable "ebs_size" { 10 | default = 5 11 | } 12 | 13 | variable "availability_zone" { 14 | default = "us-east-1b" 15 | } 16 | -------------------------------------------------------------------------------- /aws-ebs-mount/instance/main.tf: -------------------------------------------------------------------------------- 1 | # Specify the provider and access details 2 | provider "aws" { 3 | region = "${var.aws_region}" 4 | } 5 | 6 | # Lookup the correct AMI based on the region specified 7 | data "aws_ami" "amazon_windows_2012R2" { 8 | most_recent = true 9 | owners = ["amazon"] 10 | 11 | filter { 12 | name = "name" 13 | values = ["Windows_Server-2012-R2_RTM-English-64Bit-Base-*"] 14 | } 15 | } 16 | 17 | # Lookup ebs volume based on Name tag 18 | data "aws_ebs_volume" "ebs_volume" { 19 | most_recent = true 20 | 21 | filter { 22 | name = "snapshot-id" 23 | values = [""] 24 | } 25 | 26 | filter { 27 | name = "tag:Name" 28 | values = ["${var.ebs_name}"] 29 | } 30 | } 31 | 32 | # Attach ebs volume to instance 33 | resource "aws_volume_attachment" "ebs_att" { 34 | device_name = "xvdj" 35 | volume_id = "${data.aws_ebs_volume.ebs_volume.volume_id}" 36 | instance_id = "${aws_instance.ebs_example.id}" 37 | skip_destroy = true 38 | 39 | lifecycle { 40 | ignore_changes = ["tags"] 41 | } 42 | } 43 | 44 | resource "aws_instance" "ebs_example" { 45 | # The connection block tells our provisioner how to 46 | # communicate with the resource (instance) 47 | connection { 48 | type = "winrm" 49 | user = "Administrator" 50 | password = "${var.admin_password}" 51 | } 52 | 53 | instance_type = "t2.micro" 54 | ami = "${data.aws_ami.amazon_windows_2012R2.image_id}" 55 | 56 | # The name of our SSH keypair you've created and downloaded 57 | # from the AWS console. 58 | # 59 | # https://console.aws.amazon.com/ec2/v2/home?region=us-west-2#KeyPairs 60 | # 61 | key_name = "${var.key_name}" 62 | 63 | # EC2Config service does not take actions on disks that have already been 64 | # initialized. It only provisions newer 'raw' disks, formats them and assigns 65 | # them with driver letters. So Powershell's Get-Disk function is used to 66 | # bring ebs volume online with read-write access after it has already been 67 | # initialized. It should assign it with the letter D: by default. 68 | # 69 | # See the following for more info about managing storage with windows: 70 | # https://blogs.msdn.microsoft.com/san/2012/07/03/managing-storage-with-windows-powershell-on-windows-server-2012/ 71 | user_data = < 73 | # Bring ebs volume online with read-write access 74 | Get-Disk | Where-Object IsOffline -Eq $True | Set-Disk -IsOffline $False 75 | Get-Disk | Where-Object isReadOnly -Eq $True | Set-Disk -IsReadOnly $False 76 | 77 | # Set Administrator password 78 | $admin = [adsi]("WinNT://./administrator, user") 79 | $admin.psbase.invoke("SetPassword", "${var.admin_password}") 80 | 81 | EOF 82 | } 83 | -------------------------------------------------------------------------------- /aws-ebs-mount/instance/outputs.tf: -------------------------------------------------------------------------------- 1 | output "image_id" { 2 | value = "${data.aws_ami.amazon_windows_2012R2.id}" 3 | } 4 | 5 | output "private_ip" { 6 | value = "${aws_instance.ebs_example.private_ip}" 7 | } 8 | -------------------------------------------------------------------------------- /aws-ebs-mount/instance/vars.tf: -------------------------------------------------------------------------------- 1 | variable "ebs_name" { 2 | description = "Tag Name of ebs volume to mount." 3 | default = "terraform_ebs_example" 4 | } 5 | 6 | variable "admin_password" { 7 | description = "Windows Administrator password to login as." 8 | } 9 | 10 | variable "key_name" { 11 | description = "Name of the SSH keypair to use in AWS." 12 | } 13 | 14 | variable "aws_region" { 15 | description = "AWS region to launch servers." 16 | default = "us-east-1" 17 | } 18 | -------------------------------------------------------------------------------- /aws-winrm-instance/main.tf: -------------------------------------------------------------------------------- 1 | # Specify the provider and access details 2 | provider "aws" { 3 | region = "${var.aws_region}" 4 | } 5 | 6 | # Default security group to access the instances via WinRM over HTTP and HTTPS 7 | resource "aws_security_group" "default" { 8 | name = "terraform_example" 9 | description = "Used in the terraform" 10 | 11 | # WinRM access from anywhere 12 | ingress { 13 | from_port = 5985 14 | to_port = 5986 15 | protocol = "tcp" 16 | cidr_blocks = ["0.0.0.0/0"] 17 | } 18 | 19 | # outbound internet access 20 | egress { 21 | from_port = 0 22 | to_port = 0 23 | protocol = "-1" 24 | cidr_blocks = ["0.0.0.0/0"] 25 | } 26 | } 27 | 28 | # Lookup the correct AMI based on the region specified 29 | data "aws_ami" "amazon_windows_2012R2" { 30 | most_recent = true 31 | owners = ["amazon"] 32 | 33 | filter { 34 | name = "name" 35 | values = ["Windows_Server-2012-R2_RTM-English-64Bit-Base-*"] 36 | } 37 | } 38 | 39 | resource "aws_instance" "winrm" { 40 | # The connection block tells our provisioner how to 41 | # communicate with the resource (instance) 42 | connection { 43 | type = "winrm" 44 | user = "Administrator" 45 | password = "${var.admin_password}" 46 | 47 | # set from default of 5m to 10m to avoid winrm timeout 48 | timeout = "10m" 49 | } 50 | 51 | instance_type = "t2.micro" 52 | ami = "${data.aws_ami.amazon_windows_2012R2.image_id}" 53 | 54 | # The name of our SSH keypair you've created and downloaded 55 | # from the AWS console. 56 | # 57 | # https://console.aws.amazon.com/ec2/v2/home?region=us-west-2#KeyPairs 58 | # 59 | key_name = "${var.key_name}" 60 | 61 | # Our Security group to allow WinRM access 62 | security_groups = ["${aws_security_group.default.name}"] 63 | 64 | # Note that terraform uses Go WinRM which doesn't support https at this time. If server is not on a private network, 65 | # recommend bootstraping Chef via user_data. See asg_user_data.tpl for an example on how to do that. 66 | user_data = < 68 | winrm quickconfig -q & winrm set winrm/config @{MaxTimeoutms="1800000"} & winrm set winrm/config/service @{AllowUnencrypted="true"} & winrm set winrm/config/service/auth @{Basic="true"} 69 | 70 | 71 | netsh advfirewall firewall add rule name="WinRM in" protocol=TCP dir=in profile=any localport=5985 remoteip=any localip=any action=allow 72 | # Set Administrator password 73 | $admin = [adsi]("WinNT://./administrator, user") 74 | $admin.psbase.invoke("SetPassword", "${var.admin_password}") 75 | 76 | EOF 77 | } 78 | -------------------------------------------------------------------------------- /aws-winrm-instance/outputs.tf: -------------------------------------------------------------------------------- 1 | output "image_id" { 2 | value = "${data.aws_ami.amazon_windows_2012R2.id}" 3 | } 4 | 5 | output "private_ip" { 6 | value = "${aws_instance.winrm.private_ip}" 7 | } 8 | -------------------------------------------------------------------------------- /aws-winrm-instance/variables.tf: -------------------------------------------------------------------------------- 1 | variable "admin_password" { 2 | description = "Windows Administrator password to login as." 3 | } 4 | 5 | variable "key_name" { 6 | description = "Name of the SSH keypair to use in AWS." 7 | } 8 | 9 | variable "aws_region" { 10 | description = "AWS region to launch servers." 11 | default = "us-east-1" 12 | } 13 | -------------------------------------------------------------------------------- /choco-selenium-grid/hub/main.tf: -------------------------------------------------------------------------------- 1 | # Specify the provider and access details 2 | provider "aws" { 3 | region = "${var.aws_region}" 4 | } 5 | 6 | # Default security group to access the instances via WinRM over HTTP and HTTPS 7 | resource "aws_security_group" "default" { 8 | name = "terraform_example" 9 | description = "Used in the terraform" 10 | 11 | # WinRM access from anywhere 12 | ingress { 13 | from_port = 5985 14 | to_port = 5986 15 | protocol = "tcp" 16 | cidr_blocks = ["0.0.0.0/0"] 17 | } 18 | 19 | # outbound internet access 20 | egress { 21 | from_port = 0 22 | to_port = 0 23 | protocol = "-1" 24 | cidr_blocks = ["0.0.0.0/0"] 25 | } 26 | } 27 | 28 | # Lookup the correct AMI based on the region specified 29 | data "aws_ami" "amazon_windows_2016" { 30 | most_recent = true 31 | owners = ["amazon"] 32 | 33 | filter { 34 | name = "name" 35 | values = ["Windows_Server-2016-English-Full-Base-*"] 36 | } 37 | } 38 | 39 | resource "aws_instance" "winrm" { 40 | # The connection block tells our provisioner how to 41 | # communicate with the resource (instance) 42 | connection { 43 | type = "winrm" 44 | user = "Administrator" 45 | password = "${var.admin_password}" 46 | 47 | # set from default of 5m to 10m to avoid winrm timeout 48 | timeout = "10m" 49 | } 50 | 51 | instance_type = "t2.micro" 52 | ami = "${data.aws_ami.amazon_windows_2016.image_id}" 53 | 54 | # The name of our SSH keypair you've created and downloaded 55 | # from the AWS console. 56 | # 57 | # https://console.aws.amazon.com/ec2/v2/home?region=us-west-2#KeyPairs 58 | # 59 | key_name = "${var.key_name}" 60 | 61 | # Our Security group to allow WinRM access 62 | security_groups = ["${aws_security_group.default.name}"] 63 | 64 | # Note that terraform uses Go WinRM which doesn't support https at this time. If server is not on a private network, 65 | # recommend bootstraping Chef via user_data. See asg_user_data.tpl for an example on how to do that. 66 | user_data = < 68 | @powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin" 69 | winrm quickconfig -q & winrm set winrm/config @{MaxTimeoutms="1800000"} & winrm set winrm/config/service @{AllowUnencrypted="true"} & winrm set winrm/config/service/auth @{Basic="true"} 70 | 71 | 72 | netsh advfirewall firewall add rule name="WinRM in" protocol=TCP dir=in profile=any localport=5985 remoteip=any localip=any action=allow 73 | 74 | # Set Administrator password 75 | $admin = [adsi]("WinNT://./administrator, user") 76 | $admin.psbase.invoke("SetPassword", "${var.admin_password}") 77 | 78 | # Install Selenium Hub as Windows Service 79 | choco install -y nssm --pre 80 | choco install -y jdk8 81 | choco install -y selenium --params "'/role:hub /service /autostart'" 82 | 83 | EOF 84 | } 85 | -------------------------------------------------------------------------------- /choco-selenium-grid/hub/outputs.tf: -------------------------------------------------------------------------------- 1 | output "image_id" { 2 | value = "${data.aws_ami.amazon_windows_2012R2.id}" 3 | } 4 | 5 | output "private_ip" { 6 | value = "${aws_instance.winrm.private_ip}" 7 | } 8 | -------------------------------------------------------------------------------- /choco-selenium-grid/hub/variables.tf: -------------------------------------------------------------------------------- 1 | variable "admin_password" { 2 | description = "Windows Administrator password to login as." 3 | } 4 | 5 | variable "key_name" { 6 | description = "Name of the SSH keypair to use in AWS." 7 | } 8 | 9 | variable "aws_region" { 10 | description = "AWS region to launch servers." 11 | default = "us-east-1" 12 | } 13 | -------------------------------------------------------------------------------- /choco-selenium-grid/nodes/asg_user_data.tpl: -------------------------------------------------------------------------------- 1 | 4 | 5 | # Set Administrator password 6 | $admin = [adsi]("WinNT://./administrator, user") 7 | $admin.psbase.invoke("SetPassword", "${password}") 8 | 9 | # Install Screen Resolution at 1920x1080 10 | choco install -y screen-resolution --params "'/Password:${password}'" 11 | 12 | # Autologon to rdp_local account created by Screen Resolution 13 | choco install -y autologon 14 | autologon rdp_local $env:userdomain ${password} 15 | 16 | # Selenium Node and Dependencies 17 | choco install -y jdk8 firefox selenium-gecko-driver selenium-chrome-driver selenium-ie-driver 18 | choco install -y googlechrome --ignorechecksum 19 | choco install -y selenium --params "'/role:node /hub:http://${hub_url}:4444 /autostart /log'" 20 | 21 | # IE Required Configuration - https://github.com/SeleniumHQ/selenium/wiki/InternetExplorerDriver#required-configuration 22 | # disable Internet Explorer Enhanced Security Configuration (ESC) - http://support.microsoft.com/kb/933991 23 | Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}" -Name "IsInstalled" -Type DWord -Value 0 24 | Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}" -Name "IsInstalled" -Type DWord -Value 0 25 | If (!(Test-Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_ESCZoneMap_IEHarden")) { 26 | New-Item -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_ESCZoneMap_IEHarden" -Force 27 | } 28 | Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_ESCZoneMap_IEHarden" -Name "Version" -Type String -Value "[System.Math]::Round((Get-Date -Date ((Get-Date).ToUniversalTime()) -UFormat %s))" 29 | Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_ESCZoneMap_IEHarden" -Name "StubPath" -Type String -Value 'reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap" /v IEHarden /d 0 /t REG_DWORD /f' 30 | # enable protected mode for local internet zone - http://support.microsoft.com/kb/182569 31 | If (!(Test-Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zone1_2500")) { 32 | New-Item -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zone1_2500" -Force 33 | } 34 | Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zone1_2500" -Name "Version" -Type String -Value "[System.Math]::Round((Get-Date -Date ((Get-Date).ToUniversalTime()) -UFormat %s))" 35 | Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zone1_2500" -Name "StubPath" -Type String -Value 'reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\1" /v 2500 /d 0 /t REG_DWORD /f' 36 | # enable protected mode for trusted sites zone - http://support.microsoft.com/kb/182569 37 | If (!(Test-Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zone2_2500")) { 38 | New-Item -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zone2_2500" -Force 39 | } 40 | Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zone2_2500" -Name "Version" -Type String -Value "[System.Math]::Round((Get-Date -Date ((Get-Date).ToUniversalTime()) -UFormat %s))" 41 | Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zone2_2500" -Name "StubPath" -Type String -Value 'reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\2" /v 2500 /d 0 /t REG_DWORD /f' 42 | # enable protected mode for internet zone - http://support.microsoft.com/kb/182569 43 | If (!(Test-Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zone3_2500")) { 44 | New-Item -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zone3_2500" -Force 45 | } 46 | Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zone3_2500" -Name "Version" -Type String -Value "[System.Math]::Round((Get-Date -Date ((Get-Date).ToUniversalTime()) -UFormat %s))" 47 | Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zone3_2500" -Name "StubPath" -Type String -Value 'reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" /v 2500 /d 0 /t REG_DWORD /f' 48 | # enable protected mode for restricted sites zone - http://support.microsoft.com/kb/182569 49 | If (!(Test-Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zone4_2500")) { 50 | New-Item -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zone4_2500" -Force 51 | } 52 | Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zone4_2500" -Name "Version" -Type String -Value "[System.Math]::Round((Get-Date -Date ((Get-Date).ToUniversalTime()) -UFormat %s))" 53 | Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zone4_2500" -Name "StubPath" -Type String -Value 'reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\4" /v 2500 /d 0 /t REG_DWORD /f' 54 | # enable active scripting for internet zone - http://support.microsoft.com/kb/182569 55 | If (!(Test-Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zone3_1400")) { 56 | New-Item -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zone3_1400" -Force 57 | } 58 | Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zone3_1400" -Name "Version" -Type String -Value "[System.Math]::Round((Get-Date -Date ((Get-Date).ToUniversalTime()) -UFormat %s))" 59 | Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zone3_1400" -Name "StubPath" -Type String -Value 'reg add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3" /v 1400 /d 0 /t REG_DWORD /f' 60 | # disable IE Feature Back-Forward Cache - allows drivers to maintain a connection to IE (IE 11 only). 61 | If (!(Test-Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BFCACHE")) { 62 | New-Item -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BFCACHE" -Force 63 | } 64 | Set-ItemProperty -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BFCACHE" -Name "iexplore.exe" -Type DWord -Value 0 65 | # configure IE Zoom level to be 100% 66 | If (!(Test-Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zoom_ZoomFactor")) { 67 | New-Item -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zoom_ZoomFactor" -Force 68 | } 69 | Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zoom_ZoomFactor" -Name "Version" -Type String -Value "[System.Math]::Round((Get-Date -Date ((Get-Date).ToUniversalTime()) -UFormat %s))" 70 | Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\IE_Zoom_ZoomFactor" -Name "StubPath" -Type String -Value 'reg add "HKCU\SOFTWARE\Microsoft\Internet Explorer\Zoom" /v ZoomFactor /d 100_000 /t REG_DWORD /f' 71 | 72 | # Disable autoupdate - updates during testing may cause test failure 73 | If (!(Test-Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU")) { 74 | New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Force 75 | } 76 | Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "NoAutoUpdate" -Type DWord -Value 1 77 | 78 | Restart-Computer -Force 79 | 80 | -------------------------------------------------------------------------------- /choco-selenium-grid/nodes/main.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = "${var.aws_region}" 3 | } 4 | 5 | data "template_file" "asg_user_data" { 6 | template = "asg_user_data.tpl" 7 | 8 | vars { 9 | hub_url = "${var.hub_url}" 10 | password = "${var.admin_password}" 11 | } 12 | } 13 | 14 | # Lookup the correct AMI based on the region specified 15 | data "aws_ami" "amazon_windows_2016" { 16 | most_recent = true 17 | owners = ["amazon"] 18 | 19 | filter { 20 | name = "name" 21 | values = ["Windows_Server-2016-English-Full-Base-*"] 22 | } 23 | } 24 | 25 | resource "aws_launch_configuration" "example" { 26 | name = "example" 27 | image_id = "${data.aws_ami.amazon_windows_2016.image_id}" 28 | instance_type = "m1.small" 29 | 30 | key_name = "mykey" 31 | iam_instance_profile = "choco-provisioning-role" 32 | 33 | root_block_device { 34 | volume_size = "50" 35 | } 36 | 37 | user_data = "${data.template_file.asg_user_data.rendered}" 38 | } 39 | 40 | resource "aws_autoscaling_group" "example" { 41 | name = "example" 42 | availability_zones = ["us-east-1a", "us-east-1c"] 43 | vpc_zone_identifier = ["subnet-a1b2c3d4e5", "subnet-1a2b3c4d5e"] 44 | max_size = 2 45 | min_size = 2 46 | desired_capability = 2 47 | health_check_grace_period = 300 48 | health_check_type = "EC2" 49 | default_cooldown = 300 50 | force_delete = true 51 | launch_configuration = "${aws_launch_configuration.example.name}" 52 | 53 | tag { 54 | key = "Name" 55 | value = "example" 56 | propagate_at_launch = true 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /choco-selenium-grid/nodes/variables.tf: -------------------------------------------------------------------------------- 1 | variable "admin_password" { 2 | description = "Windows Administrator password to login as." 3 | } 4 | 5 | variable "hub_url" { 6 | description = "The url to selenium hub, e.g., http://selenium.example.com:4444" 7 | } 8 | 9 | variable "key_name" { 10 | description = "Name of the SSH keypair to use in AWS." 11 | } 12 | 13 | variable "aws_region" { 14 | description = "AWS region to launch servers." 15 | default = "us-east-1" 16 | } 17 | --------------------------------------------------------------------------------