Automasi Manajemen User: Mengelola 100 Windows Server Sekaligus dengan SaltStack#

Overview#

Optimalisasi Manajemen Konfigurasi Windows Server secara Terpusat Dalam operasional infrastruktur skala besar, tantangan utama yang dihadapi adalah menjaga konsistensi dan efisiensi manajemen server. Saat ini, kami memiliki kebutuhan untuk menstandarisasi seluruh aplikasi agar berjalan di bawah akun pengguna khusus (user app). Melakukan proses ini secara manual—seperti melakukan remote login via RDP pada 100 Windows Server hanya untuk membuat user satu per satu—merupakan metode yang sangat tidak efisien dan memakan waktu. Untuk mengatasi hambatan tersebut dan memastikan pembuatan user dapat diselesaikan dalam hitungan detik secara serentak, kami menerapkan solusi SaltStack.

FHS#

.
├── README.md
├── pillar
│   ├── secrets.sls
│   └── top.sls
├── salt
│   └── users
│       └── windows.sls
└── scripts
    └── encrypt.sh

Pillar#

Pillar adalah fitur SaltStack untuk menyimpan data variabel secara aman dan terpusat. Data di Pillar hanya akan dikirimkan ke Minion yang berhak.

buat file pillar/secrets.sls

#!yaml|gpg

admin_password: |
  -----BEGIN PGP MESSAGE-----
  
  hF4Dz2I2uqLs1yYSAQdAWKX8MhuC7NS2NxqQxoSAu5br/nxC6x/5ylsjOHSSUlcw
  p2Qo67AtuZs0cCy28CThMmDZxCMMCBWxvDFtSuWsB24TjPwPxMc6aB4Fx/PJuU4S
  1F8BCQIQRtuu6omvd/WYqzieHRWnZ/t2JDhfTJTJyiD/CaUsSyAQW1c5SBlUVKm2
  qw44rqFJglG1rEI5zI8J2NLrwgJEIifdhZDV06AVbHd6Ogr+IKnjLwpX26U3mE2T
  9Q==
  =FTI5
  -----END PGP MESSAGE-----

app_password: |
  -----BEGIN PGP MESSAGE-----
  
  hF4Dz2I2uqLs1yYSAQdA8TIJMqRMUcx8VngjpGBpK/1E5vMl2R7YqoRCS1P3Y2ow
  N50hoDBMyzsM2JITAwf+rxnuFLhH0o4A6pRSSvqy4xcJzE24XLeaXugJKhqD3tHD
  1FgBCQIQHyNgkGdxuBhiU258x+SbjLNEWLuT4JbVExXWKGH46NI7vOSpYiq+IHZR
  KUgCVX7jG5I2F++Aia83CRdhvxv1V+j9SZZn2OVXX12Pkuji48fd1ML9
  =fTaO
  -----END PGP MESSAGE-----

untuk generate password gunakan

pastikan sudah konfigurasi gpg sebelumnya Config GPG [Link Text]

bash encrypt.sh 'password'

ada pun file scripts/encrypt.sh

#!/bin/bash

# Pastikan ada input password
if [ -z "$1" ]; then
    echo "Penggunaan: ./encrypt_pass.sh 'Your_Password'"
    exit 1
fi

# Ambil Key ID dari keyring salt
KEY_ID=$(gpg --homedir /etc/salt/gpgkeys --list-keys --with-colons | grep '^pub' | cut -d: -f5)

if [ -z "$KEY_ID" ]; then
    echo "Error: Kunci GPG tidak ditemukan di /etc/salt/gpgkeys"
    exit 1
fi

# Proses Enkripsi
echo -e "\n--- COPY KODE DI BAWAH INI ---\n"
echo -n "$1" | gpg --homedir /etc/salt/gpgkeys --armor --batch --trust-model always --encrypt -r "$KEY_ID"

buat file pillar/top.sls

base:
  '*':
    - secrets

Salt State#

Setelah data siap di Pillar, kita membuat instruksi logika di Salt State untuk mengeksekusi pembuatan user pada sistem operasi Windows.

buat file salt/users/windows.sls

# 1. User app
create_user_app:
  user.present:
    - name: app
    - password: {{ pillar['app_password'] | json }}
    - groups:
      - Users
      - Remote Desktop Users

# 2. User sudo_app
create_user_sudo_app:
  user.present:
    - name: sudo_app
    - password: {{ pillar['admin_password'] | json }}
    - groups:
      - Administrators

# 3. MENGHAPUS sudo_app dari RDP
remove_sudo_app_from_rdp_group:
  cmd.run:
    - name: |
        $group = "Remote Desktop Users"
        $user = "sudo_app"
        if (Get-LocalGroupMember -Group $group -Member $user -ErrorAction SilentlyContinue) {
            Remove-LocalGroupMember -Group $group -Member $user
        }
    - shell: powershell
    - hide_output: True

# 4. Memasukkan kredensial sudo_app menggunakan Scheduled Task (Workaround cmdkey)
add_sudo_creds_to_app_user:
  cmd.run:
    - name: |
        $pass_sudo = {{ pillar['admin_password'] | json }}
        $taskName = "SaltCreds_sudo"
        $action = New-ScheduledTaskAction -Execute "cmd.exe" -Argument "/c cmdkey /add:localhost /user:sudo_app /pass:$pass_sudo"
        $principal = New-ScheduledTaskPrincipal -UserId "app" -LogonType S4U
        Register-ScheduledTask -TaskName $taskName -Action $action -Principal $principal
        Start-ScheduledTask -TaskName $taskName
        Start-Sleep -s 5
        Unregister-ScheduledTask -TaskName $taskName -Confirm:$false
    - shell: powershell
    - hide_output: True

# 5. Simpan juga password 'app' sendiri
add_self_creds_to_app_user:
  cmd.run:
    - name: |
        $pass_app = {{ pillar['app_password'] | json }}
        $taskName = "SaltCreds_self"
        $action = New-ScheduledTaskAction -Execute "cmd.exe" -Argument "/c cmdkey /add:localhost /user:app /pass:$pass_app"
        $principal = New-ScheduledTaskPrincipal -UserId "app" -LogonType S4U
        Register-ScheduledTask -TaskName $taskName -Action $action -Principal $principal
        Start-ScheduledTask -TaskName $taskName
        Start-Sleep -s 5
        Unregister-ScheduledTask -TaskName $taskName -Confirm:$false
    - shell: powershell
    - hide_output: True

# 5. LGPO Policy
deny_rdp_sudo_app:
  lgpo.set:
    - computer_policy:
        'Deny log on through Remote Desktop Services':
          - sudo_app

Execute#

Penyegaran memori cache

salt 'trim-vm-prd-t4-operation-jumphost-ksei' saltutil.refresh_pillar

Test eksekusi

salt 'trim-vm-prd-t4-operation-jumphost-ksei' state.apply windows_users test=True

Eksekusi

salt 'trim-vm-prd-t4-operation-jumphost-ksei' state.apply windows_users

Debug

salt-run -l debug pillar.show_pillar