Ansible Windows模块的使用与实践
1. 引言
Ansible是一款强大的自动化工具,在管理和配置系统方面表现出色。本文将详细介绍如何使用Ansible Windows模块,包括收集主机信息、安装Web服务器、启用ASP.NET支持,以及在AWS上创建Windows实例并进行相关配置。
2. 收集主机信息
2.1 setup模块
setup模块用于收集目标主机的信息。使用
ansible
命令直接调用该模块,信息将直接显示在屏幕上。具体命令如下:
$ ansible windows -i production -m setup
2.2 使用playbook显示信息
我们可以使用playbook来显示收集到的信息。以下是一个示例
playbook01.yml
:
---
- hosts: windows
gather_facts: true
tasks:
- debug:
msg: "I am connecting to {{ ansible_nodename }} which is running {{ ansible_distribution }} {{ ansible_distribution_version }}"
运行该playbook的命令为:
$ ansible-playbook -i production playbook01.yml
3. 安装Web服务器
3.1 创建基本结构
首先,我们需要创建基本的文件夹结构和文件:
$ mkdir web web/group_vars web/roles
$ touch web/production web/site.yml web/group_vars/common.yml
3.2 IIS角色
3.2.1 创建角色
进入
web
文件夹并创建
iis
角色:
$ cd web
$ ansible-galaxy init roles/iis
3.2.2 配置默认变量
在
roles/iis/defaults/main.yml
中配置默认变量:
---
# defaults file for web/roles/iis
document_root: 'C:\inetpub\wwwroot\'
html_file: ansible.html
html_heading: "Success !!!"
html_body: |
This HTML page has been deployed using Ansible to a <b>{{ ansible_distribution }}</b> host.<br><br>
The weboot is <b>{{ document_root }}</b> this file is called <b>{{ html_file }}</b>.<br>
3.2.3 模板文件
模板文件
roles/iis/templates/index.html.j2
内容如下:
<!--{{ ansible_managed }}-->
<!doctype html>
<title>{{ html_heading }}</title>
<style>
body { text-align: center; padding: 150px; }
h1 { font-size: 50px; }
body { font: 20px Helvetica, sans-serif; color: #333; }
article { display: block; text-align: left; width: 650px; margin: 0 auto; }
</style>
<article>
<h1>{{ html_heading }}</h1>
<div>
<p>{{ html_body }}</p>
</div>
</article>
3.2.4 任务配置
在
roles/iis/tasks/main.yml
中配置任务:
- name: enable IIS
win_feature:
name:
- "Web-Server"
- "Web-Common-Http"
state: "present"
- name: create an html file from a template
win_template:
src: "index.html.j2"
dest: "{{ document_root }}{{ html_file }}"
3.2.5 运行playbook
更新
site.yml
文件:
---
- hosts: windows
gather_facts: true
vars_files:
- group_vars/common.yml
roles:
- roles/iis
运行playbook的命令为:
$ ansible-playbook -i production site.yml
完成后,在本地浏览器中访问
http://localhost:8080/
将显示默认的IIS页面,访问
http://localhost:8080/ansible.html
将显示我们上传的页面。
3.3 ASP.NET角色
3.3.1 创建角色
创建
asp
角色:
$ ansible-galaxy init roles/asp
3.3.2 配置默认变量
在
roles/asp/defaults/main.yml
中配置默认变量:
aspx_document_root: 'C:\inetpub\wwwroot\ansible\'
aspx_file: default.aspx
aspx_heading: "Success !!!"
aspx_body: |
This HTML page has been deployed using Ansible to a <b>{{ ansible_distribution }}</b> host.<br><br>
The weboot is <b>{{ aspx_document_root }}</b> this file is called <b>{{ aspx_file }}</b>.<br><br>
The output below is from ASP.NET<br><br>
Hello from <%= Environment.MachineName %> at <%= DateTime.UtcNow %>.<br><br>
3.3.3 模板文件
模板文件
roles/asp/templates/default.aspx.j2
内容如下:
<!--{{ ansible_managed }}-->
<!doctype html>
<title>{{ html_heading }}</title>
<style>
body { text-align: center; padding: 150px; }
h1 { font-size: 50px; }
body { font: 20px Helvetica, sans-serif; color: #333; }
article { display: block; text-align: left; width: 650px; margin: 0 auto; }
</style>
<article>
<h1>{{ aspx_heading }}</h1>
<div>
<p>{{ aspx_body }}</p>
</div>
</article>
3.3.4 任务配置
在
roles/asp/tasks/main.yml
中配置任务:
- name: enable .net
win_feature:
name:
- "Net-Framework-Features"
- "Web-Asp-Net45"
- "Web-Net-Ext45"
state: "present"
notify: restart iis
- name: create the folder for our asp.net app
win_file:
path: "{{ aspx_document_root }}"
state: "directory"
- name: create an aspx file from a template
win_template:
src: "default.aspx.j2"
dest: "{{ aspx_document_root }}{{ aspx_file }}"
- name: ensure the default web application exists
win_iis_webapplication:
name: "Default"
state: "present"
physical_path: "{{ aspx_document_root }}"
application_pool: "DefaultAppPool"
site: "Default Web Site"
3.3.5 重启IIS
在
roles/asp/handlers/main.yml
中添加重启IIS的任务:
- name: restart iis
win_service:
name: w3svc
state: restarted
3.3.6 运行playbook
更新
site.yml
文件:
---
- hosts: windows
gather_facts: true
vars_files:
- group_vars/common.yml
roles:
- roles/iis
- roles/asp
运行playbook的命令为:
$ ansible-playbook -i production site.yml
打开浏览器访问
http://localhost:8080/ansible/
将显示相应的页面。
4. 与AWS Windows实例交互
4.1 创建文件夹结构
创建新的文件夹结构和文件:
$ mkdir cloud cloud/group_vars cloud/roles
$ touch cloud/production cloud/site.yml cloud/group_vars/common.yml
4.2 AWS角色
4.2.1 创建角色
进入
cloud
文件夹并创建
aws
角色:
$ cd cloud
$ ansible-galaxy init roles/aws
4.2.2 配置默认变量
在
roles/aws/defaults/main.yml
中配置默认变量:
vpc_cidr_block: "10.0.0.0/16"
the_subnets:
- { use: 'ec2', az: 'a', subnet: '10.0.10.0/24' }
ec2:
instance_type: "t2.large"
wait_port: "5986"
image:
base: Windows_Server-2016-English-Full-Base-*
owner: amazon
architecture: x86_64
root_device: ebs
win_initial_password: "{{ lookup('password', 'group_vars/generated_administrator chars=ascii_letters,digits length=30') }}"
4.2.3 任务配置
在
roles/aws/tasks/main.yml
中配置任务:
- name: ensure that the VPC is present
ec2_vpc_net:
region: "{{ ec2_region }}"
name: "{{ environment_name }}"
state: present
cidr_block: "{{ vpc_cidr_block }}"
resource_tags: { "Name" : "{{ environment_name }}", "Environment" : "{{ environment_name }}" }
register: vpc_info
- name: ensure that the subnets are present
ec2_vpc_subnet:
region: "{{ ec2_region }}"
state: present
vpc_id: "{{ vpc_info.vpc.id }}"
cidr: "{{ item.subnet }}"
az: "{{ ec2_region }}{{ item.az }}"
resource_tags:
"Name" : "{{ environment_name }}_{{ item.use }}_{{ ec2_region }}{{ item.az }}"
"Environment" : "{{ environment_name }}"
"Use" : "{{ item.use }}"
with_items: "{{ the_subnets }}"
- name: gather information about the ec2 subnets
ec2_vpc_subnet_facts:
region: "{{ ec2_region }}"
filters:
"tag:Use": "ec2"
"tag:Environment": "{{ environment_name }}"
register: subnets_ec2
- name: register just the IDs for each of the subnets
set_fact:
subnet_ec2_ids: "{{ subnets_ec2.subnets | map(attribute='id') | list }}"
- name: find out your current public IP address using https://ipify.org/
ipify_facts:
register: public_ip
- name: set your public ip as a fact
set_fact:
your_public_ip: "{{ public_ip.ansible_facts.ipify_public_ip }}/32"
- name: provision ec2 security group
ec2_group:
region: "{{ ec2_region }}"
vpc_id: "{{ vpc_info.vpc.id }}"
name: "{{ environment_name }}-ec2"
description: "Opens the RDP and WinRM ports to a trusted IP"
tags:
"Name": "{{ environment_name }}-ec2"
"Environment": "{{ environment_name }}"
rules:
- proto: "tcp"
from_port: "3389"
to_port: "3389"
cidr_ip: "{{ your_public_ip }}"
rule_desc: "allow {{ your_public_ip }} access to port RDP"
- proto: "tcp"
from_port: "5985"
to_port: "5985"
cidr_ip: "{{ your_public_ip }}"
rule_desc: "allow {{ your_public_ip }} access to WinRM"
- proto: "tcp"
from_port: "5986"
to_port: "5986"
cidr_ip: "{{ your_public_ip }}"
rule_desc: "allow {{ your_public_ip }} access to WinRM"
register: sg_ec2
- name: ensure that there is an internet gateway
ec2_vpc_igw:
region: "{{ ec2_region }}"
vpc_id: "{{ vpc_info.vpc.id }}"
state: present
tags:
"Name": "{{ environment_name }}_internet_gateway"
"Environment": "{{ environment_name }}"
"Use": "gateway"
register: igw_info
- name: check that we can route through internet gateway
ec2_vpc_route_table:
region: "{{ ec2_region }}"
vpc_id: "{{ vpc_info.vpc.id }}"
subnets: "{{ subnet_ec2_ids }}"
routes:
- dest: 0.0.0.0/0
gateway_id: "{{ igw_info.gateway_id }}"
resource_tags:
"Name": "{{ environment_name }}_outbound"
"Environment": "{{ environment_name }}"
- name: search for all of the AMIs in the defined region which match our selection
ec2_ami_facts:
region: "{{ ec2_region }}"
owners: "{{ image.owner }}"
filters:
name: "{{ image.base }}"
architecture: "{{ image.architecture }}"
root-device-type: "{{ image.root_device }}"
register: amiFind
- name: filter the list of AMIs to find the latest one with an EBS backed volume
set_fact:
amiSortFilter: "{{ amiFind.images | sort(attribute='creation_date') | last }}"
- name: finally grab AMI ID of the most recent result which matches our base image which is backed by an EBS volume
set_fact:
our_ami_id: "{{ amiSortFilter.image_id }}"
- name: launch an instance
ec2_instance:
region: "{{ ec2_region }}"
state: "present"
instance_type: "{{ ec2.instance_type }}"
image_id: "{{ our_ami_id }}"
wait: yes
security_groups: [ "{{ sg_ec2.group_id }}" ]
network:
assign_public_ip: true
filters:
instance-state-name: "running"
"tag:Name": "{{ environment_name }}"
"tag:environment": "{{ environment_name }}"
vpc_subnet_id: "{{ subnet_ec2_ids[0] }}"
user_data: "{{ lookup('template', 'userdata.j2') }}"
tags:
Name: "{{ environment_name }}"
environment: "{{ environment_name }}"
- name: gather facts on the instance we just launched using the AWS API
ec2_instance_facts:
region: "{{ ec2_region }}"
filters:
instance-state-name: "running"
"tag:Name": "{{ environment_name }}"
"tag:environment": "{{ environment_name }}"
register: singleinstance
- name: add our temporary instance to a host group for use in the next step
add_host:
name: "{{ item.public_dns_name }}"
ansible_ssh_host: "{{ item.public_dns_name }}"
groups: "ec2_instance"
with_items: "{{ singleinstance.instances }}"
- name: wait until WinRM is available before moving onto the next step
wait_for:
host: "{{ item.public_dns_name }}"
port: "{{ ec2.wait_port }}"
delay: 2
timeout: 320
state: "started"
with_items: "{{ singleinstance.instances }}"
4.2.4 用户数据模板
roles/aws/templates/userdata.j2
模板内容如下:
<powershell>
$admin = [adsi]("WinNT://./administrator, user")
$admin.PSBase.Invoke("SetPassword", "{{ win_initial_password }}")
Invoke-Expression ((New-Object System.Net.Webclient).DownloadString('https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1'))
</powershell>
4.3 用户角色
4.3.1 创建角色
创建
user
角色:
$ ansible-galaxy init roles/user
4.3.2 配置默认变量
在
roles/user/defaults/main.yml
中配置默认变量:
ansible:
username: "ansible"
password: "{{ lookup('password', 'group_vars/generated_ansible chars=ascii_letters,digits length=30') }}"
groups:
- "Users"
- "Administrators"
4.3.3 任务配置
在
roles/user/tasks/main.yml
中配置任务:
- name: ensure that the ansible created users are present
win_user:
name: "{{ ansible.username }}"
fullname: "{{ ansible.username | capitalize }}"
password: "{{ ansible.password }}"
state: "present"
groups: "{{ ansible.groups }}"
4.4 Chocolatey角色
4.4.1 创建角色
创建
choc
角色:
$ ansible-galaxy init roles/choc
4.4.2 配置默认变量
在
roles/choc/defaults/main.yml
中配置默认变量:
apps:
- "notepadplusplus.install"
- "putty.install"
- "googlechrome"
5. 总结
通过以上步骤,我们详细介绍了如何使用Ansible Windows模块进行主机信息收集、Web服务器安装、ASP.NET支持启用,以及在AWS上创建和配置Windows实例。希望这些内容能帮助你更好地使用Ansible管理Windows系统。
5.1 关键步骤总结
| 操作 | 步骤 |
|---|---|
| 收集主机信息 |
使用
setup
模块和playbook显示信息
|
| 安装Web服务器 | 创建基本结构,配置IIS和ASP.NET角色 |
| 与AWS实例交互 | 创建文件夹结构,配置AWS、用户和Chocolatey角色 |
5.2 流程图
graph TD;
A[开始] --> B[收集主机信息];
B --> C[安装Web服务器];
C --> D[与AWS实例交互];
D --> E[结束];
通过这些步骤和示例,你可以逐步掌握Ansible Windows模块的使用,提高系统管理的效率。
5.3 各角色功能与作用梳理
| 角色名称 | 功能概述 | 关键配置文件 | 主要任务 |
|---|---|---|---|
| IIS 角色 | 安装和配置 IIS 并上传 HTML 文件 |
roles/iis/defaults/main.yml
、
roles/iis/templates/index.html.j2
、
roles/iis/tasks/main.yml
| 启用 IIS 功能,使用模板创建 HTML 文件并部署 |
| ASP.NET 角色 | 启用 ASP.NET 支持并部署 ASPX 文件 |
roles/asp/defaults/main.yml
、
roles/asp/templates/default.aspx.j2
、
roles/asp/tasks/main.yml
、
roles/asp/handlers/main.yml
| 启用 .NET 相关功能,创建文件夹,使用模板创建 ASPX 文件,配置 IIS 中的 Web 应用程序,必要时重启 IIS |
| AWS 角色 | 创建 VPC 并启动 EC2 实例 |
roles/aws/defaults/main.yml
、
roles/aws/tasks/main.yml
、
roles/aws/templates/userdata.j2
| 设置 VPC、子网、安全组,查找合适的 AMI,启动 EC2 实例,注入用户数据脚本设置管理员密码和配置 WinRM |
| 用户角色 | 创建用于连接实例的用户 |
roles/user/defaults/main.yml
、
roles/user/tasks/main.yml
|
使用
win_user
模块创建用户并设置其属性
|
| Chocolatey 角色 | 使用 Chocolatey 安装软件 |
roles/choc/defaults/main.yml
| 定义要安装的软件包列表 |
5.4 操作步骤回顾与注意事项
5.4.1 收集主机信息
-
操作步骤
:
-
使用
ansible命令调用setup模块收集信息:ansible windows -i production -m setup。 -
使用 playbook 显示信息,编写
playbook01.yml并运行ansible-playbook -i production playbook01.yml。
-
使用
-
注意事项
:确保
production文件中正确配置了目标主机信息。
5.4.2 安装 Web 服务器
-
操作步骤
:
-
创建基本结构:
mkdir web web/group_vars web/roles和touch web/production web/site.yml web/group_vars/common.yml。 -
创建 IIS 角色并配置相关文件,更新
site.yml后运行ansible-playbook -i production site.yml。 -
创建 ASP.NET 角色并配置相关文件,更新
site.yml后再次运行ansible-playbook -i production site.yml。
-
创建基本结构:
- 注意事项 :在配置角色时,确保变量和模板文件的路径和内容正确,特别是在使用 Jinja2 模板时,要注意变量的引用和替换。
5.4.3 与 AWS 实例交互
-
操作步骤
:
-
创建文件夹结构:
mkdir cloud cloud/group_vars cloud/roles和touch cloud/production cloud/site.yml cloud/group_vars/common.yml。 -
创建 AWS 角色并配置相关文件,运行
ansible-playbook -i production site.yml启动实例。 -
创建用户角色和 Chocolatey 角色并配置相关文件,更新
site.yml后再次运行ansible-playbook -i production site.yml。
-
创建文件夹结构:
-
注意事项
:在 AWS 配置中,要确保
ec2_region和environment_name等变量正确设置,同时注意安全组的配置,只开放必要的端口。
5.5 进阶应用与拓展思路
5.5.1 多实例部署
可以通过修改
roles/aws/tasks/main.yml
中的任务,实现同时启动多个 EC2 实例。例如,修改
ec2_instance
模块的参数,设置
count
属性来指定实例数量。
- name: launch multiple instances
ec2_instance:
region: "{{ ec2_region }}"
state: "present"
instance_type: "{{ ec2.instance_type }}"
image_id: "{{ our_ami_id }}"
wait: yes
security_groups: [ "{{ sg_ec2.group_id }}" ]
network:
assign_public_ip: true
filters:
instance-state-name: "running"
"tag:Name": "{{ environment_name }}"
"tag:environment": "{{ environment_name }}"
vpc_subnet_id: "{{ subnet_ec2_ids[0] }}"
user_data: "{{ lookup('template', 'userdata.j2') }}"
tags:
Name: "{{ environment_name }}"
environment: "{{ environment_name }}"
count: 3 # 启动 3 个实例
5.5.2 软件包动态管理
在
roles/choc/defaults/main.yml
中,可以将软件包列表改为动态配置。例如,通过外部变量传入要安装的软件包列表。
apps: "{{ choc_apps | default(['notepadplusplus.install', 'putty.install', 'googlechrome']) }}"
在运行 playbook 时,可以通过
-e
参数传入不同的软件包列表:
$ ansible-playbook -i production site.yml -e "choc_apps=['firefox', '7zip']"
5.5.3 自动化监控与报警
可以结合 Ansible 和监控工具(如 Zabbix、Prometheus 等)实现自动化监控和报警。例如,在
roles/user/tasks/main.yml
中添加任务,安装监控客户端并配置监控项。
- name: install Zabbix agent
win_chocolatey:
name: zabbix-agent
state: present
- name: configure Zabbix agent
win_template:
src: "zabbix_agentd.conf.j2"
dest: "C:\Program Files\Zabbix Agent\zabbix_agentd.conf"
- name: start Zabbix agent service
win_service:
name: Zabbix Agent
state: started
5.6 总结与展望
通过本文的介绍,我们全面了解了如何使用 Ansible Windows 模块进行各种操作,从简单的主机信息收集到复杂的 AWS 实例创建和软件包安装。这些操作不仅提高了系统管理的效率,还为自动化运维提供了有力支持。
未来,随着云计算和自动化技术的不断发展,Ansible 的应用场景将更加广泛。我们可以进一步探索如何将 Ansible 与其他工具和技术集成,实现更高级的自动化任务,如持续集成/持续部署(CI/CD)、容器编排等。同时,不断优化 Ansible 脚本的性能和可维护性,确保系统的稳定运行。
5.7 新的流程图:包含进阶应用
graph TD;
A[开始] --> B[收集主机信息];
B --> C[安装 Web 服务器];
C --> D[与 AWS 实例交互];
D --> E[多实例部署];
D --> F[软件包动态管理];
D --> G[自动化监控与报警];
E --> H[结束];
F --> H;
G --> H;
通过以上的拓展和总结,我们可以更好地利用 Ansible Windows 模块,应对更复杂的系统管理需求。希望读者能够根据这些内容,结合实际情况进行实践和创新,提升自己的技术能力。
超级会员免费看
1061

被折叠的 条评论
为什么被折叠?



