Jim Rigsbee
2020-02-12 401011db7ff1ca5674c629891e5abd90a5e97761
Add PSRP through bastion for Windows hosts

* Enable the routing of PSRP connection through the Linux
bastion using Socks proxy.

* Remove Ansible initial delay when connecting to Windows hosts.

* Delegates to localhost when including vars to workaround Windows connection issue.
1 files added
6 files modified
144 ■■■■ changed files
ansible/cloud_providers/ec2_infrastructure_deployment.yml 26 ●●●● patch | view | raw | blame | history
ansible/include_vars.yml 2 ●●●●● patch | view | raw | blame | history
ansible/roles/infra-common-ssh-config-generate/tasks/main.yml 1 ●●●● patch | view | raw | blame | history
ansible/roles/infra-ec2-create-inventory/defaults/main.yml 3 ●●●●● patch | view | raw | blame | history
ansible/roles/infra-ec2-create-inventory/tasks/main.yml 99 ●●●●● patch | view | raw | blame | history
ansible/roles/infra-ec2-wait_for_windows_hosts/tasks/main.yml 2 ●●●●● patch | view | raw | blame | history
ansible/setup_runtime.yml 11 ●●●●● patch | view | raw | blame | history
ansible/cloud_providers/ec2_infrastructure_deployment.yml
@@ -62,6 +62,17 @@
      import_role:
        name: infra-common-ssh-config-generate
    - name: Stop SSH/Socks proxy for Windows proxying through bastion
      shell: |
        ssh -i {{ ssh_key | default(infra_ssh_key) | default(ansible_ssh_private_key_file) | default(default_key_name)}} -o "ControlPath=~/.ssh/cp/ssh-%r@%h:%p" -O exit -p 22 {{hostvars[bastion_hostname].ansible_user}}@{{hostvars[bastion_hostname].public_ip_address}}
      when: win_connect_method | d('winrm') == 'psrp'
      ignore_errors: true
    - name: Start a SSH/Socks proxy for Windows proxying through bastion
      shell: |
        mkdir -p ~/.ssh/cp
        ssh -i {{ ssh_key | default(infra_ssh_key) | default(ansible_ssh_private_key_file) | default(default_key_name)}} -o "ControlMaster=auto" -o "ControlPersist=no" -o "ControlPath=~/.ssh/cp/ssh-%r@%h:%p" -o "StrictHostKeyChecking=no" -CfNq -D 127.0.0.1:{{psrp_socks_port}} -p 22 {{hostvars[bastion_hostname].ansible_user}}@{{hostvars[bastion_hostname].public_ip_address}}
      when: win_connect_method | d('winrm') == 'psrp'
# include global vars again, this time for all hosts now that the inventory is built
- import_playbook: ../include_vars.yml
  tags:
@@ -104,20 +115,7 @@
    - step001
    - step001.4
  tasks:
    - name: set facts for remote access
      tags:
        - create_inventory
      set_fact:
        ansible_become: false
        ansible_connection: winrm
        ansible_host: "{{ public_dns_name }}"
        ansible_password: "{{ hostvars['localhost'].windows_password | default(hostvars['localhost'].generated_windows_password) }}"
        ansible_port: 5986
        ansible_user: Administrator
        ansible_winrm_server_cert_validation: ignore
        aws_region_final: "{{hostvars['localhost'].aws_region_final}}"
    - name: Run infra-ec2-wait_for_linux_hosts Role
    - name: Run infra-ec2-wait_for_windows_hosts Role
      import_role:
        name: infra-ec2-wait_for_windows_hosts
ansible/include_vars.yml
@@ -45,11 +45,13 @@
  tags: include_vars
  tasks:
    - name: Set output_dir for all hosts
      delegate_to: localhost
      set_fact:
        output_dir: "{{ hostvars.localhost.output_dir }}"
      when: hostvars.localhost.output_dir is defined
    - name: Include variables files
      delegate_to: localhost
      include_vars:
        file: "{{ item.stat.path }}"
      when:
