自动化节省 AWS 账单费用的两种简单方法
自动化节省 AWS 账单费用的两种简单方法
Red Hat Ansible Automation Platform 是一款用于公共云的优秀的自动化和编排工具。在这篇文章中,我将介绍 Ansible Automation Platform 可以提供帮助的两种常见场景。我想跳出常见的公共云用例(例如资源的供应和取消供应),而是看看如何自动化常见的运维任务。
什么是运维任务?它只是管理员除了创建和删除云资源(例如实例、网络、密钥等)之外需要执行的任何操作,以帮助维护其公司的公共云帐户。我遇到的问题之一是实例被遗留在后台运行,从而增加了我们的公共云账单,而我们却将注意力集中在其他地方。用户越多,出现问题的可能性就越大;自动化可以帮助解决这些问题并保持对帐户的控制。这里我想解决两个常见的场景
- 为一次性计划手动创建的定制 AWS 实例,通常用于测试某些内容,然后忘记了这些实例并将其保持运行状态。
- 每次将 Pull Request (PR) 推送到我们的项目时,都会启动持续集成 (CI) 实例以以编程方式测试更改,并且有时会遇到某些情况,导致并非所有内容都正确地取消了供应(关闭)。
在这两种情况下,孤立的实例都可能长时间保持运行状态。假设您启动了几十个实例来在公共云上测试某些内容,然后您忙了起来,忘记了时间,并在下班前忘记终止这些实例。这可能是 16 小时(至少)的时间,您在此期间被收取费用,并且没有从您的公司正在资助的公共云中获得任何价值。现在将此乘以数十个用户,该账单可能会很快达到数万美元。
用例一:处理定制的孤立实例
因此,让我们解决每个问题,并使用 Ansible Automation Platform 自动化上述第一个场景的解决方案,其中实例在任何自动化防护栏之外启动(即,它们不使用任何自动化工具,包括 Ansible,来启动云资源)。我们要求团队中所有可以访问公共云帐户的人员标记其实例。他们必须创建一个键值对标签,内容为:owner: person
这创建了一种非常简单的方法来审计和查看谁(哪个人、组织或团队)对账单负责,这是成功的一半。我将编写一个非常简单的 Ansible Playbook 来强制执行此操作。我将使用完全受支持的 amazon.aws 集合来演示这一点。
- amazon.aws
- 在 Ansible Automation Hub 上完全支持下游内容
- 在 Ansible Galaxy 上找到上游代码
此处社区集合和受支持集合之间的主要区别在于您 Red Hat 订阅的支持。对于作为 Red Hat 订阅一部分包含的完全受支持的 amazon.aws 集合,还进行了大量的集成测试、代码审计和 Python 3/boto3 支持。
处理未标记的实例
在我的第一个 Ansible Playbook 中,我想获取所有没有标签的实例列表。首先,让我们检索特定区域中所有正在运行的实例
- name: grab info for un-tagged instances amazon.aws.ec2_instance_info: region: "{{ ec2_region }}" filters: instance-state-name: running register: ec2_node_info
我正在使用 AWS 集合中找到的 ec2_instance_info 模块,它是 Amazon 命名空间的一部分。此任务检索所有实例(无论是否有标签)。我发现最简单的方法是获取所有内容,然后过滤掉空标签
- name: set the untagged to a var set_fact: untagged_instances: "{{ ec2_node_info.instances | selectattr('tags', 'equalto', {}) | map(attribute='instance_id') | list }}"
此 selectattr 过滤器只是匹配任何没有标签的实例,标签为 ['tags', 'equalto', {} ]
然后我可以简单地终止这些实例,因为我的同事没有遵循我制定的良好准则
- name: Terminate every un-tagged running instance in a region. amazon.aws.ec2: region: "{{ ec2_region }}" state: absent instance_ids: "{{ untagged_instances }}" when: untagged_instances | length > 0
但是,由于您可能比我更宽容,因此您可以使用 state: stopped
而不是 absent,这将关闭它们而不是终止它们。
检索任何缺少标签的实例
为了扩展上述内容,我们不仅关心完全未标记的实例(表示根本没有标签),而且我们特别关注 owner 标签。我现在想检索任何缺少 owner 标签的实例。我可以使用与上面完全相同的逻辑,但改为使用 selectattr 过滤器查找未定义的值。
- name: set the missing tag to a var set_fact: missing_tag: "{{ ec2_node_info.instances | selectattr('tags.owner', 'undefined') | map(attribute='instance_id') | list }}"
我想展示上面这两个示例,以提供一条实现操作化的路径。使用 Ansible Automation Platform 实现上述操作,您的组织现在可以理解,他们需要使用标签,否则他们的实例将被关闭(或更糟!)。更进一步,组织可以使用自动化来强制执行特定的标签以分配所有权,或者将对实例采取措施。您可以使用上述一个或两个示例。
用例二:处理自动化的实例
对于我的特定用例,我有一个代码存储库,该存储库会自动进行测试。我们的代码每晚都会进行测试,并且每次将 Pull Request (PR) 推送到代码存储库时都会进行测试。CI 测试将在 AWS 上配置实例,配置实例,运行自动化测试,然后取消其配置。有时,取消配置步骤将无法成功完成,从而导致孤立的主机。我注意到的一件事是,这些实例通常会被发现部分关闭,它们的标签完全丢失(已删除),但实例实际上并未关闭,因此我们仍在被收取费用。前面的示例中的上述 Ansible Playbook 可以捕获这种情况。
但是,另一个很棒的测试是使用新的正常运行时间参数。
- name: grab info amazon.aws.ec2_instance_info: region: "{{ ec2_region }}" uptime: 121 filters: instance-state-name: [ "running" ] "tag:ansible-workshops": true register: ec2_node_info
在此任务中,我想重点介绍两个参数。第一个是正常运行时间参数(在 amazon.aws 的 1.4.0 中添加),它只返回运行时间超过该整数(以分钟为单位)的实例。对于此示例,它必须运行超过 121 分钟,或超过两个小时。我知道我的 CI 测试永远不应该花费超过两个小时。要么实例卡住了,要么我的自动化测试坏了,要么取消配置没有成功。
此处另一个标签只是一个过滤器,以便我只返回属于我的自动化测试(相对于其他计划)的实例。在此示例中,它必须是 workshop。现在,您应该明白为什么我需要在开头使用“未标记”示例!如果根本没有标签,则整个运维任务将失败。因此,由于标签在公共云基础设施中的重要性,因此“无标签”用例与每个其他用例都重叠。
自动化自动化
因此,这种自动化非常棒,但是手动运行 playbook 只能节省您少量时间。我继续使用 Ansible 工作流 功能一次性访问多个区域,然后对其进行计划,以便我的自动化作业每小时运行一次。
右侧的每个矩形代表一个自动化 作业。同一列中的每个作业都在我的 Ansible Automation Platform 集群上并行运行。每个作业模板都设置为不同的区域。我还使用了 调查功能 使得从 Web UI 中轻松配置。
在我的特定场景中,我在四个 AWS 区域(us-east-1、ap-northeast-1、ap-southeast-1 和 eu-central-1)中运行自动化测试。现在我的工作流已完成,安排我的工作流每小时运行一次非常简单。
瞧!现在我在后台进行了自动化测试,以确保没有孤立的实例正在运行。对于我的特定用例,这将节省大量资金,并强制在公共云使用方面形成一种问责制文化,以便团队成员之间能够清楚透明地了解成本。