Skip to content

Instantly share code, notes, and snippets.

@blachniet
Last active August 12, 2017 20:01
Show Gist options
  • Save blachniet/0e72c20c6f635db010f36f0b695cbe00 to your computer and use it in GitHub Desktop.
Save blachniet/0e72c20c6f635db010f36f0b695cbe00 to your computer and use it in GitHub Desktop.
Install Consul in a consistent way on Windows machines
<#
.SYNOPSIS
Installs Consul and creates a Windows service to run the agent.
.DESCRIPTION
Installs Consul and creates a Windows service to run the agent.
Requirements:
- You must execute script with administrator priveleges
- A service named 'Consul' MUST NOT exist
- C:\ProgramData\Consul MUST NOT exist
- This script must reside in a directory resembling the following. You must provide
all files other than this script.
config/
config.json
ssl/
ca.crt
agent.crt
agent.key
consul.exe
Install-Consul.ps1
nssm.exe
What it does:
- Installs NSSM to C:\ProgramData\NSSM if it does not already exist there
- Installs Consul to C:\ProgramData\Consul
- Creates firewall rules required by Consul
- Creates a Windows service which runs the agent
- Uses NSSM to configure the Windows service
#>
param(
[Parameter(Mandatory=$true,
HelpMessage="Maps to Consul's '-encrypt' command line argument")]
[string]
$Encrypt,
[Parameter(Mandatory=$false,
HelpMessage="Maps to Consul's '-server' command line argument")]
[switch]
$Server,
[Parameter(Mandatory=$false,
HelpMessage="Maps to Consul's '-bootstrap-expect' command line argument")]
[int]
$BootstrapExpect = 0
)
$ErrorActionPreference = 'Stop'
$consulDir = "C:\ProgramData\Consul"
$consulExe = (Join-Path $consulDir "consul.exe")
$nssmDir = "C:\ProgramData\NSSM"
$nssmExe = (Join-Path $nssmDir "nssm.exe")
function Invoke-NSSM {
param (
[Parameter(Mandatory=$true, Position=0)]
[string]
$Command,
[Parameter()]
[switch]
$Echo
)
if ($Echo) {
Write-Host $Command
}
$sb = [scriptblock]::Create("$nssmExe $Command")
Invoke-Command $sb
if ($LASTEXITCODE) {
throw "Exit code '$LASTEXITCODE' from '$Command'"
}
}
if ((Test-Path $consulDir) -or ((Get-Service Consul -ErrorAction SilentlyContinue) -ne $null)) {
throw "Consul already installed. This script only supports fresh installs"
}
# Copy NSSM if necessary
if (!(Test-Path $nssmExe)) {
New-Item -ItemType Container $nssmDir -ErrorAction SilentlyContinue
Copy-Item "$PSScriptRoot/nssm.exe" $nssmDir
}
# Copy Consul binaries, configs, etc.
New-Item -ItemType Container $consulDir
New-Item -ItemType Container "$consulDir/data"
New-Item -ItemType Container "$consulDir/logs"
Copy-Item "$PSScriptRoot/consul.exe" $consulDir
Copy-Item "$PSScriptRoot/config" $consulDir -Recurse
Copy-Item "$PSScriptRoot/ssl" $consulDir -Recurse
# Install Consul Firewall rules
New-NetFirewallRule -DisplayName 'Consul Server RPC' `
-Direction Inbound -LocalPort 8300 -Protocol TCP
New-NetFirewallRule -DisplayName 'Consul Serf LAN TCP' `
-Direction Inbound -LocalPort 8301 -Protocol TCP
New-NetFirewallRule -DisplayName 'Consul Serf LAN UDP' `
-Direction Inbound -LocalPort 8301 -Protocol UDP
New-NetFirewallRule -DisplayName 'Consul Serf WAN TCP' `
-Direction Inbound -LocalPort 8302 -Protocol TCP
New-NetFirewallRule -DisplayName 'Consul Serf WAN UDP' `
-Direction Inbound -LocalPort 8302 -Protocol UDP
# Build startup args
$args = "agent -config-dir=$consulDir/config -encrypt=$Encrypt"
if ($Server) {
$args += " -server"
}
if ($BootstrapExpect -gt 0) {
$args += " -bootstrap-expect=$BootstrapExpect"
}
# Install the Consul service
Invoke-NSSM "install Consul $consulExe"
Invoke-NSSM "set Consul AppDirectory $consulDir"
Invoke-NSSM "set Consul AppParameters `"$args`""
Invoke-NSSM "set Consul AppStdout $consulDir/logs/consul.log"
Invoke-NSSM "set Consul AppStderr $consulDir/logs/consul.log"
Start-Service Consul
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment