Deployment script for Windows agent

Hello,

I try to create a playbook witch use powershell script to install and configure the windows agent.
The goal is for each new server I will deploy, I use the playbook to install and enroll the agent in my icinga.

I successfully create a working script which need me to give an API key. I found on the webui the API key generate for my “windows host” template. It’s working like a charm but it seems that this key need to be regenerated periodically.
So now i’m searching for a way to get it through cli or api call (to be use in my playbook).

How can I achieve that ?

For now my installation process do the following step :

  • Installation of Icinga framework without wizard → here a certificate request is waiting for approval on the master node
  • Approve the previously created request
  • Enroll the host through the director self service api → for this I use the api key from the host template (that I found in the “Agent” tab of the template definition)

Thanks for advance for your help

the icinga powershell framework can be used to “install icinga” / “register the host” and “get a valid certificate” because there is a feature for generating tickets used for signing requests.

If you post exactly what you are currently doing, I can try to point you in the right direction.

thanks for your reply.
Here the script i’m writing

Param( 
    [Parameter(Mandatory=$true)][string]$hostname,
    [Parameter(Mandatory=$false)][string]$selfServiceKey,
    [Parameter(Mandatory=$true)][ValidateSet("1","2")]$step
)

switch($step)
{
    1
    {
        $installCommand = "{
            IfW-ParentAddress:{Values:{hostname.master1:['0.0.0.0']}},
            IfW-ParentZone:{Values:['master']},
            IfW-Connection:{'Selection':'0'},
            IfW-ParentNodes:{Values:['hostname.master1','hostname.master2']},
            IfW-StableRepository:{Values:['https://packages.icinga.com/IcingaForWindows/stable']},
            IfW-Hostname:{'Selection': '6'},
            IfW-CustomHostname:{Values:['$hostname']}
        }"
    }
    2
    {
        if ($selfServiceKey -eq $null)
        {
            throw "selfServiceKey is mandatory when step 2 is selected"
            exit 1
        }
        $installCommand = "{
            IfW-DirectorSelfServiceKey:{Values:['$selfServiceKey']},
            IfW-DirectorUrl:{Values:['https://url_2_icingaweb/director/']},
            IfW-StableRepository:{Values:['https://packages.icinga.com/IcingaForWindows/stable']},
            IfW-Hostname:{'Selection': '6'},
            IfW-CustomHostname:{Values:['$hostname']}
        }"
    }
}

[Net.ServicePointManager]::SecurityProtocol = 'tls12, tls11';
$ProgressPreference = 'SilentlyContinue';
[string]$ScriptFile = 'C:\Users\Public\IcingaForWindows.ps1';

# download script
try {
    Invoke-WebRequest `
        -UseBasicParsing `
        -Uri             'https://packages.icinga.com/IcingaForWindows/IcingaForWindows.ps1' `
        -OutFile         $ScriptFile;
}
catch {
    throw "Error downloading script :$($_.Exception.Message)"
    exit 1
}

# install icinga framework
try {
    & $ScriptFile `
        -ModuleDirectory  'C:\Program Files\WindowsPowerShell\Modules\' `
        -SkipWizard
}
catch {
    throw "Error during framework installation : $($_.Exception.Message)"
    exit 1
}

# set framework parameters
try {
    Enable-IcingaUntrustedCertificateValidation
}
catch {
    throw $($_.Exception.Message)
    exit 1
}

# set firewall rule
try {
    New-NetFirewallRule -Program "%ProgramFiles%\ICINGA2\sbin\icinga2.exe" -Action Allow -Profile @('Domain', 'Private') -DisplayName "Icinga2" -Description "Allow Icinga2 agent communication with master" -Direction Outbound
    New-NetFirewallRule -Program "%ProgramFiles%\ICINGA2\sbin\icinga2.exe" -Action Allow -Profile @('Domain', 'Private') -DisplayName "Icinga2" -Description "Allow Icinga2 agent communication with master" -Direction Inbound
}
catch {
    throw "Error during firewall setting : $($_.Exception.Message)"
    exit 1
}

# install
try {
    & $ScriptFile `
        -InstallCommand $installCommand
}
catch {
    throw "Error during wizard execution : $($_.Exception.Message)"
    exit 1
}

# set service parameters
try {
    Get-CimInstance win32_service -filter "name='icinga2'" | Invoke-CimMethod -Name Change -Arguments @{StartName="LocalSystem";StartPassword=""}
}
catch {
    throw "Error during service setting : $($_.Exception.Message)"
    exit 1
}

# restart service
try {
    restart-service icinga2
}
catch {
    throw "Error during service restart : $($_.Exception.Message)"
    exit 1
}

exit 0

Hope it’s not so far from the good way to do it ^^

The global process is (with ansible)
1- Execute the script with hostname and step define to 1
2- Ansible sign the csr on the master node
3 - Execute the script with hostname, host template api key and step define to 2

For my understanding, step 1 create the csr, step 2 validate the csr, step 3 create the host in director through self service api.
Am I good ?

Did you look at https://github.com/Linuxfabrik/lfops/tree/main/roles/icinga2_agent & https://github.com/Linuxfabrik/lfops/blob/main/playbooks/icinga2_agent.yml?

The director self service in combination with IfW is better suited for fist run scripts in image based server deployment.

Thanks, no I didn’t knew the role. I juste test it everythong seems to be good but I have an error when trying to add host in director :
Unhandled exception occurred when sending web request. Exception: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
If I try a curl against the director URL the ssl handshake is OK… Maybe ansible doesn’t use the OS CA cert magazine ?

Try with -vvv and be carefull on which host and with which user the call is made.
Maybe you need to trust a new CA on the client?

I try with -vvv but nothing helpfull.
I finally find why, I modified the role to execute this task on the ansible server with a delegate_to: 127.0.0.1 but it seems to continue to be executed from client.
Anyway, on client I just install the CA certificate and no more SSL error since :slight_smile:
I put the user in Administrator role to validate the concept, now I have to work on permissions (if you already have the minimum necessary permission I’ll take it. ;))

thanks for your help

Normal permissions work for most but for the windows update you will need local system admin rights.

Sorry it was not clear, I talk about user permission on icinga, not on windows client (here I set the service to run as NT AUTHORITY\SYSTEM).

I autoreply myself ^^
Those permission work for add host on director :

1 Like

one last thing, is there a way to push deploy from director to master through ansible ?

Sure, via the https://icinga.com/docs/icinga-director/latest/doc/70-REST-API/#trigger-actions

I founded this ansible collection to do it : https://github.com/telekom-mms/ansible-collection-icinga-director
It work like a charm but I will test the link you send me.
Thanks !