Windows 빌드 서버 구성에 필요한 Ansible 패키지 구성
이전에 구성한 Ansible Role에 실제 Windows 빌드에 필요한 패키지를 하나씩 구성해보자.
Windows 빌드 서버에 필요한 패키지
Chocolatey 설치 및 필수 패키지 설치
처음 테스트 했던 chcolatey를 해당 role에도 추가한다.
# 기존 테스트용 ansible 코드는 삭제하고 빌드 서버에 필요한 구성목록을 새로 작성
# 맨 위에 ---를 사용하는 것은 YAML 문서의 시작을 나타냄
# Ansible에서는 각 플레이북이나 role의 YAML 파일의 시작에 ---를 넣는 경우를 종종 볼 수 있음
cat <<EOT > roles/build_initialize/tasks/main.yml
---
# tasks file for build_initialize
- include_vars: vars/main.yml
# Chocolatey Install and Package Install
- import_tasks: chocolatey.yml
EOT
# Chocolatey 설치 및 Chocolatey를 통해 필요 패키지 설치
cat <<EOT > roles/build_initialize/tasks/chocolatey.yml
- name: Install Chocolatey
win_chocolatey:
name: "chocolatey"
register: download_choco
until: download_choco is succeeded
retries: 4
delay: 5
- name: Include additional Chocolatey packages
include_vars: vars/chocolatey_package.yml
- name: Install Chocolatey's packages
win_chocolatey:
name: "{{ item }}"
loop: "{{ chocolatey_packages }}"
EOT
# Chocolatey를 통해 설치할 패키지 목록을 vars에서 관리
cat <<EOT > roles/build_initialize/vars/chocolatey_package.yml
chocolatey_packages:
- git
- openjdk
- python
EOT
실행 테스트
root@ersia:~/ansible/windows_build_server# ansible-playbook windows_build_server.yml
SSH password:
PLAY [Configuration Build Server on Windows] ***************************************************************************
TASK [Gathering Facts] *************************************************************************************************
ok: [build_server1]
TASK [build_initialize : include_vars] *********************************************************************************
ok: [build_server1]
TASK [build_initialize : Install Chocolatey] ***************************************************************************
[WARNING]: Chocolatey was missing from this system, so it was installed during this task run.
changed: [build_server1]
TASK [build_initialize : Include additional Chocolatey packages] *******************************************************
ok: [build_server1]
TASK [build_initialize : Install Chocolatey's packages] ****************************************************************
changed: [build_server1] => (item=git)
changed: [build_server1] => (item=openjdk)
changed: [build_server1] => (item=python)
PLAY RECAP *************************************************************************************************************
build_server1 : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Visual Studio Build Tools Component 설치
Visual Studio를 사용할 때 개발에 필요한 패키지를 설치하면 아래와 같은 패키지 관리자를 볼 수 있다.
이런 Visual Studio 패키지는 각각 Component라고 불리며, MS에서 제공하는 별도의 패키지 관리자 프로그램을 통해서 설치할 수 있다.
이때 사용되는 도구는 버전(2019, 2022 등)별로 다르고, Visual Studio 종류(Enterprise, Professionnal 등)별로 다르게 관리된다.
일반적으로 Windows 빌드에는 Build Tools를 사용하게되는데, 다른 종류의 관리자 프로그램을 설치해도 대부분의 패키지를 설치할 수 있다. (단 devenv같은 도구는 라이선스가 필요)
버전과 종류 별로 패키지가 각각 관리되므로 가능한 한 하나로 통일해서 사용해야 빌드할 때 패키지 의존성을 잘 파악할 수 있다. (예를 들어 vs_buildtools로 Component를 설치하고, 실제 빌드에 사용하는 msbuild는 vs_professional을 통해 설치하면 vs_buildtools에 설치한 Component는 msbuild로 빌드 시 인식이 안될 수 있다.)
상세한 내용은 아래의 링크에서 확인할 수 있다.
# vs_buildtools 다운로드 및 vs_buildtools를 통해 필요 Component 설치
cat <<EOT > roles/build_initialize/tasks/vs_buildtools.yml
- name: Include build tools components list
include_vars:
file: vars/vs_buildtools_list.yml
- name: Install VS Component by BuildTools
ansible.windows.win_package:
path: https://aka.ms/vs/17/release/vs_buildtools.exe
product_id: '{6F320B93-EE3C-4826-85E0-ADF79F8D4C61}'
arguments: "{{ buildtools_components | map('regex_replace', '^', '--add ') | join(' ') }} --norestart --passive --wait"
state: present
EOT
# main task에 새로 생성한 vs_buildtools task 추가
cat <<EOT >> roles/build_initialize/tasks/main.yml
# Install Visual Studio Component by vs_buildtools
- import_tasks: vs_buildtools.yml
EOT
# vs_buildtools를 통해 설치할 Component 목록을 vars에서 관리
cat <<EOT > roles/build_initialize/vars/vs_buildtools_list.yml
buildtools_components:
- Microsoft.VisualStudio.Workload.MSBuildTools
- Microsoft.VisualStudio.Component.Windows11SDK.22621
EOT
실행 테스트
root@ersia:~/ansible/windows_build_server# ansible-playbook windows_build_server.yml
SSH password:
PLAY [Configuration Build Server on Windows] ***************************************************************************
TASK [Gathering Facts] *************************************************************************************************
ok: [build_server1]
TASK [build_initialize : include_vars] *********************************************************************************
ok: [build_server1]
...
...
TASK [build_initialize : Include build tools components list] **********************************************************
ok: [build_server1]
TASK [build_initialize : Install VS Component by BuildTools] ***********************************************************
changed: [build_server1]
PLAY RECAP *************************************************************************************************************
build_server1 : ok=7 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
(추가) vs_buildtools로 설치 시 주의사항
vs_buildtools와 같은 식으로 CLI를 통해 Visual Studio Component를 설치할 때 중요한 점이 있는데,
일단 한번 vs_buildtools로 설치를 하면 그 후에 vs_buildtools를 통해 패키지를 추가로 설치하는 작업을 진행할 수가 없다.
Ansible에서는 멱등성을 보장하기 위해 설치를 확인하는 작업 등을 수행하는데, product_id로 이미 한번 설치가 된 패키지에 대해서는 설치가 확인되면 추가로 작업을 수행하지 않는다,
나는 처음에 add 옵션에 component를 추가하려고 했었다.
하지만 계속 테스트를 해보니 ansible.windows.win_package 모듈을 통해 vs_buildtools.exe를 설치한 것으로 인식하기 때문에 arguments에 --add를 아무리 추가해도 이미 설치된 패키지에 인자만 바뀐 것으로 인식해서 작업을 수행하지 않고 넘어가게 된다.
root@ersia:~/ansible/windows_build_server# cat roles/build_initialize/vars/vs_buildtools_list.yml
buildtools_components:
- Microsoft.VisualStudio.Workload.MSBuildTools
- Microsoft.VisualStudio.Component.Windows11SDK.22621
root@ersia:~/ansible/windows_build_server#
root@ersia:~/ansible/windows_build_server# cat roles/build_initialize/vars/vs_buildtools_list.yml
buildtools_components:
- Microsoft.VisualStudio.Workload.MSBuildTools
- Microsoft.VisualStudio.Component.Windows11SDK.22621
- Microsoft.VisualStudio.Component.Windows10SDK.18362
# Microsoft.VisualStudio.Component.Windows10SDK.18362 Component를 추가했으나
# playbook을 실행하면 아래와 같이 그냥 지나가게된다.
root@ersia:~/ansible/windows_build_server# ansible-playbook windows_build_server.yml
SSH password:
PLAY [Configuration Build Server on Windows] **************************************************************************************************************
...
...
TASK [build_initialize : Include build tools components list] *********************************************************************************************
ok: [build_server1]
TASK [build_initialize : Install VS Component by BuildTools] **********************************************************************************************
ok: [build_server1]
PLAY RECAP ************************************************************************************************************************************************
build_server1 : ok=7 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
이를 해결하기 위해서 여러가지 테스트를 해보았는데 CLI를 통해서 Component를 추가하고 삭제하는게 정확하게 보장되진 않는 것 같았다.
예를 들어 --add로 추가한 Component를 추가하고 다시 ansible을 수행할 때는 --remove를 통해 제거하려고 할 때 제거가 되지 않거나 아무런 동작을 하지 않는 케이스가 종종 확인되었다.
winget이나 다른 패키지 관리자가 지원되는지도 찾아봤는데, win_chocolatey과 win_scoop만 지원하며 다른 모듈에 대해서는 지원 역량이 부족하다고 한다.
https://github.com/ansible-collections/community.windows/issues/89#issuecomment-1266054035
따라서 Windows Ansible에서는
- Visual Studio Component 설치 시 win_chocolatey만 사용하거나
- 별도의 cmd 스크립트를 통해서 관리하거나
- 최초 설치에만 vs_buildtools.exe를 써야
유지보수가 가능할 것 같다.
(추가) win_chocolatey로도 패키지 설치 시 param을 통해 추가 설치한 패키지에 대해서는 관리가 되지 않는다.
choco install visualstudio2022buildtools --params "`
--add Microsoft.VisualStudio.Component.VC.Llvm.Clang `
--add Microsoft.VisualStudio.Component.VC.Llvm.ClangToolset `
--add Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Llvm.Clang `
--add Microsoft.VisualStudio.Component.VC.CMake.Project"