在Windows上精通Ansible:您的首选专家指南

尽管 Ansible 以使用 SSH 管理 Linux 节点而闻名,但您是否知道 Ansible 在 Windows 上同样出色?通过使用 Windows 远程管理 (WinRM),Ansible 在 Windows 上可以有效地管理所有 Windows 节点!

在 Windows 上使用 Ansible,您可以执行诸如部署补丁、管理 Windows 服务器、执行 PowerShell 脚本等任务。

在本教程中,您将学习如何设置您的第一个 Windows 节点,以便使用 Ansible 进行管理,并了解如何对其运行命令和 Playbooks。

先决条件

如果您想要按照本教程操作,请确保在开始之前具备以下条件:

  • An Ansible 控制节点 – 本教程将使用 Ansible v2.9.18,在具有 IP 地址 10.111.4.53 的 Ubuntu 18.04.5 LTS 机器上运行。请注意,Windows 不支持作为控制节点,仅支持作为被管理节点。
  • 在 Ansible 控制节点上安装 Python – 本教程将使用 Python v2,但 v3 也应该可以正常工作。
  • 在 Ansible 控制节点上安装 pip 软件包
  • A Windows 2012 R2 or greater computer for Ansible to manage – This tutorial will use two Windows Server 2012 R2 Standard machines as remote nodes with IP addresses of 52.242.251.213 and 10.111.4.106.
  • A Windows workstation – This tutorial will perform some basic pre-configuration to the node that Windows will manage with Ansible and will require you to sitting at a Windows workstation.
  • 要管理的 Windows 服务器已启用 PowerShell 远程
  • A user account in the local Administrators group on the Windows computer. This tutorial will use an account called adminuser.

在 Windows 上设置 WinRM 监听器

在 Ansible 能够与远程 Windows 节点通信之前,它必须能够与之建立连接。它通过 Microsoft 协议 WinRM 来实现这一点。WinRM 是 PowerShell 远程 使用的相同协议,用于在 PowerShell 中运行远程命令。

截至目前,Ansible 并不完全支持 SSH 作为管理协议,但这是一个试验性功能。

为了使 Ansible 使用 WinRM 与 Windows 节点通信,您必须配置 WinRM。为此,Ansible 提供了 一个 PowerShell 脚本 来设置各种 WinRM 选项。

尽管 Red Hat 提供的用于配置 WinRM 的 PowerShell 脚本 已经经过测试并且安全,但您应该阅读并理解其高层次的功能。

您的第一个任务是下载配置脚本,并在 Windows 节点上运行 Ansible。为此,假设您的目标 Windows 计算机已经启用了 PowerShell 远程,并且您位于 Windows 工作站上:

下载ConfigureRemotingForAnsible.ps1 PowerShell 脚本到本地的 Windows 计算机。本教程将假定它被保存在~\Downloads目录中。

在 Windows 节点上运行配置脚本,该节点将由 Ansible 进行管理,使用Invoke-Command命令。下面的命令将在教程的两台演示机器上运行该命令,并提示您输入 Windows 节点上本地adminuser帐户的密码。

Invoke-Command -ComputerName 52.242.251.213, 10.111.4.106 -FilePath '~\Downloads\ConfigureRemotingForAnsible.ps1' -Credential (Get-Credential -UserName adminuser)

默认情况下,配置脚本将为基本的 HTTP 认证配置 WinRM。如果您想要 Ansible 使用更安全的连接,请了解如何为 Ansible 配置 WinRM over HTTPS

在 Windows 上配置 Ansible 的控制器

现在 Windows 节点已经准备好接受 Ansible,让我们现在配置 Ansible 控制器,告诉 Ansible 如何与其通信。

1. 使用您喜欢的 SSH 客户端通过 SSH 连接到您的 Ansible 控制器主机。

2. 安装pywinrm Python 模块。pywinrm Python 模块是必需的,用于让 Ansible 在 Windows 上通过 WinRM 协议与主机通信。

pip install pywinrm

