ansible: Add support for common configuration on Windows hosts
authorKienan Stewart <kstewart@efficios.com>
Wed, 31 May 2023 21:03:07 +0000 (17:03 -0400)
committerKienan Stewart <kstewart@efficios.com>
Thu, 1 Jun 2023 15:34:01 +0000 (11:34 -0400)
Change-Id: I9f5d9c7f4e58c4e1c55d5e25fe1886abcd8a7f0a

automation/ansible/README.md
automation/ansible/group_vars/windows.yml [new file with mode: 0644]
automation/ansible/hosts
automation/ansible/roles/common/tasks/main.yml
automation/ansible/roles/common/tasks/setup-Windows.yml [new file with mode: 0644]
automation/ansible/roles/common/tasks/users-Windows.yml [new file with mode: 0644]
automation/ansible/roles/common/tasks/users.yml [new file with mode: 0644]
automation/ansible/roles/common/templates/authorized_keys.j2 [new file with mode: 0644]
automation/ansible/roles/common/vars/Windows.yml [new file with mode: 0644]

index e51165015ea2ff88d8868b54979f6d8d7b51b684..9d2ffaa0cf84da24cd455106fd37c56a536382bd 100644 (file)
@@ -24,3 +24,11 @@ bw sync -f
 ```
 ansible-playbook -i hosts [-l SUBSET] site.yaml
 ```
+
+# Bootstrapping hosts
+
+## Windows
+
+1. Configure either SSH or WinRM connection: see https://docs.ansible.com/ansible/latest/os_guide/windows_setup.html
+2. For arm64 hosts:
+  * Install the necessary optional features (eg. OpenSSH, Hyper-V) since Windows RSAT isn't available on Arm64 yet
diff --git a/automation/ansible/group_vars/windows.yml b/automation/ansible/group_vars/windows.yml
new file mode 100644 (file)
index 0000000..05c617d
--- /dev/null
@@ -0,0 +1,4 @@
+---
+ansible_connection: ssh
+ansible_shell_type: powershell
+ansible_python_interpreter: 'c:/windows/py.exe'
index 3b4b654596a437bd3086eb0dcf7cb36f771d9226..60bed35403755d1ce9a49744fee030677130a623 100644 (file)
@@ -9,6 +9,10 @@ cloud05.internal.efficios.com
 #cloud06.internal.efficios.com
 #cloud07.internal.efficios.com
 #cloud08.internal.efficios.com
+ci-host-win11-arm64-01.internal.efficios.com
+
+[windows]
+ci-host-win11-arm64-01.internal.efficios.com
 
 [infra_lava]
 lava-master-03.internal.efficios.com
index 5cb4e16ea8dbac2cd6b8470fd93ae96433628528..a8798c55a5a06f35183f30febfbf03cc8215fe86 100644 (file)
 - include: setup-Suse.yml
   when: ansible_os_family == 'Suse'
 
+- include: setup-Windows.yml
+  when: ansible_os_family == "Windows"
+
 - name: Set up authorized_keys for the root user
   authorized_key:
     user: 'root'
     key: "{% for key in query('fileglob', 'public_keys/*.pub') %}{{ lookup('file', key) ~ '\n'}}{% endfor %}"
     exclusive: true
+  when: ansible_os_family != 'Windows'
 