ansible/roles/infra-common-ssh-config-generate/tasks/main.yml
@@ -79,6 +79,7 @@
  when:
    - item not in [bastion_hostname, 'localhost', '127.0.0.1']
    - item != hostvars[item].bastion
    - hostvars[item].ostype | d('linux') == 'linux'
  with_items: "{{ groups['all'] }}"
  tags:
    - bastion_proxy_config_hosts
ansible/roles/infra-ec2-create-inventory/defaults/main.yml
New file
@@ -0,0 +1,3 @@
---
win_connect_method: winrm
ansible/roles/infra-ec2-create-inventory/tasks/main.yml
@@ -45,7 +45,8 @@
    label: "{{item.tags.internaldns | default(item.private_dns_name)}}"
  ignore_errors: yes
- add_host:
- name: Add Linux hosts
  add_host:
    name: "{{item.tags.internaldns | default(item.private_dns_name)}}"
    shortname: "{{item.tags.Name | default(item.private_dns_name)}}"
    groups:
@@ -67,13 +68,105 @@
    public_dns_name: "{{item['public_dns_name']}}"
    private_dns_name: "{{item['private_dns_name']}}"
    private_ip_address: "{{item['private_ip_address']}}"
    public_ip_address: "{{item['public_ip_address']}}"
    public_ip_address: "{{item['public_ip_address'] | d('') }}"
    placement: "{{item['placement']['availability_zone']}}"
    image_id: "{{item['image_id']}}"
    ansible_ssh_extra_args: "-o StrictHostKeyChecking=no"
    ansible_python_interpreter: "{{ item.tags.ansible_python_interpreter | default(omit) }}"
    bastion: "{{ local_bastion | default('') }}"
  when: item.state.name != 'terminated'
    ostype: "{{item.tags.ostype | default('linux')}}"
    instance_name: "{{item.tags.instance_name  | d('') }}"
  when:
    - item.state.name != 'terminated'
    - item.tags.ostype | d('linux') == 'linux'
  with_items: "{{ec2_facts['instances']}}"
  loop_control:
    label: "{{item.tags.internaldns | default(item.private_dns_name)}}"
  tags:
    - create_inventory
    - must
- name: Add Windows hosts - winrm
  add_host:
    name: "{{item.tags.internaldns | default(item.private_dns_name)}}"
    shortname: "{{item.tags.Name | default(item.private_dns_name)}}"
    groups:
      - "tag_Project_{{stack_tag}}"
      - "tag_{{stack_tag}}_{{item['tags'][project_tag] | default('unknowns')}}"
      - "tag_{{stack_tag}}_ostype_{{item['tags'][project_tag_ostype] | default('unknown')}}"
      - "{{item.tags.ostype | default('unknowns')}}"
      - "{{item['tags'][project_tag_ostype] | default('unknowns')}}"
      - "{{ 'newnodes' if (item.tags.newnode|d()|bool) else 'all'}}"
    ansible_user: Administrator
    remote_user: Administrator
    ansible_connection: winrm
    ansible_password: "{{ hostvars['localhost'].windows_password | default(hostvars['localhost'].generated_windows_password) }}"
    ansible_port: 5986
    ansible_winrm_server_cert_validation: ignore
    key_name: "{{item['key_name']}}"
    state: "{{item['state']}}"
    internaldns: "{{item.tags.internaldns | default(item.private_dns_name)}}"
    isolated: "{{item.tags.isolated | default(false)}}"
    instance_id: "{{ item.instance_id }}"
    region: "{{ aws_region_final | default(aws_region) | default(region) | default('us-east-1')}}"
    public_dns_name: "{{item['public_dns_name']}}"
    private_dns_name: "{{item['private_dns_name']}}"
    private_ip_address: "{{item['private_ip_address']}}"
    public_ip_address: "{{item['public_ip_address'] | d('') }}"
    placement: "{{item['placement']['availability_zone']}}"
    image_id: "{{item['image_id']}}"
    bastion: "{{ local_bastion | default('') }}"
    ostype: windows
    instance_name: "{{item.tags.instance_name | d('') }}"
  when:
    - item.state.name != 'terminated'
    - item.tags.ostype | d('linux') == 'windows'
    - win_connect_method == 'winrm'
  with_items: "{{ec2_facts['instances']}}"
  loop_control:
    label: "{{item.tags.internaldns | default(item.private_dns_name)}}"
  tags:
    - create_inventory
    - must