3. 在Ansible清单文件中定义远程Windows节点。Ansible清单是通过文件定义的远程主机集合,可以使用主机名或IP地址进行标识。一旦定义,您可以使用命令和playbooks来针对Ansible清单进行操作,您很快就会看到。

默认的Ansible清单文件位于/etc/ansible/hosts目录中。

下面的示例清单文件创建了一个windows 主机组,其中包含每个Windows节点。此处使用主机组是为了稍后更容易一次性针对所有Windows节点(如果有多个的话)。

[windows]
 54.242.251.213
 10.111.4.106

4. 接下来,在清单文件中定义一些必需的变量,Ansible将在连接到Windows主机时使用这些变量,作为windows:vars组。

[windows:vars]
 ansible_user=localadmin ## ansible与之通信的Windows用户名
 ansible_password=s3crect ## ansible与之通信的Windows密码
 ansible_connection=winrm ## ansible将与远程Windows节点建立的连接类型
 ansible_winrm_server_cert_validation=ignore ## 忽略证书验证,因为我们将使用Ansible附带的自签名证书

5. 现在,使用 Ansible 的 \texttt{win_ping} 模块来执行对步骤#3中定义的 \texttt{windows} 主机组内主机的简单连接测试。

# windows 是主机组
# -m 告诉 Ansible 使用 win_ping 模块
 ansible windows -m win_ping

执行后,您可以看到 Ansible 返回绿色文本,并显示成功消息,指示成功的 ping 尝试。

Successful win_ping connection

输出确认了 Ansible 控制主机可以通过 WinRM 与 Windows 远程主机成功通信。

在 Windows 主机上运行临时命令

此时,您已准备好让 Ansible 开始控制您的 Windows 节点。现在,让我们通过在 Windows 节点上运行一个临时命令来测试一下。在不需要首先创建 playbook 的情况下,在节点上运行简单的命令时,临时命令非常有用。

我们将通过在清单文件中定义的 \texttt{windows} 主机组中安装 Windows 功能来演示临时命令。为此,假设您仍然连接到 Ansible 控制节点的 SSH 中:

1. 本次不使用 win_ping 模块,而是调用 win_feature 模块-m),传递两个参数(-a),分别是 namestate,表示要安装的Windows功能的名称和所需状态。

# 这里的 windows 是一组主机
# win_feature 是模块的名称
# state=present 表示安装该包或服务
 ansible windows -m win_feature -a "name=Telnet-Client state=present"

运行上述命令时,如果一切顺利,Ansible 应连接到 windows 主机组中的所有节点,并在每个节点上运行 win_feature 命令,检查并安装 Telnet-Client Windows 功能,如果尚未安装。

Ansible Windows Feature

2. Ansible 显示成功,但为了确保,手动使用 PowerShell 连接到 Windows 节点,并验证 Telnet Client Windows 功能是否已安装。在本地 Windows 工作站上运行 Invoke-Command 来运行每台 Windows 计算机上的 Get-WindowsFeature PowerShell 命令。

Invoke-Command -ComputerName 52.242.251.213, 10.111.4.106 -ScriptBlock { Get-WindowsFeature -Name 'Telnet-Service' } -Credential (Get-Credential -UserName adminuser)

此时,您可以运行 任何 Windows 模块 作为即席命令!

创建和运行 Windows Playbooks 的 Ansible

一旦您掌握了在Windows管理节点上运行临时命令的技巧,您的下一个任务就是创建和运行playbooks。Ansible playbook将命令组合到一个位置,并允许您编写复杂逻辑来执行复杂的自动化场景。

使用win_command模块运行远程Windows命令

假设您仍然连接到您的Ansible控制主机:

1. 在您的主目录下创建一个名为ansible-windows-demo的文件夹,并切换到该文件夹。该文件夹将保存您的playbook。

mkdir ~/ansible-windows-demo 
cd ~/ansible-windows-demo 

2. 打开您喜欢的文本编辑器,创建并保存一个名为ansible-windows.yml的文件,保存在~/ansible-windows-demo目录中。

