Amazon Web Services 指南

amazon.aws 集合包含许多用于控制 Amazon Web Services (AWS) 的模块和插件。本指南介绍如何使用这些模块和清单脚本来自动化您的 AWS 资源。

AWS 模块的要求极低。

所有模块都需要并针对最新版本的 botocore 和 boto3 进行测试。从 2.0 版 AWS 集合开始,集合的策略通常是支持在最新主要集合版本发布前 12 个月发布的这些库版本。各个模块可能需要更新的库版本才能支持特定功能,或者可能需要 boto 库,请检查模块文档以了解每个模块所需的最低版本。您必须在控制机器上安装 boto3 Python 模块。您可以从您的操作系统发行版或使用 python 包安装程序安装这些模块:pip install boto3

从 2.0 版的两个集合开始,将根据 AWS 的Python 2.7 支持结束公告结束 Python 2.7 支持,并将需要 Python 3.6 或更高版本。

虽然 Ansible 通常会在其主机循环中针对多台远程机器执行任务,但大多数云控制步骤都在您的本地机器上执行,并参考要控制的区域。

在您的 playbook 步骤中,我们通常会对配置步骤使用以下模式

- hosts: localhost
  gather_facts: False
  tasks:
    - ...

身份验证

与 AWS 相关的模块的身份验证通过指定您的访问密钥和密钥作为环境变量或模块参数来处理。

对于环境变量

export AWS_ACCESS_KEY_ID='AK123'
export AWS_SECRET_ACCESS_KEY='abc123'

对于将这些存储在 vars_file 中,理想情况下使用 ansible-vault 加密

---
aws_access_key: "--REMOVED--"
aws_secret_key: "--REMOVED--"

请注意,如果您将凭据存储在 vars_file 中,则需要在每个 AWS 模块中引用它们。例如

- amazon.aws.ec2_instance:
    aws_access_key: "{{ aws_access_key }}"
    aws_secret_key: "{{ aws_secret_key }}"
    key_name: "example-ssh-key"
    image_id: "..."

或者它们可以在 playbook 的顶部使用“module_defaults”指定。

# demo_setup.yml

- hosts: localhost
  module_defaults:
    group/aws:
      aws_access_key: '{{ aws_access_key }}'
      aws_secret_key: '{{ aws_secret_key }}'
      region: '{{ region }}'
  tasks:
    - amazon.aws.ec2_instance:
        key_name: "example-ssh-key"
        image_id: "..."

凭据也可以从凭据配置文件访问。

- amazon.aws.ec2_instance:
    aws_profile: default
    key_name: "example-ssh-key"
    image_id: "..."

配置

ec2_instance 模块配置和取消配置 EC2 中的实例。

以下是创建具有分配的公共 IP 的实例的示例。

“name”参数将在实例上创建一个“tag:Name”标签。可以使用“tags”参数指定其他标签。

# demo_setup.yml

- hosts: localhost
  gather_facts: False

  tasks:

    - name: Provision an EC2 instance with a public IP address
      amazon.aws.ec2_instance:
        name: Demo
        key_name: "example-ssh-key"
        vpc_subnet_id: subnet-5ca1ab1e
        instance_type: c5.large
        security_group: default
        network:
          assign_public_ip: true
        image_id: ami-123456
        tags:
          Environment: Testing
      register: result

已创建的实例数据通过名为“result”的变量中的“register”关键字保存。

由此,我们将使用 add_host 模块动态创建由这些新实例组成的主机组。这有助于在后续任务中立即对主机执行配置操作。

# demo_setup.yml

- hosts: localhost
  gather_facts: False

  tasks:

    - name: Provision an EC2 instance with a public IP address
      amazon.aws.ec2_instance:
        name: Demo
        key_name: "example-ssh-key"
        vpc_subnet_id: subnet-5ca1ab1e
        instance_type: c5.large
        security_group: default
        network:
          assign_public_ip: true
        image_id: ami-123456
        tags:
          Environment: Testing
      register: result

   - name: Add all instance public IPs to host group
     add_host: hostname={{ item.public_ip }} groups=ec2hosts
     loop: "{{ result.instances }}"

现在主机组已创建,同一个配置 playbook 文件底部的第二个 play 现在可能有一些配置步骤

# demo_setup.yml

- name: Provision a set of instances
  hosts: localhost
  # ... AS ABOVE ...

- hosts: ec2hosts
  name: configuration play
  user: ec2-user
  gather_facts: true

  tasks:

     - name: Check NTP service
       service: name=ntpd state=started

安全组

AWS 上的安全组是有状态的。无论入站安全组规则如何,来自您实例的请求的响应都允许流入,反之亦然。如果您只想允许与 AWS S3 服务的流量,则需要获取一个区域的 AWS S3 的当前 IP 范围并将其应用为出站规则。