-- name: Remove ubuntu user
-  user:
-    name: ubuntu
-    state: absent
-    remove: yes
-
-- name: Remove debian user
-  user:
-    name: debian
-    state: absent
-    remove: yes
-
-- name: Create jenkins user
-  when: jenkins_user | bool
-  user:
-    name: 'jenkins'
-
-- name: Set up authorized_keys for the jenkins user
-  when: jenkins_user | bool
-  authorized_key:
-    user: 'jenkins'
-    key: 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDA3fwpioVLDoCQsQkYK5bOwPb8N0EXeYm2MleBQTfqxtKaqWWbmUtFXAiyclKHRspjcAiIKwwqLyhPopHBqJzmXnB0GsfGmxXJ6wSBgKJ4kdBVRM+nKlK0wCl1oQkFeV/Xl3jzt1Ey96XiNWlesfkvgcMCpsJzQ7/xRb9IcghskzlQbLOwDNir/156JgAYUYvOLqNCcE+xcgPxJGanfZDXTLkfBYxaeaB8isBPeEU6fhPvu/W055M1uB7E0qhcbFtuKCBu1Fg4jzsW4yDU8+ZB1b5mAXwEAuMbVGMrOf4rjtTpGpQd6XFsXpFT28NU1u5j2cUbtANJalkNDX/UY6XJ jenkins@ci-master-02'
-
-#- name: Create sudoers.d directory.
-#  file:
-#    path: /etc/sudoers.d
-#    owner: root
-#    group: root
-#    mode: 0755
-#    state: directory
-#
-#- name: Set includedir in /etc/sudoers.
-#  lineinfile:
-#    dest: /etc/sudoers
-#    line: "#includedir /etc/sudoers.d"
-#    state: present
-#    validate: "/usr/sbin/visudo -cf %s"
-#
-#- name: Create jenkins sudoers file.
-#  copy:
-#    dest: "/etc/sudoers.d/jenkins"
-#    content: "jenkins ALL=NOPASSWD: ALL"
-#    mode: 0440
-#    owner: root
-#    group: root
-#    validate: "/usr/sbin/visudo -cf %s"
+- include: users-Windows.yml
+  when: ansible_os_family == "Windows"
 
