ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Ansible] Window Server 업데이트 자동화
    오픈소스 2021. 3. 3. 17:02

     

     개요

     IT인프라. 특히나 서버 관리자로 일하는 사람들은 모두 패치 작업을 한 번쯤은 진행해보았을 것이다. 대상에 따라 차이는 있겠지만 같은 작업을 1대..2대..많게는 50대까지.. 수행하는 것은 여간 피곤한 일이 아니다. 더군다나 서비스 중단 시간 최소화를 위하여 야간에 작업하는 관리자에게 패치 작업은 모두 완료되었는가를 물어봤을 때, 확실하게 대답할 수 있는 사람은 몇 없을 것이다.

    Ansible을 활용하여 이를 해결할 수 있는 방법을 가져왔다. 본 글에서는 WINDOW에 대한 패치 작업 자동화를 다룰 예정이며 다른 OS에도 구현이 완료되는 대로 정리하여 업로드할 예정이다. Playbook을 작성하기 나름이겠지만 필자는 Task 단위로 작성하였으며, 모든 서버에서 동시다발적으로 병렬 수행되어 시간이 크게 감소된다는 것을 참고하길 바란다.

     

     


     

     

     Task#1 작업 폴더 생성

     패치 작업을 진행하기 전에 관련 파일 저장을 위한 폴더를 생성한다. 안에는 구성 정보와 패치 파일 등이 저장된다. win_file 모듈을 사용하며 기존에 폴더가 생성되어 있어 오류가 발생하더라도 무시하고 넘어갈 수 있도록 ignore_errors 구문을 추가했다.

      - name: Make Folder
        win_file:
            path: C:\Ansible
            state: directory
        ignore_errors: yes

     

     Task#2 구성 정보 백업

     OS의 기본 명령어들을 통하여 현재 상태 값을 파일로 저장하는 방식이며, 관리자마다 필요한 정보가 다를 수 있으니 필요할 경우 양식만 맞춰서 추가하면 된다. 필자는 가능한 대부분의 값을 백업하는데 작업 이후에 발생하는 차이를 확인하기 위함이며 레지스트리는 서버에 따라 백업 시간이 상이할 수 있다. (그래 봤자 5분 이내면 다 끝난다.)

      - name: Server Config Backup
        win_shell: |
            cmd /C "ipconfig /all > C:\Ansible\ipconfig.txt"
            cmd /C "tasklist > C:\Ansible\tasklist.txt"
            cmd /C "netstat -ano > C:\Ansible\netstat_ano.txt"
            cmd /C "netstat -rn > C:\Ansible\netstat_rn.txt"
            cmd /C "sc query > C:\Ansible\sc_query.txt"
            cmd /C "reg export HKCR C:\Ansible\Registry_HKCR.reg /y"
            cmd /C "reg export HKLM C:\Ansible\Registry_HKLM.reg /y"
            cmd /C "reg export HKU C:\Ansible\Registry_HKU.reg /y"
            cmd /C "reg export HKCC C:\Ansible\Registry_HKCC.reg /y"

     

     Task#3 패치 파일 배포

     Ansible의 win_copy 모듈을 사용하면 파일 복사는 간단하게 처리할 수 있다. 하지만 우리는 하나의 버전만을 다루는 게 아니기 때문에 현재 OS 정보 확인하여 그에 맞는 파일을 배포할 필요가 있는데 필자는 Register이라는 명령어 결과를 저장하는 옵션을 사용하여 이를 처리했다. 아래 구문은 WinSVR2012와 WinSVR2016을 구분하여 배포하는 내용이다.

      - name: Check Client OS Edition
        win_shell: "wmic os get Caption | findstr Window"
        register: OS_Edition
    
      - name: Copy PatchFile to Client (2012)
        win_copy:
           src: /etc/2012/
           dest: C:\Ansible
        when: '"2012" in OS_Edition.stdout'
    
      - name: Copy PatchFile to Client (2016)
        win_copy:
           src: /etc/2016/
           dest: C:\Ansible
        when: '"2016" in OS_Edition.stdout'

    wmic 명령어를 통하여 대상 장비의 버전을 확인하고 이를 OS_Edition 이라는 변수에 저장한다. 이후 변수 안에 특정 문자열이 포함되었는가를 기준으로 하여 파일을 배포한다. 특수문자가 많이 있으니 사용 시에 주의하자.

     

     Task#4 패치 시작

     Task#3을  끝으로 패치를 위한 준비는 모두 끝났다. 패치는 win_hotfix 라는 모듈을 사용하며 업데이트 종류에 따라 구문이 조금 달라진다.

    필자는 기본적으로 Stack → Rollup 순으로 패치를 진행하는데, Stack은 패치 정보를 조회할 수 있도록 해주는 패치로 대부분 재부팅이 필요하지 않다. 반면, Rollup은 해당 일자까지의 모든 내용이 합쳐진 패치이기 때문에 재부팅이 필수적으로 들어가게 되는데, 이는 win_hotfix 모듈의 reboot 옵션을 통하여 처리할 수 있다. 패치를 적용한 후에 재부팅이 필요할 경우에 어떤 방식으로 처리할지를 결정하는 옵션이다.

      - name: Execute 2012 PatchFile#1
        win_hotfix:
           source: "C:\\Ansible\\{{ var_2012_patch1 }}"
           state: present
        when: '"2012" in OS_Edition.stdout'
    
      - name: Execute 2012 PatchFile#2
        win_hotfix:
           source: "C:\\Ansible\\{{ var_2012_patch2 }}"
           state: present
           reboot: yes
        when: '"2012" in OS_Edition.stdout'
    
      - name: Execute 2016 PatchFile#1
        win_hotfix:
           source: "C:\\Ansible\\{{ var_2016_patch1 }}"
           state: present
        when: '"2016" in OS_Edition.stdout'
    
      - name: Execute 2016 PatchFile#2
        win_hotfix:
           source: "C:\\Ansible\\{{ var_2016_patch2 }}"
           state: present
           reboot: yes
        when: '"2016" in OS_Edition.stdout'

    본문에 {{ var_2012_patch1 }} 형식으로 된 값들이 보이는데, 향후에도 Playbook을 재 사용하기 위하여 패치 파일명을 변수로 선언한 값이며, 게시글 마지막 부분에 전체 Playbook 링크를 첨부할 테니 참고하도록 하자.

     

     Task#5 재부팅 확인 및 패치 적용 여부 확인

     모종의 이유로 패치가 실패할 수도 있기 때문에, 패치 적용 이후에 정상적으로 재부팅 되었는지 반드시 확인해야 한다. 이를 위한 모듈도 존재하는데 win_reboot이다. WINDOW 서버가 재 기동 되었을 경우에 정상 부팅되어 Ansible 연동이 정상적일 때까지 기다리는 기능으로 해당 모듈이 완료되면 대상 장비는 재기동까지 모두 완료되었음을 알 수 있다.

      - name: After Update reboot
        win_reboot:

    그리고 마지막으로 패치가 적용되었는지 확인하면 된다. Ansible을 명령어를 수행했을 때, 결과가 정상이 아니면 FAIL/SKIP 등으로 표시하기 때문에 패치 확인 명령어가 OK로 떨어지면 패치가 완료되었다고 볼 수 있고 결과가 다른 장비는 개별적으로 확인해보면 된다.

      - name: Check Client OS Edition
        win_shell: "wmic os get Caption | findstr Window"
        register: OS_Edition
    
      - name: Patch Applied Check (2012)  
        win_shell: |
            cmd /C "wmic qfe list | findstr {{ var_2012_patch1.split('.').0 }}"
            cmd /C "wmic qfe list | findstr {{ var_2012_patch2.split('.').0 }}"
        when: '"2012" in OS_Edition.stdout'
    
      - name: Patch Applied Check (2016)
        win_shell: |
            cmd /C "wmic qfe list | findstr {{ var_2016_patch1.split('.').0 }}"
            cmd /C "wmic qfe list | findstr {{ var_2016_patch2.split('.').0 }}"
        when: '"2016" in OS_Edition.stdout'

    패치를 수행할 때와 확인할 때 사용하는 파일의 이름이 달라서 Split 옵션을 사용한 것을 참고하도록 하자.

     

     패치 진행도 확인

     Playbook이 수행중인 과정이 화면에 표시되기는 하지만 대상이 많을 경우엔 빠르게 지나가기 때문에 정확히 확인하기가 쉽지 않다. 콘솔 등으로 붙어서 확인하는 방법도 있지만 업데이트 중일 경우엔 일반적인 상태가 같아 보이기 때문에 역시 식별이 쉽지 않다. 이럴 경우엔 패치 관련 프로세스가 기동 중인지 여부로 확인해볼 수 있다.

    ※ TiWorker.exe = 모듈 설치 프로그램 작업자로 알려진 프로세스로 Microsoft의 소프트웨어이다.

     

     최종 Playbook

     필자가 사용한 Playbook의 필요한 부분만 확인하여 기재하였으니 전체를 참고해도 되고 필요한 모듈만 활용해서 다른 Playbook을 작성해도 좋다. 전체 Playbook 파일을 첨부하였으니 확인해보고, 수행 중 확인된 이슈로 패치 확인을 같은 Playbook에서 수행하면 실패하거나 상황에 따라 결과가 달라지는 경우가 있어서 2개의 Playbook으로 분리하였으니 참고하길 바란다. 

    AutoPM_Total.yml
    0.00MB
    AutoPM_CheckPatch.yml
    0.00MB

     

     

     


     

     

     마무리

     Ansible 기반으로 생각보다 많은 것을 자동화할 수 있다는 것에 큰 매력을 느끼고 있다. 비록 오픈소스라 문제 해결에 시간이 많이 걸리긴 하지만 그에 상응하는 자유로움이 확실한 강점인 듯하다. 이를 활용하여 앞으로도 다양한 내용을 게시할 예정이니 같은 업계에서 고생하는 분들께 조금이나마 도움이 되었으면 한다.

    궁금하신 내용은 댓글로 남겨주시고, 많은 블로그 방문은 저에게 큰 힘이 됩니다. ・ᴥ・ 

     

    댓글

Designed by Tistory.