- name: Add Windows Hosts - psrp
  add_host:
    name: "{{item.tags.internaldns | default(item.private_dns_name)}}"
    shortname: "{{item.tags.Name | default(item.private_dns_name)}}"
    groups:
      - "tag_Project_{{stack_tag}}"
      - "tag_{{stack_tag}}_{{item['tags'][project_tag] | default('unknowns')}}"
      - "tag_{{stack_tag}}_ostype_{{item['tags'][project_tag_ostype] | default('unknown')}}"
      - "{{item.tags.ostype | default('unknowns')}}"
      - "{{item['tags'][project_tag_ostype] | default('unknowns')}}"
      - "{{ 'newnodes' if (item.tags.newnode|d()|bool) else 'all'}}"
    ansible_user: Administrator
    remote_user: Administrator
    ansible_connection: psrp
    ansible_password: "{{ hostvars['localhost'].windows_password | default(hostvars['localhost'].generated_windows_password) }}"
    ansible_psrp_protocol: https
    ansible_psrp_auth: basic
    ansible_psrp_cert_validation: ignore
    ansible_psrp_proxy: "socks5h://localhost:{{psrp_socks_port}}"
    key_name: "{{item['key_name']}}"
    state: "{{item['state']}}"
    internaldns: "{{item.tags.internaldns | default(item.private_dns_name)}}"
    isolated: "{{item.tags.isolated | default(false)}}"
    instance_id: "{{ item.instance_id }}"
    region: "{{ aws_region_final | default(aws_region) | default(region) | default('us-east-1')}}"
    public_dns_name: "{{item['public_dns_name']}}"
    private_dns_name: "{{item['private_dns_name']}}"
    private_ip_address: "{{item['private_ip_address']}}"
    public_ip_address: "{{item['public_ip_address'] | d('') }}"
    placement: "{{item['placement']['availability_zone']}}"
    image_id: "{{item['image_id']}}"
    bastion: "{{ local_bastion | default('') }}"
    ostype: windows
    instance_name: "{{item.tags.instance_name | d('') }}"
  when:
    - item.state.name != 'terminated'
    - item.tags.ostype | d('linux') == 'windows'
    - win_connect_method == 'psrp'
  with_items: "{{ec2_facts['instances']}}"
  loop_control:
    label: "{{item.tags.internaldns | default(item.private_dns_name)}}"
ansible/roles/infra-ec2-wait_for_windows_hosts/tasks/main.yml
@@ -2,7 +2,6 @@
  wait_for_connection:
    timeout: 900
    connect_timeout: 60
    delay: 120
  register: rwait
  ignore_errors: true
@@ -20,5 +19,4 @@
  wait_for_connection:
    timeout: 900
    connect_timeout: 60
    delay: 120
  when: rwait is failed
ansible/setup_runtime.yml
@@ -45,3 +45,14 @@
# Load galaxy roles of the config
- import_playbook: install_galaxy_roles.yml
  tags: galaxy_roles
- name: Step 0000 - Set global vars
  hosts: localhost
  connection: local
  gather_facts: false
  become: false
  tasks:
    - name: Generate unique socks proxy port number
      set_fact:
        psrp_socks_port: "{{ 32767 |random(start=1024,seed=guid) }}"
      when: win_connect_method | d('winrm') == 'psrp'