-- name: Remove jenkins sudoers file
-  file:
-    path: "/etc/sudoers.d/jenkins"
-    state: absent
+- include: users.yml
+  when: ansible_os_family != "Windows"
diff --git a/automation/ansible/roles/common/tasks/setup-Windows.yml b/automation/ansible/roles/common/tasks/setup-Windows.yml
new file mode 100644 (file)
index 0000000..2ef6c88
--- /dev/null
@@ -0,0 +1,56 @@
+---
+
+- name: Install OpenSSH
+  ansible.windows.win_feature:
+    name: OpenSSH
+    state: present
+  # This depends on Get-WindowsFeature, provided by RSAT. Not currently available on arm
+  when: ansible_architecture != 'ARM 64-bit Processor'
+- name: Run OpenSSH automatically
+  ansible.windows.win_service:
+    name: sshd
+    start_mode: auto
+    state: started
+- name: Turn off standy
+  ansible.windows.win_command: 'C:\Windows\system32\powercfg.exe /change standby-timeout-ac 0'
+- name: Turn off hibernation
+  ansible.windows.win_command: 'C:\Windows\system32\powercfg.exe /hibernate off'
+- name: Turn off disk timeouts
+  ansible.windows.win_command: 'C:\Windows\system32\powercfg.exe /change disk-timeout-ac 0'
+- name: Install powershell
+  ansible.windows.win_package:
+    path: 'https://github.com/PowerShell/PowerShell/releases/download/v7.3.4/PowerShell-7.3.4-win-x64.msi'
+    state: 'present'
+    # get-wmiobject Win32_Product
+    product_id: '{11479679-5C7F-477F-869F-3ED956CE684D}'
+- name: Set powershell 7 as the default shell for OpenSSH
+  ansible.windows.win_regedit:
+    path: 'HKLM:\SOFTWARE\OpenSSH'
+    name: 'DefaultShell'
+    data: 'c:/progra~1/powershell/7/pwsh.exe'
+- name: Join domain
+  ansible.windows.win_domain_membership:
+    dns_domain_name: 'internal.efficios.com'
+    hostname: "{{ansible_hostname}}"
+    domain_ou_path: 'DC=internal,DC=efficios,DC=com'
+    state: 'domain'
+    domain_admin_user: "{{ lookup('community.general.bitwarden', '2443aefa-0b85-497d-aa0e-aef6011295c4', search='id', field='username')[0] }}"
+    domain_admin_password: "{{ lookup('community.general.bitwarden', '2443aefa-0b85-497d-aa0e-aef6011295c4', search='id', field='password')[0] }}"
+  register: domain_state
+- name: Install python
+  ansible.windows.win_package:
+    path: 'https://www.python.org/ftp/python/3.11.3/python-3.11.3-arm64.exe'
+    state: 'present'
+    arguments:
+      - '/InstallAllUsers=1'
+      - '/SimpleInstall'
+      - '/quiet'
+    creates_path: 'C:\Windows\py.exe'
+- name: Set administrator authorized keys
+  ansible.windows.win_template:
+    src: 'authorized_keys.j2'
+    dest: 'c:\ProgramData\ssh\administrators_authorized_keys'
+
+- name: Reboot if domain changed
+  when: domain_state.reboot_required
+  ansible.windows.win_reboot:
diff --git a/automation/ansible/roles/common/tasks/users-Windows.yml b/automation/ansible/roles/common/tasks/users-Windows.yml
new file mode 100644 (file)
index 0000000..0a61c88
--- /dev/null
@@ -0,0 +1,18 @@
+---
+- name: Create jenkins user
+  ansible.windows.win_user:
+    name: jenkins
+    state: "{{ (jenkins_user|bool) | ternary('present', 'absent') }}"
+
+- name: Create jenkins user dotssh folder
+  when: jenkins_user|bool
+  ansible.windows.win_file:
+    state: directory
+    path: "c:/users/jenkins/.ssh"
+
+- name: Deploy jenkins authorized_keys
+  when: jenkins_user|bool
+  ansible.windows.win_copy:
+    # yamllint disable-line rule:line-length
+    content: 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDA3fwpioVLDoCQsQkYK5bOwPb8N0EXeYm2MleBQTfqxtKaqWWbmUtFXAiyclKHRspjcAiIKwwqLyhPopHBqJzmXnB0GsfGmxXJ6wSBgKJ4kdBVRM+nKlK0wCl1oQkFeV/Xl3jzt1Ey96XiNWlesfkvgcMCpsJzQ7/xRb9IcghskzlQbLOwDNir/156JgAYUYvOLqNCcE+xcgPxJGanfZDXTLkfBYxaeaB8isBPeEU6fhPvu/W055M1uB7E0qhcbFtuKCBu1Fg4jzsW4yDU8+ZB1b5mAXwEAuMbVGMrOf4rjtTpGpQd6XFsXpFT28NU1u5j2cUbtANJalkNDX/UY6XJ jenkins@ci-master-02'
+    dest: 'c:/users/jenkins/.ssh/authorized_keys'
diff --git a/automation/ansible/roles/common/tasks/users.yml b/automation/ansible/roles/common/tasks/users.yml
new file mode 100644 (file)
index 0000000..f5065bd
--- /dev/null
@@ -0,0 +1,28 @@
+---
+- name: Remove ubuntu user
+  user:
+    name: ubuntu
+    state: absent
+    remove: yes
+
+- name: Remove debian user
+  user:
+    name: debian
+    state: absent
+    remove: yes
+
+- name: Create jenkins user
+  when: jenkins_user | bool
+  user:
+    name: 'jenkins'
+
+- name: Set up authorized_keys for the jenkins user
+  when: jenkins_user | bool
+  authorized_key:
+    user: 'jenkins'
+    # yamllint disable-line rule:line-length
+    key: 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDA3fwpioVLDoCQsQkYK5bOwPb8N0EXeYm2MleBQTfqxtKaqWWbmUtFXAiyclKHRspjcAiIKwwqLyhPopHBqJzmXnB0GsfGmxXJ6wSBgKJ4kdBVRM+nKlK0wCl1oQkFeV/Xl3jzt1Ey96XiNWlesfkvgcMCpsJzQ7/xRb9IcghskzlQbLOwDNir/156JgAYUYvOLqNCcE+xcgPxJGanfZDXTLkfBYxaeaB8isBPeEU6fhPvu/W055M1uB7E0qhcbFtuKCBu1Fg4jzsW4yDU8+ZB1b5mAXwEAuMbVGMrOf4rjtTpGpQd6XFsXpFT28NU1u5j2cUbtANJalkNDX/UY6XJ jenkins@ci-master-02'
+- name: Remove jenkins sudoers file
+  file:
+    path: "/etc/sudoers.d/jenkins"
+    state: absent
diff --git a/automation/ansible/roles/common/templates/authorized_keys.j2 b/automation/ansible/roles/common/templates/authorized_keys.j2
new file mode 100644 (file)
index 0000000..f08adee
--- /dev/null
@@ -0,0 +1,3 @@
+{% for filename in lookup('fileglob', 'public_keys/*.pub', wantlist=true) -%}
+{{ lookup('file', filename) }}
+{% endfor %}
diff --git a/automation/ansible/roles/common/vars/Windows.yml b/automation/ansible/roles/common/vars/Windows.yml
new file mode 100644 (file)
index 0000000..ed97d53
--- /dev/null
@@ -0,0 +1 @@
+---
This page took 0.028505 seconds and 4 git commands to generate.