- name: fetch raw ip ranges for aws s3
  set_fact:
    raw_s3_ranges: "{{ lookup('aws_service_ip_ranges', region='eu-central-1', service='S3', wantlist=True) }}"

- name: prepare list structure for ec2_group module
  set_fact:
    s3_ranges: "{{ s3_ranges | default([]) + [{'proto': 'all', 'cidr_ip': item, 'rule_desc': 'S3 Service IP range'}] }}"
  loop: "{{ raw_s3_ranges }}"

- name: set S3 IP ranges to egress rules
  ec2_group:
    name: aws_s3_ip_ranges
    description: allow outgoing traffic to aws S3 service
    region: eu-central-1
    state: present
    vpc_id: vpc-123456
    purge_rules: true
    purge_rules_egress: true
    rules: []
    rules_egress: "{{ s3_ranges }}"
    tags:
      Name: aws_s3_ip_ranges

主机清单

节点启动后,您可能希望再次与它们通信。使用云设置时,最好不要在文本文件中维护云主机名的静态列表。相反,最好的方法是使用 aws_ec2 清单插件。请参阅使用动态清单

该插件还将返回在 Ansible 之外创建的实例,并允许 Ansible 管理它们。

标签、组和变量

使用清单插件时,您可以根据 AWS 返回的元数据配置额外的清单结构。

例如,您可以使用keyed_groups根据实例标签创建组

plugin: amazon.aws.aws_ec2
keyed_groups:
  - prefix: tag
    key: tags

然后,您可以在 play 中定位所有值为“webserver”的“class”标签的实例

- hosts: tag_class_webserver
  tasks:
    - ping

您还可以将这些组与“group_vars”一起使用,以设置自动应用于匹配实例的变量。

使用 Ansible Pull 进行自动缩放

Amazon 自动缩放功能会根据负载自动增加或减少容量。云文档中还显示了可以配置自动缩放策略的 Ansible 模块。

当节点上线时,等待下一个 ansible 命令周期到来并配置该节点可能还不够。

为此,请预先烘焙包含必要的 ansible-pull 调用的机器镜像。Ansible-pull 是一个命令行工具,它从 git 服务器获取 playbook 并将其在本地运行。

这种方法的挑战之一是需要一种集中式方法来存储有关自动缩放上下文中的 pull 命令结果的数据。因此,下一节中提供的自动缩放解决方案可能是一种更好的方法。

有关拉模式剧本的更多信息,请阅读ansible-pull

使用 Ansible 自动化平台进行自动缩放

Ansible 自动化平台 (AAP) 还包含一个非常适合自动缩放用例的特性。在此模式下,简单的 curl 脚本可以调用定义的 URL,服务器将“拨出”到请求者并配置正在启动的实例。这对于重新配置临时节点非常有用。有关更多详细信息,请参阅安装和产品文档。

与拉模式相比,在 AAP 中使用回调的好处在于作业结果仍然被集中记录,并且需要与远程主机共享的信息更少。

Ansible 与(以及对比)CloudFormation

CloudFormation 是一种 Amazon 技术,用于将云堆栈定义为 JSON 或 YAML 文档。

在许多示例中,Ansible 模块提供的接口比 CloudFormation 更易于使用,无需定义复杂的 JSON/YAML 文档。这对于大多数用户来说是推荐的做法。

但是,对于已决定使用 CloudFormation 的用户,可以使用 Ansible 模块将 CloudFormation 模板应用于 Amazon。

当将 Ansible 与 CloudFormation 一起使用时,通常 Ansible 将与 Packer 等工具一起用于构建镜像,而 CloudFormation 将启动这些镜像,或者在镜像上线后将通过用户数据调用 Ansible,或者两者结合使用。

有关更多详细信息,请参阅 Ansible CloudFormation 模块中的示例。

使用 Ansible 构建 AWS 镜像

许多用户可能希望镜像启动到更完整的配置,而不是在实例化后完全配置它们。为此,可以使用许多程序与 Ansible 剧本一起定义和上传基础镜像,然后该镜像将获得自己的 AMI ID,用于与 ec2 模块或其他 Ansible AWS 模块(如 ec2_asg 或 cloudformation 模块)一起使用。可能的工具包括 Packer、aminator 和 Ansible 的 ec2_ami 模块。

一般来说,我们发现大多数用户使用 Packer。

请参阅 Packer 文档中的Ansible 本地 Packer 预配置程序Ansible 远程 Packer 预配置程序

如果您目前不想采用 Packer,则在配置后使用 Ansible 配置基础镜像(如上所示)是可以接受的。

下一步:探索模块

Ansible 附带大量模块,用于配置各种各样的 EC2 服务。浏览模块文档的“云”类别以获取完整的列表和示例。

另请参阅

集合索引

浏览现有的集合、模块和插件

使用剧本

剧本简介

控制任务运行位置:委托和本地操作

委托,对于处理负载均衡器、云和本地执行步骤非常有用。