24、Ansible Windows模块的使用与实践

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 收集主机信息
  • 操作步骤
    1. 使用 ansible 命令调用 setup 模块收集信息: ansible windows -i production -m setup
    2. 使用 playbook 显示信息,编写 playbook01.yml 并运行 ansible-playbook -i production playbook01.yml
  • 注意事项 :确保 production 文件中正确配置了目标主机信息。
5.4.2 安装 Web 服务器
  • 操作步骤
    1. 创建基本结构: mkdir web web/group_vars web/roles touch web/production web/site.yml web/group_vars/common.yml
    2. 创建 IIS 角色并配置相关文件,更新 site.yml 后运行 ansible-playbook -i production site.yml
    3. 创建 ASP.NET 角色并配置相关文件,更新 site.yml 后再次运行 ansible-playbook -i production site.yml
  • 注意事项 :在配置角色时,确保变量和模板文件的路径和内容正确,特别是在使用 Jinja2 模板时,要注意变量的引用和替换。
5.4.3 与 AWS 实例交互
  • 操作步骤
    1. 创建文件夹结构: mkdir cloud cloud/group_vars cloud/roles touch cloud/production cloud/site.yml cloud/group_vars/common.yml
    2. 创建 AWS 角色并配置相关文件,运行 ansible-playbook -i production site.yml 启动实例。
    3. 创建用户角色和 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 模块,应对更复杂的系统管理需求。希望读者能够根据这些内容,结合实际情况进行实践和创新,提升自己的技术能力。

<think>好的,用户现在想了解使用Ansible管理Windows主机的最佳实践,之前已经讨论过证书自动部署的问题。需要结合用户提供的四个引用内容,特别是引用1、3、4关于Ansible.Windows集合、安全实践和示例项目的信息。首先,用户提到的引用1指出需要安装ansible.windows集合,这是基础步骤,必须包含在最佳实践中。然后引用3提到了微信部署的例子,说明AnsibleWindows应用部署中的实际应用,可以借鉴其中的模块使用和流程设计。引用4的windows-playbook项目可能提供了一些具体的配置示例,需要参考其结构或方法。用户之前的问题涉及证书部署,现在扩展到更广泛的最佳实践,需要涵盖环境准备、安全配置、模块使用自动化流程、维护等方面。同时,要确保回答结构清晰,分点列出,并附上代码示例和相关问题。 需要确保回答中正确引用提供的引用内容,比如安装集合的部分引用[^1],安全实践引用[^2],应用部署引用[^3],配置指南引用[^4]。同时,用户可能关注如何保证Ansible操作的安全性,如加密通信、权限控制等,这些在引用2中提到过,需整合到最佳实践中。还要注意用户可能忽略的细节,比如WinRM的正确配置、模块的选择、幂等性设计等,这些是Ansible管理Windows的关键点。此外,生成的相关问题需要最佳实践相关,如如何优化性能、处理复杂应用部署等。最后,检查是否符合之前的系统指令,如LaTeX格式是否正确,引用标记是否自然添加,以及是否生成相关问题。需要确保回答真实可靠,结构清晰,帮助用户一步步解决问题。</think>### Ansible 管理 Windows 主机最佳实践 通过 Ansible 管理 Windows 主机需聚焦 **环境配置**、**安全通信**、**模块选择** 和 **自动化设计**,以下是关键实践方案: --- #### 一、环境配置初始化 1. **安装 Ansible.Windows 集合** AnsibleWindows 的支持通过 `ansible.windows` 集合实现,需先安装[^1]: ```bash ansible-galaxy collection install ansible.windows ``` 2. **配置 WinRM 通信** - 确保 Windows 主机启用 WinRM HTTPS 监听器 - 使用自签名证书或企业 CA 证书加密通信(参考前文证书部署方案) - 验证连接: ```bash ansible windows_servers -m win_ping ``` --- #### 二、安全实践 1. **通信加密** - 强制使用 HTTPS 协议而非 HTTP[^2] - 通过 `win_certificate_store` 模块管理证书,避免私钥泄露[^1] 2. **权限最小化** - 为 Ansible 执行账户分配最小权限(如 `Power Users` 组) - 使用 `become` 提权时限制特权范围: ```yaml - name: 以管理员身份运行命令 ansible.windows.win_command: whoami become: yes become_method: runas become_user: Administrator ``` --- #### 三、模块 Playbook 设计 1. **优先使用专用模块** - 文件管理:`win_copy`、`win_file` - 服务管理:`win_service` - 注册表操作:`win_regedit` ```yaml - name: 部署配置文件 ansible.windows.win_copy: src: config.ini dest: C:\App\config.ini force: yes # 幂等性设计 ``` 2. **幂等性保障** - 利用模块内置的幂等性检查(如 `state` 参数) - 通过 `changed_when` 自定义状态判断逻辑 --- #### 四、自动化流程示例 ```yaml # deploy_wechat.yml - name: 部署微信应用 hosts: windows_clients vars_files: - secrets/vault.yml # 加密的凭据文件 tasks: - name: 下载微信安装包 ansible.windows.win_get_url: url: "https://weixin.qq.com/download/WeChatSetup.exe" dest: C:\Temp\WeChatSetup.exe - name: 静默安装微信 ansible.windows.win_package: path: C:\Temp\WeChatSetup.exe arguments: /S # 静默安装参数 product_id: WeChat state: present - name: 清理临时文件 ansible.windows.win_file: path: C:\Temp\WeChatSetup.exe state: absent ``` *注:微信静默安装参数需根据实际安装包调整[^3]* --- #### 五、维护优化 1. **版本控制** - 将 Playbook 和配置纳入 Git 仓库管理(参考 [windows-playbook](https://gitcode.com/gh_mirrors/wi/windows-playbook) 项目结构[^4]) 2. **性能优化** - 使用 `async` 和 `poll` 参数实现异步任务 - 通过 `strategy: free` 允许并行执行任务 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值