Setting Up Amazon EC2 for Windows Server with Ansible
Tags: aws, ec2, windows, ansible
Published: 2023-02-15 11:18:27

Hi everyone! I come back and this is my first post in 2023. I hope you are well, healthy, and still excited to keep learning.

So, this post was created because someone asked me about his `user_data` script for the Windows instance that didn't work. He's following my blog post [here](https://dev.to/aws-builders/launch-amazon-ec2-using-ansible-1mpf) and there you can see my conversations with him as well. I think the case is an interesting and rare topic to be discussed, then here it is!

To be honest, I've never launched a Windows EC2 instance as long as I learned AWS but at this time I do because I have to reproduce someone's case as I mentioned above. The reason actually doesn't sound cool :) but I hope it will be useful for anyone else who is in the same condition.

Goal: Remote directly once the instance is running.

Here are some steps we will do:

1. Create Key Pair
    
2. Create Security Group
    
3. Create Instance
    
4. Retrieve Password
    
5. Remote
    

As usual, if you are familiar with this blog. Before we do ansible tasks, you have to prepare some prerequisites:

1. [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) and [set at least one credential](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html);
    
2. [Ansible](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html);
    
3. Ansible collection for AWS by running `ansible-galaxy collection install collection_name`. There are 2 collections you can use, `amazon.aws` and `community.aws`.
    

## Ready? Let's get started!

**1\. Create Key Pair**

I usually import a key pair for Linux instance but at this time I do something different. This is also the only requirement so we can retrieve the password for the Windows instance. Please note, that we only can use `rsa` as a key type for Windows instances.

```yaml
    - name: create rsa key pair
      amazon.aws.ec2_key:
        name: Administrator
        key_type: rsa
      register: key
```

Then, let's save the file! We never know that we may need it again for future tasks. We can use it for any other Windows instances.

```yaml
    - name: download private key
      copy: content="{{ key.key.private_key }}" dest="administrator.pem" mode=0600
```

**2\. Create Security Group**

We will create a custom SG that allows RDP port which is 3389.

```yaml
    - name: create security group
      amazon.aws.ec2_group:
        name: rdp
        description: allow remote windows
        vpc_id: vpc-xxxx
        region: ap-southeast-3
        rules:
          - proto: tcp
            ports: 3389
            cidr_ip: 0.0.0.0/0
      register: sgroup
```

**3\. Create Instance**

Here we will directly create one instance using `amazon.aws.ec2_instance` module. Please check [this blog post](https://dev.to/aws-builders/launch-amazon-ec2-using-ansible-1mpf) below for more.

```yaml
    - name: create instance
      amazon.aws.ec2_instance:
        name: windows
        vpc_subnet_id: subnet-xxxx
        image_id: ami-019fd4e0ba82e7e28
        instance_type: t3.micro
        key_name: "{{ key.key.name }}"
        security_group: "{{ sgroup.group_id }}"
        state: present
        volumes:
          - device_name: /dev/sda1
            ebs:
              volume_size: 30
              volume_type: gp2
              delete_on_termination: true
        user_data: "{{ lookup('file','script_file_name') }}"
        wait: true
      register: instance
```

Note: `user_data` is optional. In case you wanna use it with PowerShell. Don't forget to put your script between `powershell` tag. It should seem like below:

```powershell
<powershell>
$put_your_script_here
</powershell>
```

**4\. Retrieve Password**

Here we ask default password for the default user of the Windows server which is the administrator.

```yaml
    - name: get the Administrator password
      community.aws.ec2_win_password:
        instance_id: "{{ instance.instances[0].instance_id }}"
        region: ap-southeast-3
        key_file: administrator.pem
        wait: true
      register: password

    - name: show password
      debug:
        msg: "{{ password.win_password }}"
```

## Let's run the playbook!

Here we run all tasks at once (in one YAML file) and refer the resources to each other as they are newly created (marked with register). All can be customized based on your need, either using variables, tags, or anything. For existing resources, you can directly define each resource's name as the value.

```bash
$ ansible-playbook -i host.yml windows.yml

PLAY [windows] *****************************************************************

TASK [create rsa key pair] *****************************************************
changed: [127.0.0.1]

TASK [download private key] ****************************************************
changed: [127.0.0.1]

TASK [create security group] ***************************************************
changed: [127.0.0.1]

TASK [create instance] *********************************************************
changed: [127.0.0.1]

TASK [get the Administrator password] ******************************************
ok: [127.0.0.1]

TASK [show password] ***********************************************************
ok: [127.0.0.1] => {
    "msg": "baHNB1OIx8BL8;15$&*76xp.BNrp63DF"
}

PLAY RECAP *********************************************************************
127.0.0.1                  : ok=6    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```

**5\. Remote**

Once all is ready, we can remote it using the RDP client. If you are a Linux user, you can use an RDP client for Linux such as Remmina.

![remmina_1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/41ienocrafws8qt85f69.png)

![remmina_2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/on50lirrj8otqm6sa3ht.png)

That's all for now. Let me know if you have any questions or even corrections. Last but not least, don't forget to follow this blog! Thank you!

**References:**

* https://docs.ansible.com/ansible/latest/collections/community/aws/ec2_win_password_module.html
    
* https://aws.amazon.com/premiumsupport/knowledge-center/retrieve-windows-admin-password/
    
* https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-windows-user-data.html#user-data-powershell