AWS EC2 & Ansible Automation

My Process

I began this project with the idea that it would be pretty cool if I could just setup one AWS ec2 instance and route my kali linux VM's traffic through that instance using wireguard. I began setting it up while taking detailed notes throughout the process and was able to get it up and running successfully. I realized that even though setting everything up by hand taught me a lot, it also felt a bit tedious. That’s when I decided this whole setup would be way more useful if I could automate it. Since I already had detailed notes to work with, I started digging into ways I could turn those steps into a repeatable process. That way, instead of just being a one-off project, it could be something I can spin up quickly whenever I need it.

Python EC2 Automation


"""David Enfinger: 08-6-25"""

import boto3

ec2 = boto3.resource('ec2', region_name='us-east-1')

instances = ec2.create_instances(
    ImageId='[Insert AMI ID]',
    InstanceType='t2.micro',
    MinCount=1,
    MaxCount=1,
    KeyName='[Insert Priv key name]',
    SecurityGroupIds=['Insert Security group ID']  # NOTE: Make sure SG ID allows inbound traffic on 51820/UDP for WG
)

instance = instances[0]
print(f"Launching instance {instance.id}...")

instance.wait_until_running()
instance.load()

print(f"Instance running: {instance.public_ip_address}")

# saves to Ansible inventory
with open('ec2_inventory.ini', 'w') as f:
    f.write(f"[wireguard]\n{instance.public_ip_address} ansible_user=ubuntu ansible_ssh_private_key_file='/hle='[PATH TO PRIV KEY]'\n")
    

Ansible Routing Automation


- name: Setup WireGuard VPN server
  hosts: wireguard
  become: yes
  vars:
    wg_port: 51820
    server_private_key_path: /etc/wireguard/server_private.key
    client_temp_path: /tmp/wg0-client.conf
    client_local_path: ~/Desktop/wg0-client.conf

  tasks:

    - name: Install WireGuard
      apt:
        name: wireguard
        state: present
        update_cache: yes

    - name: Enable IP forwarding
      sysctl:
        name: net.ipv4.ip_forward
        value: '1'
        state: present
        reload: yes

    - name: Generate server private key
      command: wg genkey
      register: server_private
      changed_when: false

    - name: Save server private key
      copy:
        content: "{{ server_private.stdout }}"
        dest: "{{ server_private_key_path }}"
        owner: root
        group: root
        mode: '600'

    - name: Generate server public key
      shell: echo {{ server_private.stdout }} | wg pubkey
      register: server_public
      changed_when: false

    - name: Generate client private key
      command: wg genkey
      register: client_private
      changed_when: false

    - name: Generate client public key
      shell: echo {{ client_private.stdout }} | wg pubkey
      register: client_public
      changed_when: false

    - name: Create server config
      copy:
        dest: /etc/wireguard/wg0.conf
        content: |
          [Interface]
          Address = 10.0.0.1/24
          ListenPort = {{ wg_port }}
          PrivateKey = {{ server_private.stdout }}

          [Peer]
          PublicKey = {{ client_public.stdout }}
          AllowedIPs = 10.0.0.2/32

    - name: Start WireGuard server
      shell: wg-quick down wg0 || true && wg-quick up wg0

    - name: Create client config on EC2
      copy:
        dest: "{{ client_temp_path }}"
        content: |
          [Interface]
          Address = 10.0.0.2/24
          PrivateKey = {{ client_private.stdout }}
          DNS = 1.1.1.1

          [Peer]
          PublicKey = {{ server_public.stdout }}
          Endpoint = {{ ansible_host }}:{{ wg_port }}
          AllowedIPs = 0.0.0.0/0
        owner: ubuntu
        group: ubuntu
        mode: '600'

    - name: Fetch client config to local Kali Desktop
      fetch:
        src: "{{ client_temp_path }}"
        dest: "{{ client_local_path }}"
        flat: yes
    

Screenshot of Automation in Action

Automation Screenshot