Ansible playbooks使用YAML编写。

3. 现在,将以下playbook复制到ansible-windows.yml文件中,以创建一个单独的任务。该playbook将使用win_command Windows Ansible模块windows主机组内的所有主机上执行netstat Windows命令。

win_command模块在Windows远程主机上执行命令。它不允许包含变量的命令,如特殊字符、换行符、大于号等。

---
 - name: Ansible win_command module example  
   hosts: windows # 在哪个主机组上运行该模块
   tasks: 
   -  name: run an executable command on a remote Windows system
      win_command: netstat -e # win_command是一个Windows模块。

4. 调用ansible-windows.yml剧本,通过运行以下命令在远程主机上执行任务。

ansible-playbook ansible-windows.yml

如果一切顺利,您应该看到以下输出。

Ansible successfully executed the netstat command using win_command module

使用win_shell模块运行远程PowerShell命令

在前面的示例中,您创建了一个剧本来在Windows管理节点上运行远程cmd.exe命令(netstat)。现在让我们提高一点难度,使用win_shell模块来运行PowerShell命令。

默认情况下,win_shell模块在Windows主机上运行PowerShell。

在您的本地Windows工作站:

首先,在本地 Windows 工作站上打开您喜欢的文本编辑器,并创建一个示例的 PowerShell 脚本,将以下代码复制到其中,并保存为 one.ps1。本教程将把脚本保存到 ~\one.ps1

下面的代码将在 C:\temp 目录中创建一个名为 test2.txt 的空文本文件。

Set-Content -Path C:\temp\test2.txt -Value ''

然后,使用您喜欢的方法将 one.ps1 PowerShell 脚本复制到 Windows 受控节点。本教程将假定您已将 one.ps1 脚本复制到每个 Windows 节点上的 C:\Temp 文件夹。

当示例 PowerShell 脚本位于 Windows 节点上时,连接到您的 Ansible 控制器主机,再次打开您喜欢的文本编辑器。这次,创建并保存另一个名为 ansible-windows-shell.yml 的 playbook,保存在相同的 ~/ansible-windows-demo 目录中。

复制并粘贴以下 playbook 到 ansible-windows-shell.yml 文件中。此 playbook 将运行两个任务,演示 win_shell 模块。它调用从步骤#2 复制的 PowerShell 脚本,并将 PowerShell 代码直接插入到 playbook 中,以演示根本不需要脚本。

要传递多行的 PowerShell 代码到 win_shell 模块,请使用 | 管道字符。

---
 - name: Ansible win_shell module example 
   remote_user: localadmin # 本地 Windows 用户连接
   hosts: windows # 远程主机组
   tasks:
    - name: Single line PowerShell # 使用 win_shell 模块运行单个命令
      win_shell: C:\temp\one.ps1
    - name: Run multi-lined shell commands 
      win_shell: |
        $text = ' Iam Author of ATA'
       Set-Content -Path C:\temp\test3.txt -Value $text 

5. 现在,调用第二个 playbook ansible-windows-shell.yml,在远程主机上执行,但使用 PowerShell。

ansible-playbook ansible-windows-shell.yml
ansible-playbook ansible-windows-shell.yml

6. 如果需要,在本地 Windows 工作站上验证 playbook 执行了现有脚本和 playbook 中的 PowerShell 代码。

Invoke-Command -ComputerName 52.242.251.213, 10.111.4.106 -ScriptBlock { Test-Path -Path 'C:\Temp\test3.txt','C:\Temp\test2.txt' } -Credential (Get-Credential -UserName adminuser)

如果 Ansible playbook 成功运行,PowerShell 应返回两个 True 语句,表示文件现在已存在。

结论

在本教程中,您学会了如何在 Ansible 中设置第一个 Windows 托管节点。尽管 Ansible 传统上被认为是 Linux 工具,但它也可以轻松用于 Windows!

你将使用哪些 playbook 和 Windows 模块 来管理 Ansible 的 Windows?

Source:
https://adamtheautomator.com/ansible-on-windows/