AWS 认证 DevOps 工程师(二)

原文:annas-archive.org/md5/b44a68a3321a441a0fdffa7dcbaf1892

译者:飞龙

协议:CC BY-NC-SA 4.0

第四章:Amazon S3 Blob 存储

Amazon S3 是 Amazon Web Services 的核心组成部分之一。然而,在 DevOps 专业人员的上下文中,有一些关于该服务的细微差别,你不仅需要熟悉它们,还需要在实施时感到得心应手。

亚马逊的简单存储服务S3)是许多用户和公司进入云计算的入口。它提供的一些主要特点是高度可用、极其耐用、性能卓越并且易于管理,同时具备彻底的安全性。S3 的一个主要特点是其 11 个 9 的耐用性(99.999999999%),这意味着它不会丢失对象或数据。一旦你上传一个对象,在返回 200 成功状态之前,该对象必须复制到多个系统和多个可用区,以防止在各种场景下的数据丢失。

在本章中,我们将涵盖以下主要内容:

  • S3 概念

  • 在 S3 中使用生命周期策略

  • 使用 S3 事件触发其他 AWS 服务

  • S3 访问日志

  • S3 端点

S3 概念

在深入了解 S3 之前,让我们简要了解一下三种不同类型的云存储:

  • 对象存储 – 数据作为对象保存,并与该对象的相关元数据一起打包。

  • 文件存储 – 数据作为单个信息存储在文件夹结构中。

  • 块存储 – 数据和文件被分隔成块。每个块作为独立的数据片段进行存储。

S3 是一种对象存储服务,尽管它看起来有文件夹结构,但实际上这只是附加到对象上的元数据,通过键/值对的方式,使数据可以更高效地分类。

一旦创建了 S3 桶,不仅可以存储数据,而且此时它几乎是无限可扩展的。AWS 还创建了许多辅助服务,帮助你将数据迁移到 S3。它们包括像 Amazon Kinesis 这样的流式解决方案、AWS SFTP 等 SSH 文件传输协议SFTP)替代方案,甚至像 AWS Snowball 和 Snowball Edge 这样的批量数据加载服务:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_4.1_B17405.jpg

图 4.1 – 数据传输的 S3 选项

默认情况下,AWS 账户最多可以创建 100 个 S3 桶。这是一个软性限制,如果需要更多的桶,可以通过提交服务限制提升请求来增加该数量。

与 S3 的交互

用户有几种与 S3 交互的方式,从 AWS 控制台开始。通过它,你可以图形化地列出你的桶,并根据你为不同对象指定的标签,以文件夹形式展示你的对象。

随着您对 S3 及其功能的熟悉,您可能会发现,控制台需要多个点击才能执行诸如删除文件之类的简单操作,这时 CLI 和掌握其命令可以成为您的有力助手。

在 AWS CLI 中,有一些基础命令可以用来与 S3 交互:

  • 还有基础的 aws s3 命令——该命令使您能够执行九种基本操作,例如创建桶、列出桶或其内容,甚至创建一个预签名 URL 以访问桶。

  • 还有 aws s3api 命令——该命令为基础 s3 命令中的项目提供了一组不同的二级命令。

  • aws s3control 命令允许您对 S3 控制面板进行精细化访问。

  • 最后,还有 aws s3outposts 命令——该命令提供对 AWS Outposts 上 S3 的访问。

S3 命名指南

所有 AWS 上的 S3 桶名称必须是唯一的,不仅仅是在您的账户中。

创建桶时,您必须遵循一些规则,以确保名称符合 S3 的要求:

  • 桶名称的长度必须至少为 3 个字符,最多不超过 63 个字符。

  • 桶名称只能由数字、小写字母、点号 (.) 和连字符 (-) 组成。

  • 桶名称必须以数字或字母开头和结尾。

  • 桶名称不能以 xn– 开头。

  • 桶名称不能像 IP 地址那样格式化(例如 192.168.2.1)。

亚马逊还建议,除非您将 S3 桶用于静态网页托管,否则不要在桶名称中使用点号 (.)。

企业的桶名称

前述规则是命名 S3 桶的最低标准。随着您进入实际应用,大多数已经在 AWS 云中的大型组织都有桶命名方案。某些中小型企业仍然没有关于如何命名 S3 桶的组织标准,但这可能是一个错误。

S3 桶非常容易创建,不仅开发人员可以创建,几乎任何有权限访问该服务的人都可以创建。问题出现在您开始遇到像 mytest-bucket123 这样的桶名称时。再一次,这与最初的原则有关,即如何弄清楚谁是这些数据的拥有者,以及是否需要为了安全存储而复制这些数据,或是否可以安全删除。

随着您进入企业命名方案,您和您的组织需要就负责账户中桶的统一命名标准达成共识:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_4.2_B17405.jpg

图 4.2 – 企业桶命名示例

使用如 <region>-<environment>-<department>-<product>-<identifier> 这样的简化模式,可以为每个桶创建一个唯一的名称,并且仍然符合 AWS 的命名标准。

这有助于快速识别每个存储桶的所有者,并允许团队和账户管理员快速、轻松地排序和搜索资源,不仅能按产品或项目区分谁创建了存储桶。这在 图 4.2 中显示,并且存储桶名称为 oh-d-devops-pip-cont1。这个存储桶名称是 ohio-development-devops-pipeline-containers 的简写。

创建 S3 存储桶

如果您想备份实例,无论是为了恢复目的还是用于自动扩展中的启动配置,则需要创建一个 AMI 镜像:

  1. 启动一个 EC2 实例。

  2. 我们需要一个实例来备份并创建 AMI:

    $ aws s3 MB s3://devopspro-beyond –region us-east-2
    

    注意

    您需要使用与示例中不同的存储桶名称。只要遵守 S3 命名规则,您可以随意命名存储桶。

  3. 如果成功,您应该看到以下输出:

    make_bucket: devopspro-beyond
    

    现在您有了一个我们可以操作的存储桶。如果你想在命令行中查看存储桶,可以使用以下命令列出它:

    $ aws s3 ls
    

    我们刚刚创建的这个存储桶现在已经准备好存放文件、媒体、日志或您希望存储的任何内容。

将数据迁移到 S3

到此为止,我们至少创建了一个存储桶。随着后续操作的进行,您会注意到一些 AWS 服务会在您的账户中创建存储桶,例如 CloudFormation

如果我们只是尝试一次迁移一个项目或一个文件夹,那么我们可以使用 AWS 管理控制台或 CLI 中的 aws s3 copy 命令。

如果我们有一台生成日志的服务器,并且希望将这些日志存储到 S3 存储桶中,用于存储、备份、分析或这些选项的组合,那么我们可以使用aws s3 sync命令。s3 sync命令将同步指定文件夹中的所有对象与 S3 中指定的存储桶。这与 cron 或类似的计划任务一起使用时效果极佳,可以按照预定计划执行该命令。

当试图迁移整个服务器或数据中心时,尝试通过网络推送所有文件和对象可能会非常耗时。在这种情况下,Snowball 系列服务就派上用场了。Snowball Edge 存储优化版SESO)允许安全地传输最多 80 TB 可用硬盘存储的数据,数据上传到设备后,再运送到 AWS,最终被卸载到您指定的 S3 存储桶中。

S3 清单

使用列出命令查看存储桶中不同对象非常有用,直到你开始拥有成千上万到百万级别的对象。当达到这个数量时,拥有一个更强大的工具就显得尤为重要。S3 清单就是为这个目的而创建的。S3 清单工具会创建一份报告,然后将其交付到另一个存储桶中,并提供有关您的对象的各种信息,如以下内容:

  • 创建日期

  • 存储类

  • 加密状态

  • 复制状态

  • 对象大小

您可以选择使用 SSE-S3 或 密钥管理服务KMS)密钥对报告进行加密。

一旦报告生成完成,您可以使用 Amazon Athena 等工具使用标准 SQL 查询报告,寻找趋势或异常。

S3 清单报告生成需要小额费用(每百万个对象少于 0.003 美分);但不应假定该工具是免费的,它是 S3 服务的一部分。

S3 存储层

亚马逊 S3 服务有一系列不同的存储层,可以满足不同的需求以及不同的成本结构。默认存储层是标准存储层,尽管这并不总是存储数据的正确选择,特别是当您的组织需要长期存储和/或寻求节省成本时。

您可以创建生命周期策略,将对象从一个存储层移动到另一个存储层,或者在一段时间后如果对象不再需要则删除它。

S3 Standard

一旦您初次设置了一个存储桶,默认情况下,除非指定其他存储层,否则它将位于 S3 Standard 层。这是一个高可用性的通用访问存储策略,提供毫秒级别的对象访问。尽管这是所有存储层中最昂贵的,但与其他类型的存储服务(如文件存储和块存储)相比,S3 Standard 存储非常便宜。

需要记住的关于 S3 Standard 的要点:

  • Standard 层提供高吞吐量、低延迟和对象上传与下载的性能。

  • 如果没有指定其他存储层,则 Standard 是默认的存储类。

  • 设计为每年 99.99% 的可用性。

  • 适合需要频繁访问的对象。

  • 适合用于数据湖、云原生应用、网站和内容分发等用例。

S3 智能分层(Intelligent-Tiering)

有时您可能认为亚马逊推导出来的将对象移动到不同存储层的算法,比您自己提出的任何方法都更有效。这时选择 S3 智能分层是一个完美的案例。使用智能分层,AWS 将根据您的使用情况自动在频繁访问层和不频繁访问层之间移动您的对象,并根据使用情况向您收费。

需要记住的关于 S3 智能分层的要点如下:

  • 设计为通过自动将对象移动到最具成本效益的存储层来优化存储成本。

  • 设计用于至少 30 天的长期存储(最低 30 天的充电时间),并且智能分层(Intelligent-Tiering)需要 30 天才能开始分析访问模式。

  • 它将对象存储在两个访问层中,并基于频繁访问和不频繁访问的对象优化存储。

  • 当智能分层在不同层级之间移动对象时,不会影响性能,也不会产生额外费用。

  • 设计为每年 99.99% 的可用性。

  • 针对数据湖和其他访问模式不确定的数据集进行了优化。

S3 标准低频访问(S3 Standard-IA)

如果您有不常访问但仍需要实时检索的数据,Standard-IA 是一个值得考虑的选项。考虑此存储选项时需要注意一些要点,例如文件需要至少存储 30 天才可以删除(或者需要为这 30 天支付费用),并且文件的最小大小为 128 KB。

关于 S3 Standard-IA,需记住的关键点如下:

  • 设计用于大于 128 KB 的文件(小于 128 KB 的文件将按 128 KB 计费)。

  • 设计用于至少存储 30 天(最低 30 天费用)。

  • 相比标准存储,S3 One Zone-IA 在 GET、PUT、COPY、POST、LIST 和 SELECT 操作上的费用较高,但存储成本较低,因此它是为低频访问而设计的,正如其名称所示。

  • 对象可以实时访问,且没有延迟。

  • 为保证一年内 99.99% 的可用性而设计。

  • 数据的副本存储在多个可用区中。

S3 单区低频访问(S3 One Zone-IA)

S3 One Zone-IA 具有与 Standard-IA 相同的许多功能,但由于数据只存储在一个可用区而不是至少三个可用区,因此价格更低。这对于关键数据并不是一个好选择,但对于不常访问且可以在必要时重新创建的文件来说,可以大幅节省成本。

关于 S3 One Zone-IA,需记住的关键点如下:

  • 适用于可重新创建的数据或在设置跨区域复制时的对象副本。

  • 设计用于至少存储 30 天(最低 30 天费用)。

  • 对象可以进行实时访问。

  • 为保证一年内 99.95% 的可用性而设计。

  • 数据可能会因灾难性事件(如洪水或地震)导致的数据中心停机而丢失。

S3 Glacier

S3 Glacier 存储层提供低成本、持久的存档存储选项,并且数据检索费用低。与 AWS Glacier 服务不同,您无需等待数天才能将对象恢复到 S3 存储桶中。S3 Glacier 有 3 种检索速度等级:第一种是加急等级,可在 1-5 分钟内恢复对象;第二种是标准检索等级,可在 3-5 小时内恢复对象;第三种是批量等级,恢复对象大约需要 12 小时。

关于 S3 Glacier,需记住的关键点如下:

  • 设计用于至少存储 90 天(最低 90 天费用)。

  • 为保证一年内 99.9% 的可用性而设计。

  • 对象可以通过VAULT LOCK功能进行锁定。

  • Glacier 检索时间可以配置为几分钟到几小时不等。

  • 适合低成本的数据归档,尤其适用于合规目的,不常访问的对象。

S3 Glacier 深度归档

像 Glacier 服务一样,如果你有很少检索的数据但需要保存,那么 Glacier Deep Archive 可以成为一个切实可行的存储解决方案。通常,有一些场景比如从磁带备份系统迁移到数字磁带备份系统,数据每年只需要检索一到两次,并且可以接受等待 12 小时来检索数据。这些控制提供了巨大的节省,因为 Glacier Deep Archive 的存储费用仅为每月每 TB 1 美元。

关于 S3 Glacier Deep Archive,有几个关键点需要记住:

  • 设计用于长期数字存储,可能在某一年内仅访问一次或两次

  • 旨在保证每年 99.9% 的可用性

  • 设计用于至少存储 180 天(最低 180 天的费用)

  • 是本地磁带库的替代方案

    注意

    S3 Glacier 和 S3 Glacier Deep Archive 是 S3 中的存储类,因此,对象将一直保存在 S3 服务内。

在 S3 中使用生命周期策略

正如我们刚才讨论过的,S3 提供不同的存储类,并非所有存储在 S3 中的数据都需要始终处于标准存储层,如下所示:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_4.3_B17405.jpg

](https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_4.3_B17405.jpg)

图 4.3 – 一个示例 S3 生命周期策略

根据你定期访问数据的频率,你可以通过对象生命周期将你的对象移动到不同的存储层。

创建生命周期策略

以下练习将使用 AWS 控制台和我们在本章前面创建的桶:

  1. 登录 AWS 控制台(使用你在本章中创建的 S3 桶所在账户)。确保你已使用具有 S3 完全访问权限的用户登录账户。

  2. 访问 S3 页面(s3.console.aws.amazon.com/)。

  3. 如果你有多个 S3 桶,请点击你在前面的练习中创建的桶。

    该桶当前应没有任何对象,也没有与其关联的生命周期策略。

  4. 当你进入桶的主页时,点击主屏幕上的 管理 选项卡。

    这将把 生命周期规则 部分显示在主屏幕的中间,并且在 生命周期规则 后面会有一个 (0),意味着当前没有与此桶关联的 生命周期规则

    https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_4.4_B17405.jpg

    ](https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_4.4_B17405.jpg)

    图 4.4 – 通过管理选项卡查看 S3 生命周期规则

  5. 现在我们可以点击 生命周期规则 部分中的 创建生命周期规则 按钮。这将引导我们进入创建生命周期规则的界面。

    我们将创建一个规则,在一天后删除存储桶中的对象。我们可以创建多个规则,遵循图 4.2中的路径,但如果你记得低频访问存储层的关键点,任何未保存至少 30 天的对象将会被收取 30 天的存储费用。在测试如何创建生命周期规则时,我们将创建一个规则,删除对象,而不是测试期间产生额外的费用。

  6. 将规则命名为devopspro-1day-delete

  7. 在规则范围下,点击选项此规则适用于存储桶中的所有对象

  8. 勾选出现的框,标明我确认此规则将适用于存储桶中的所有对象https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_4.5_B17405.jpg

    图 4.5 – 配置生命周期规则

  9. 生命周期规则操作下,勾选标有过期当前对象版本的框。

  10. 1

  11. 点击页面底部的创建规则按钮:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_4.6_B17405.jpg

图 4.6 – 创建规则按钮

我们现在已经创建了生命周期规则,为了测试它,我们需要上传一个文件到存储桶中,然后等待一天,以便看到它被自动删除。

S3 终端节点

在 S3 终端节点创建之前,所有访问 S3 的数据都必须经过公共互联网。如果你有私人信息从私有 S3 存储桶传输到 VPC 中私有子网的资源,那么不仅存在一些安全风险,还需要额外的网络配置,使得私有子网中的资源能够与互联网通信,以便可以上传和下载你想要访问的 S3 存储桶。

如果我们的 VPC 中的资源位于一个私有子网,并且没有通过 NAT 实例或 NAT 网关与互联网建立公共路由,那么我们将无法访问 S3 存储桶中的项目,除非设置那个 NAT 实例,或者我们可以通过使用 S3 终端节点来建立更安全的连接。

S3 终端节点,作为一个网关终端节点,允许我们向VPC的路由表中添加一条入口。通过添加这个终端节点,我们现在可以绕过公共互联网,既可以通过公共实例,也可以通过私有实例,同时保护我们数据沿路由传输过程中的隐私。这比使用公共路由更安全,是从 EC2 实例和其他在 VPC 中的服务传输数据的更好解决方案。

S3 访问控制

一旦你将数据和对象上传到桶中,除非你的桶具有公共访问权限,否则你可能希望限制谁可以访问桶中的对象。刚开始时,你可能只允许具有帐户授权的任何人访问。这些人可以访问任何非公开的桶中的数据。当你进入大多数企业环境时,数据的某些部分可能需要在不同业务部门之间进行隔离。一个产品团队很可能没有必要访问另一个数据团队存储的数据。类似地,财务和业务部门存储的数据可能需要限制任何技术人员访问,甚至可能删除这些数据。

这时,S3 的访问控制就发挥了作用。实现访问控制有两种主要方法:一种是使用 S3 桶策略来限制谁和什么可以访问单个对象,另一种是使用 IAM 控制来限制可以单独访问桶的用户、组和资源,或者使用基于属性的控制模型(如标签)等控制。

通常,选择一种访问方法而非两者混合使用是个好主意,因为混合使用可能会导致一些非常令人沮丧的排错会话,试图解决权限问题:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_4.7_B17405.jpg

图 4.7 – S3 资源与基于用户的策略

你还应该知道,必须显式地将 S3 桶设置为公共访问,因为所有 S3 桶默认都是私有的,并且阻止公共访问。

基于资源的策略

如果你和你的组织更倾向于在对象级别进行限制,那么你可以在桶访问级别或对象访问级别使用访问控制列表ACLs)。

基于用户的策略

另一方面,许多人更愿意通过 IAM 策略来控制对 S3 桶的访问。这使你能够控制从桶和文件夹级别的权限,并且可以根据标签、VPC-idsource-IP 地址和其他因素在 IAM 策略中构建更复杂的条件。

跨账户访问

如果你需要一个账户中的用户或资源能够访问另一个账户中的对象,那么你可以设置跨账户访问角色,就像我们在 IAM 练习中所做的那样,见 第三章AWS 中的身份与访问管理和密钥管理

S3 访问日志

当你在 S3 中存储不同的对象时,尤其是那些需要被各种用户和组下载的对象,你可能希望知道谁在何时从什么位置访问了不同的文件。

用户可以通过 S3 中一个简单的设置捕获所有访问日志和谁在访问桶中不同对象的记录。你不能将日志存储在与正在跟踪的项目相同的桶中,因此你需要创建一个全新的桶,专门用于捕获日志,或者指定当前账户中已创建的桶来存储这些日志。

与 Web 服务器上的日志不同,日志不会在访问项目时实时推送到该桶。亚马逊会以批量的形式推送日志,尽力而为。

如果你不想设置一个完全不同的桶来捕获这些日志,并且你已为该账户启用CloudTrail 日志,那么你可以收集 IAM 用户对 S3 API 调用的信息。

S3 的加密选项

S3 允许对其存储的对象进行静态加密。存储对象时,默认选项是将其以未加密的形式存储。如果你在任何需要合规性的环境中工作,那么你很可能需要加密你存储的对象。

如果你已经决定将存储在 S3 中的对象进行加密,那么你确实有选择。你可以在服务器端加密客户端加密之间进行选择。在做出这个决定之前,有几个关键问题需要考虑:

  • 你需要管理加密密钥吗?

  • 加密密钥将存储在哪里?

  • 谁将负责数据的加密和解密?

服务器端加密

AWS 通过其服务器端加密选项使得加密存储在 S3 中的对象和数据变得简单:

  • SSE-S3:使用 SSE-S3 选项可以让你使用 AWS S3 主密钥来加密你的对象和数据。这使得你的数据可以在静态存储时进行加密,而无需在设置过程中做过多管理或额外配置。你只需将对象上传到你选择的 S3 桶,一旦成功接收,S3 服务会处理这些对象的加密。类似地,当服务或用户请求一个对象时,只要该服务或用户有权限访问该对象,S3 服务就会解密该请求的对象。

  • SSE-K:MS:将密钥管理服务KMS)集成到服务器端加密中,会增加少许费用,但相较于仅使用 S3 服务提供的默认加密密钥,它带来了一些额外的功能和好处。你现在可以更细粒度地控制客户密钥以及哪些 IAM 实体可以访问该密钥。KMS 还提供了密钥访问的审计记录。其主要特点之一是,你可以根据需要旋转密钥。

客户端加密

选择客户端加密时,完全的加密和解密责任由您,客户端承担。这种方法涉及在对象到达 S3 之前进行加密。您还需要负责任何主密钥/子密钥的管理及密钥轮换。如果您的组织需要完全控制主密钥和加密算法,客户端加密是一个不错的选择。

我们将在第十九章,《保护传输中的数据和静态数据》中深入探讨数据的传输和存储保护。

使用 S3 事件触发其他 AWS 服务

S3 服务可以在存储桶中的对象发生特定变化时通知其他服务。最常见的两种场景是对象被上传或对象从某个特定存储桶中删除。然后,S3 存储桶可以通知其他三种 AWS 服务发生了什么事情,以及事件发生的存储桶。允许 S3 事件通知的三种服务如下:

  • AWS Lambda

  • 亚马逊 简单队列服务 (SQS)

  • 亚马逊 简单通知服务 (SNS)

当向存储桶添加或覆盖新对象时,您可以安排将通知发送到 SQS 或 SNS。通知也可以传递到 AWS Lambda,由 Lambda 函数处理:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_4.8_B17405.jpg

图 4.8 – S3 事件流

让我们从 DevOps 的角度来思考这个问题,看看如何使用它。AWS Lambda 是一个极其强大的工具,我们将在第十二章,《Lambda 部署与版本管理》中详细探讨,它可以用于调用几乎任何其他的 AWS 服务。在我们当前的场景中,我们可能有一个客户正在使用 AWS SFTP 服务将文件上传到 Amazon S3 存储桶。该存储桶可以触发一个存储桶事件到 AWS Lambda。Lambda 函数可以启动一个 AWS Pipeline 构建来处理文件,处理结果无论是成功还是失败,都会向开发团队发送通知,告知有新的构建可供部署。

注意

为了使用 S3 事件,必须授予 S3 相关权限,以便使用请求的服务。这包括发布到 SNS 队列或 SQS 主题的权限,以及调用 Lambda 的能力。

触发 S3 事件

我们将通过一个示例来使用我们之前创建的存储桶,在每次上传对象到存储桶时添加事件触发器。这个事件一开始会是一个简单的操作:向我们自己发送电子邮件通知。为了发送这封邮件,我们需要创建一个 SNS 主题,并用我们的电子邮件订阅该主题。然后,我们可以返回到存储桶并添加存储桶事件配置,这样每当上传一个对象时,就会发送通知给我们。

既然我们知道需要设置一个 SNS 主题,让我们使用 CLI 创建该主题并订阅,以便上传到我们的存储桶时能够收到邮件:

  1. 打开终端并输入以下命令,创建该主题:

     $aws sns create-topic --name s3-event
    

    如果主题创建成功,那么应该返回如下内容:

    {
        "TopicArn": "arn:aws:sns:us-east-2:470066103307:s3-event"
    }
    
  2. 现在我们已经有了主题,需要使用我们的电子邮件地址进行订阅:

    $ aws sns subscribe \
        --topic-arn arn:aws:sns:us-east-2:470066103307:s3-event \
        --protocol email \
        --notification-endpoint devopsproandbeyond@gmail.com
    

    这应该返回一条 JSON 语句,告诉你订阅正在等待中:

    {
        "SubscriptionArn": "pending confirmation"
    }
    
  3. 现在我们需要进入我们的电子邮件账户,找到 SNS 服务刚刚发送的邮件,然后点击上面写着确认订阅的链接。

    现在让我们登录到我们的账户,进入我们的 S3 存储桶,以便配置事件通知

  4. 我们的 SNS 主题准备就绪的最后一步是添加一个 IAM 角色,允许它接收来自 S3 存储桶的通知事件。

    我们将使用以下策略,并在保存到文件之前填写以下值:

    • 账户编号

    • 区域

    • 存储桶名称

    我们将创建以下策略,然后在登录 AWS 控制台后将其添加到访问部分的主题中:

    {
      "Version": "2012-10-17",
      "Id": "s3-event-sns-ID",
      "Statement": [
        {
          "Sid": "s3-publish-ID",
          "Effect": "Allow",
          "Principal": {
            "Service": "s3.amazonaws.com"
          },
          "Action": "SNS:Publish",
          "Resource": "arn:aws:sns:region:account-num:sns-topic",
          "Condition": {
            "StringEquals": {
              "aws:SourceAccount": "account-num"
            },
            "ArnLike": {
              "aws:SourceArn": "arn:aws:s3:::bucket-name"
            }
          }
        }
      ]
    }
    
  5. 现在让我们登录到我们的 AWS 账户,进入 SNS 服务,以便更新我们的访问策略。这样,SNS 主题就能拥有正确的权限来与 S3 事件通知交互。

  6. 一旦进入 SNS 服务,选择主题

  7. 主题菜单中,你应该能够看到我们通过CLI – s3events创建的主题。点击主题名称以进入配置页面。

  8. 进入主题后,我们需要点击页面右上方的编辑按钮:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_4.9_B17405.jpg

    图 4.9 – 页面顶部的编辑按钮

  9. 现在在这一部分找到我们之前创建的JSON策略。一旦将之前的值替换为新的访问策略,点击页面底部的橙色保存更改按钮。

  10. 现在我们可以进入 S3 控制台(s3.console.aws.amazon.com/)。

  11. 找到你在本章中创建的存储桶(我们的存储桶名为devopspro-beyond)。如果你还没有创建存储桶,你可以选择账户中已有的任何存储桶,或者快速创建一个新存储桶。点击该存储桶名称进入主存储桶页面。

  12. 一旦进入主存储桶页面,点击主窗口框中的水平菜单中的属性菜单项:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_4.10_B17405.jpg

    图 4.10 – S3 水平菜单,属性高亮显示

  13. 现在向下滚动页面,直到找到名为事件通知的面板:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_4.11_B17405.jpg

    图 4.11 – 没有创建通知的 S3 事件通知

  14. 现在点击创建事件通知按钮。

  15. 使用以下配置进行我们的 S3 事件测试:

    • S3 测试

    • .txt

    • 事件类型 – 勾选标记为 Put 的复选框:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_4.12_B17405.jpg

图 4.12 – 配置 S3 事件通知

  1. 向下滚动到页面底部,直到看到 目标

  2. 选择位于 s3-event 旁边的单选按钮:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_4.13_B17405.jpg

    图 4.13 – 选择 S3 事件通知的目标

  3. 点击橙色的 保存更改 按钮。

  4. 现在是上传文本文件并测试我们是否能收到邮件通知的时候了。

  5. 我们需要测试的只是一份文本文件(记住,我们配置的事件仅限于 .txt 文件,其他类型的文件不适用)。我们将使用 CLI 上传文件:

    $aws s3 cp test.txt s3://devopspro-beyond/test.txt
    

    如果你成功上传了文件,应该会看到如下输出:

    upload: ./test.txt to s3://devopspro-beyond/test.txt
    
  6. 文件上传后,你应该会收到一封邮件通知,通知会发送到你订阅 SNS 主题时使用的邮箱地址。

现在我们已经看到如何触发其他服务(如 LambdaSNSSQS)的操作,我们可以思考一下这种方式如何在现实世界中对我们有帮助。以 SNS 为例,你可能有一个客户,他有一个账户,并希望在他们的客户上传一个或多个文件到他们的个人 S3 存储桶时收到通知,以便查看这些文件。对于 Lambda 来说,你可能会收到另一个部门的发票,需要在将其存储到一个或多个数据存储中之前提取数据,使用 S3 事件,这一切都可以在文件上传到存储桶后自动发生。

在接下来的部分,我们将了解 S3 批量操作,看看如何借助清单文件,我们可以一次处理少量或几千个文件,仅使用 S3 服务。

S3 批量操作

拥有良好的标签策略是推荐的 AWS 账户管理的一部分。就像其他举措一样,这些策略中的许多会随着时间的推移而不断发展。也许会有某个时刻,你或你的组织会觉得需要更改当前 S3 存储桶中对象的某些强制性标签。如果你已经在 AWS 中运行了一段时间,那么很可能有太多对象需要手动重新标记,因此你需要想办法制定一个解决方案。这时,AWS S3 批量操作的强大功能就能派上用场了。它可以轻松地对文件和存储桶执行批量操作。

S3 批量操作不仅仅是修改标签。以下操作可以通过 S3 批量操作来执行:

  • 修改对象和元数据属性。

  • 在 S3 存储桶之间复制对象。

  • 替换对象标签集。

  • 修改对敏感数据的访问控制。

  • 从 Glacier 恢复归档对象。

  • 调用 AWS Lambda 函数。

作业创建后,会经历一系列法规,然后达到完成或失败状态。以下表格描述了 Amazon S3 批处理作业可用的不同状态:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/011.jpg

S3 批处理实例

为了测试 S3 批处理的功能,我们将取 75 个文件,上传到我们的存储桶,然后使用 AWS 批处理几乎即时为每个文件添加一个标签。

注意

如果不想重新创建此练习的所有文件,只需转到本书的 GitHub 仓库;在第四章Amazon S3 Blob Storage,批处理子文件夹中有 75 个小文件可用。

另外,由于所有文件都具有.txt扩展名,您可能希望在将所有练习文件上传到 S3 存储桶之前,关闭 S3 事件通知或取消订阅主题。

我们现在将使用 S3 批处理的实际示例一次性更新多个文件的标签。如果您有强制性的标签策略,并且文件缺少其中一些标签,则这可能是管理这些更改的有效方式,而不是尝试编写自定义脚本执行任务或手动更改文件的标签:

  1. 在开始之前,为了使作业能够执行,我们需要确保有一个 IAM 角色。让我们首先登录 AWS 管理控制台,并导航到 IAM 服务。

  2. 为 AWS 服务创建角色,选择S3,然后在页面底部选择S3 批处理操作https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_4.14_B17405.jpg

    图 4.14 – 在 IAM 中选择 S3 权限的用例

  3. 点击标有下一步:权限的蓝色按钮。

  4. 到达策略时,从 GitHub 中点击S3_batch_IAM.jsonJSON代码。您需要在所有需要变量的地方替换您的 S3 存储桶名称。(变量名称标记为<<TargetResource>><<ManifestBucket>><<ResourceBucket>>)。完成后,您可以点击标有下一步:标签的蓝色按钮。此时不需要任何标签,只需点击标有下一步:审核的蓝色按钮。

  5. 现在可以命名和保存我们的角色;一个好的描述性名称可以是S3-Batch-Tagging-Role。如果需要,添加描述,然后点击蓝色的创建策略按钮。

  6. 返回到创建角色的其他标签页,并搜索我们刚刚创建的名为S3-Batch-Tagging的策略。创建完角色后,我们需要记下 ARN,以便稍后在batch命令中使用。

  7. 从 GitHub 目录下载 75 个.txt文件(或创建您自己的文件集),放入单个目录中,以便可以将它们上传到您之前创建的 S3 存储桶。

  8. 接下来,我们将使用 s3 sync 命令快速将文件从本地目录移动:

    $aws s3 sync . s3://devopspro-beyond
    
  9. 我们还需要从 GitHub 仓库下载清单(.csv 文件),以便开始我们的批处理任务。在清单中,你需要将当前的存储桶名称devopspro-beyond替换为你上传对象的存储桶名称。更改这些值后,确保将清单上传到 S3 存储桶,因为当使用 CSV 文件时,S3 批处理需要从 S3 位置读取清单,而不是从本地文件读取。

  10. 最终报告还需要一个文件夹来存放。我们将使用 s3 cp 命令将文件移动到新文件夹,并使其准备好接收最终报告:

    $aws s3 cp manifest.csv s3://devopspro-beyond/final-reports/manifest.csv
    
  11. 现在我们的对象和清单已经上传,我们可以返回到 AWS 管理控制台并开始批处理任务。返回到你之前创建 IAM 角色的浏览器窗口,导航到S3 服务

  12. 在左侧菜单中,点击批处理操作https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_4.15_B17405.jpg

    图 4.15 – 批处理操作菜单项

  13. 点击右侧的橙色按钮,标签为创建任务

  14. 在清单页面,选择 S3 存储桶中标记为 manifest.csv 文件的单选按钮。清单的 ETag 会自动填充:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_4.16_B17405.jpg

    图 4.16 – S3 批处理的清单信息

  15. 点击页面底部的橙色下一步按钮。

  16. 操作下,选择替换所有标签旁边的单选按钮。

  17. 这会使另一个选项集出现。选择 TAGChapter4。完成后,点击橙色的下一步按钮:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_4.17_B17405.jpg

    图 4.17 – 添加要更改的键和值

  18. 对于完成报告,通过 CLI 上传 manifest 文件副本后,浏览到我们之前创建的 final-reports 文件夹:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_4.18_B17405.jpg

    图 4.18 – 选择 S3 批处理报告的目的地

  19. 在权限下,选择现有的 IAM 角色,然后在下拉框中选择你在本次练习开始时创建的S3-Batch-Tagging-Role。点击页面底部的橙色下一步按钮。

  20. 在审查页面,滚动到底部并点击橙色的创建任务按钮。

  21. 一旦你创建了任务,你将被带回 S3 批处理主界面。任务创建可能需要一两分钟,但创建完成后,你可以选择左侧的单选按钮,然后点击标有运行任务的按钮。这将开始处理清单中所有文件的标签。

  22. 现在,我们可以返回 AWS 管理控制台并导航到我们的 S3 存储桶,查看我们的文件,看看是否已经添加了删除标签。

    注意事项

    在 GitHub 存储库中上传的清单包含了 S3 示例存储桶的名称。在上传和运行批处理作业之前,您需要更改清单中的存储桶名称,修改为您创建的 S3 存储桶名称。

S3 复制

即使在其高耐久性保证下,仍然有许多情况需要您制定计划以保护数据,以防出现区域性故障或数据丢失。您甚至可能希望将受访问策略限制的原始数据复制到其他地方,以便另一个团队可以访问这些数据。这时,S3 复制功能就派上用场了。它使您能够异步地将数据复制到另一个存储桶中。S3 复制有两种版本可用:

  • 跨区域复制CRR):这意味着存储桶中的对象会被复制到一个在与原始存储桶所在区域不同的区域中创建的独立存储桶中。

  • 单区域复制SRR):在 SRR 中,对象仍然会被复制到一个新的独立存储桶中,但两个存储桶都位于相同的地理区域。

S3 版本控制

在 S3 服务中,您可以使用版本控制功能跟踪文件随时间的变化。虽然该功能确实会增加额外的成本,但它在帮助恢复被删除对象时特别有用。

一旦启用版本控制,S3 存储桶中的每个对象都会获得一个版本 ID。如果您没有在存储桶上启用版本控制,那么存储桶中对象的版本 ID 将被设置为 null:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_4.19_B17405.jpg

图 4.19 – 启用版本控制的 S3 存储桶,显示版本 ID

一旦您上传启用了版本控制的对象的新版本,亚马逊会为该新版本生成一个新的版本 ID,并将该新版本的对象放入存储桶中。

总结

本章我们介绍了 AWS S3 服务及其众多功能。我们不仅讲解了创建存储桶的基础知识,以及如何通过不同类型的访问策略保护存储桶,还介绍了如何使用 AWS 的不同加密方法对静态数据进行加密。我们还看到了如何通过存储桶事件触发工作流,例如启动我们的 DevOps 流水线。现在我们对对象存储有了更深入的了解,接下来我们将继续学习无服务器的 NoSQL 数据库 DynamoDB。

复习题

  1. 您公司有一个部门需要配置一个 S3 存储桶,该存储桶中的对象每周都会被访问,并且需要具备高耐久性和可靠性。您应该使用哪个 S3 存储类型来配置该存储桶?

  2. 您的组织有五个部门。其中三个部门是产品团队,一个是会计部门,另一个是人力资源部门。会计部门决定将其文件从数据中心迁移到 S3 以节省成本。如何确保只有会计部门的成员可以访问会计文件,而其他人无法访问?

  3. 一家医疗保健公司正在准备内部审计。他们需要确保存储在 S3 中的所有文件都已加密,并且密钥每年至少轮换一次。该公司成立已超过 15 年,并在最近 5 年内推动了大量文件转移到云上。这导致存储了超过 150 万份文件,包括账单记录、患者信息、业务信息和其他文档。最有效的持续检查方法是什么?

检查答案

  1. S3 标准。

  2. 确保为会计部门的成员创建了一个 IAM 组。创建一个 IAM(基于用户)策略,允许会计组的成员对会计桶具有完全权限。您还可以进一步创建一个策略边界,明确拒绝其他所有组访问会计桶。

  3. 创建一个 S3 清单报告。使用 AWS Athena 查询未加密的文件。

第五章:Amazon DynamoDB

随着应用架构对可扩展性的需求增加,并将重点转向无服务器设计模式,开发人员开始寻找灵活、可扩展且管理开销低的数据存储。DynamoDB 已成为满足这些特性需求的一个经过验证且值得信赖的解决方案。然而,它一直在不断发展,许多从该服务衍生出来的功能在 DevOps 专业认证考试中具有重要意义。

虽然在专业级考试中,计算 DynamoDB 数据库的读写比率并不是重点,但理解该核心 AWS 服务如何融入部署和场景是非常重要的。对 DynamoDB 的功能和特性有扎实的理解,将帮助你回答考试问题,也能帮助你在职业生涯中实施解决方案。

在本章中,我们将涵盖以下主要主题:

  • 理解 DynamoDB 的基础和背景

  • 理解 DynamoDB 数据建模

  • 在 DynamoDB 中插入和访问数据

  • 理解 DynamoDB 流

  • 使用 DynamoDB 加速器 (DAX)

  • 在 DynamoDB 中进行身份验证和授权

  • 监控 DynamoDB

理解 DynamoDB 的基础和背景

DynamoDB 是一个 NoSQL 数据库。这意味着它不仅仅是 SQL,更重要的是,DynamoDB 不需要完全结构化的模式来插入数据。它的灵活性和性能是许多人选择 DynamoDB 的原因,此外,还有其按需付费的定价模式以及高可用性和可扩展性。

DynamoDB 的起源

在 2007 年,亚马逊发布了一篇由未来 AWS 首席技术官 Werner Vogels 和其他人共同撰写的白皮书,名为 Dynamo: Amazon 的高可用键值存储

你仍然可以在今天找到这篇论文,链接在这里:www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf

当亚马逊构建其电商平台时,试图解决如下问题:

  • 分区

  • 写操作的高可用性

  • 处理临时故障

  • 从永久故障中恢复

  • 成员资格和故障检测

当时的数据库性能不够强大,电商网站开始在数据库层面遇到瓶颈。

NoSQL 与关系型数据库

关系型数据库自 1970 年代以来就存在。当你需要强制数据完整性并使用结构化查询语言SQL)来组织数据时,关系型数据库是非常合适的。关系型数据库的优化基于存储是你最有限的资源这一前提。一旦存储或磁盘空间用尽,你就需要购买更多的存储空间。知道这一点是使用关系型数据库时采用主键和连接的原因之一。通过使用数据的 ID,然后通过表连接检索实际需要的列,数据可以只存储一次,从而节省系统的存储空间,如下所示:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_5.1_B17405.jpg

图 5.1 – 关系型数据库表

随着云存储的普及,存储及其相关成本不再是限制性因素。这就引出了 NoSQL,或称非 SQL(有时称为不仅仅是 SQL)。与其将数据存储在表中,NoSQL 系统则采用不同的方式存储数据,常见的如 DynamoDB,它将数据存储在JSON文档中。

NoSQL 数据库提供了关系型数据库无法提供的灵活性。如今的现代应用程序,如 Web 应用、游戏系统和移动应用,都需要这种灵活性,同时需要具备可扩展性,以满足用户需求,并在检索和插入数据时提供高性能。

与传统的关系型数据库不同,DynamoDB 更像一个键值存储,它在数据的检索和存储方面非常高效。

Dynamo 的核心组件

让我们来看一下 DynamoDB 的主要组成部分:

  • 表及其属性

  • 主键

  • 次级索引

让我们开始吧。

表及其属性

DynamoDB 中的类似于其他数据库系统中的数据库,而不仅仅是关系型数据库系统中的表。一个表是关于某一特定主题的数据集合。Dynamo 中的每个表都是单独存储项目的地方,数据就存储在这里。

每个表包含零个或多个项目。项目有不同的字段和属性。

以下是一个包含项目的 DynamoDB 表:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_5.2_B17405.jpg

图 5.2 – Dynamo DB 表和项目

如果你查看上面的表格,你会看到以下几点:

  • 每个项目都有一个主键。这是该项目的唯一标识符(CarID)。

  • 项目没有固定的模式。只要主键存在,其他任何属性可以存在,也可以不存在。

  • 大多数属性只有一个值。然而,最后一项有一个特性字段。这是一个嵌套值,可以包含多个属性。

主键

在创建 DynamoDB 表时,必须指定主键。这个主键是每个表项的唯一标识符,这意味着没有两个项可以拥有相同的主键。

使用主键,你可以引用表中的不同项。DynamoDB 使用主键作为其内部哈希算法的数据。这个哈希值用来确定应该使用哪个分区来存储该属性。

二级索引

二级索引是可选的键,可以用来进行查询。DynamoDB 支持两种类型的二级索引:

  • 全局二级索引

  • 本地二级索引

我们将在本章后面深入探讨二级索引。

其他相关的 Dynamo 信息

当你开始思考你的表时,重要的是要注意,Dynamo 并不是由单一的服务器实例或机器托管的。一旦添加数据,它会分布到多个实例中,这使得 DynamoDB 可以利用其关键的扩展性和性能特点。写操作在数据被冗余存储之前不会被认为成功。

理解 DynamoDB 数据建模

如果你曾经设计过关系型数据库,那么你会熟悉诸如星型模式这样的架构。每个表都需要有一个指定的属性,如果该属性没有值,那么会保留一个空值。

DynamoDB 使用分区。这些分区可以是热分区,也可以是冷分区。

DynamoDB 中的每个项目至少需要一个属性,即分区键。Dynamo 使用该分区键对数据进行哈希并将其放置在内存中。为了在 DynamoDB 中实现最佳性能,我们需要选择一个能够使 DynamoDB 将搜索分散到磁盘上的分区键,而不是让单个分区过于热点

这最好通过一个不好的分区键示例来演示,比如日期。如果你尝试收集所有来自同一天的数据,那么这个日期的哈希值将存储在同一个分区中。不同的日期可能会存储在不同的分区中,因为它们的哈希值不同;然而,当查询某一天发生的所有事件时,这个单一的分区将变得过热,这可能会导致性能问题。

高质量分区键的示例如下:

  • 位置 ID

  • 部门 ID

  • 客户 ID

  • 姓氏的首字母

在前面的示例中,数据在读取和写入时会分布到不同的分区,如下所示:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_5.3_B17405.jpg

图 5.3 – 键均匀分布在分区中

读取和写入容量

创建表时,必须同时指定读和写容量值。一旦指定,DynamoDB 将保留处理该容量所需的资源,并将其平均分配到各个分区。

需要指定两种不同类型的容量单位:

  • 读取容量单位RCU):这是您的表每秒可以处理的强一致性读取次数。它可以包含最大 4 KB 大小的项。

  • 写容量单位WCU):这是您的表每秒可以处理的每 1 KB 单位的写入次数。

自适应容量

如果您的工作负载本质上不平衡,DynamoDB 提供了一个名为 自适应容量 的功能,帮助最大限度减少限流。这个功能的最佳之处在于,它会自动为每个 DynamoDB 表启用,无需额外费用。您无需进入设置去打开或关闭自适应容量设置。

虽然您可以为每个分区预配置 10 个 写容量单位WCUs),但可能会有一个分区的写入操作比其他分区更多。如果表的总容量没有被超出,那么 DynamoDB 可以使用自适应容量功能,允许 分区继续接收写入,而不进行限流:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_5.4_B17405.jpg

图 5.4 – 自适应容量示例

上图显示了一个包含 4 个分区的 DynamoDB 表的示例。创建时,我们为整个表分配了 40 个 WCS(写容量单位)。分区 2分区 3分区 4 每个只消耗了 5 个 WCUs,总共消耗了 15 个 WCUs,剩余的 25 个 WCUs 是从我们初始预配置中分配的。分区 1 则有最多的活动,消耗了 15 个 WCUs,比每个分区分配的 10 个 WCU 超出了 5 个。自适应容量功能考虑到还有额外的 WCU 容量,并在不限制表的情况下进行调整。

DynamoDB 表中可用的数据类型

DynamoDB 允许将各种类型的数据插入到属性中。

数字、字符串、布尔值、二进制数据(需要 base64 编码)和空值都是支持的属性数据类型。这些都是可以插入到属性字段中的单一值示例。

DynamoDB 还允许将一组项插入到属性中。这些集合可以包含数字、二进制数据或字符串。集合必须是相同类型的,因此不能将数字和字符串混合在一个集合中,且集合不保留顺序。

类似于文档数据库,DynamoDB 允许将 JSON 文档作为属性添加,并且这些文档可以最多嵌套 32 层。

注意

主键必须是字符串、数字或二进制。

在 DynamoDB 中插入和访问数据

现在我们已经介绍了 DynamoDB 的历史和理论,接下来是时候动手操作,真正开始处理数据了。

对于我们的示例,我们将创建一个虚构的数据库,用来跟踪我们公司中的项目。这些信息可能包括 ProjectID、项目名称、项目负责人、项目或团队的联系邮箱,甚至其他信息如构建和语言信息。由于 DynamoDB 具有灵活的模式,并非所有行都需要这些信息。然而,我们确实需要声明我们的主键,然后根据查询需求,再声明次级键。

我们的模式将如下所示 JSON

{
Project_ID,
Department, 
Owner, 
< optional information (like language or build id) >, 
Contact_Email
}

定义好我们的模式后,我们可以开始创建表格。

在 DynamoDB 中创建表格

现在我们可以打开终端,使用以下命令创建我们的表格:

$aws dynamodb create-table --table-name projects \
--attribute-definitions AttributeName=Project_Name,AttributeType=S \
--key-schema AttributeName=Project_Name,KeyType=HASH \
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 

如果你将之前的命令与我们的模式进行对比,你会发现我们只定义了一个列:Project_Name。这是因为这个列是我们的哈希键(主索引)。其他字段可以稍后定义,不是必须的。这些字段将在数据插入后,无论是批量插入还是逐行插入时填充。需要注意的是,现在 Project_Name 字段中的所有字符串必须是唯一的,否则它们将因为重复值而被拒绝插入。

你可能也注意到,在语句的末尾,我们为表格最初分配了五个读取容量单位和五个写入容量单位。

向 DynamoDB 插入数据

在本书的 GitHub 目录下,在 chapter five 中,我们有几个文件需要上传到我们创建的表格中。为了这个练习,我们需要下载三个不同的 JSON 文件:

  • project_item.json

  • projects.json

  • projects_bulk.json

我们将通过 CLI 执行所有插入操作。虽然你可以在 Amazon 管理控制台 (AMC) 中进行单行和批量插入,但我们希望集中精力编写脚本命令,以便将来在需要时可以自动化执行。

我们将进行的第一种插入操作是将单个项目插入到表中。为此,我们需要 project_item.json 文件,如果你还没有下载该文件,请查看它的结构,如下所示,看看这个 JSON 文件的内容:

{
    "Project_ID": {"N": "0100"},
    "Dept": {"S": "Test Team"},
    "Dept_ID": {"N": "0001"},
    "Project_Name": {"S": "Serverless Forms"},
    "Owner": {"S": "Jerry Imoto"},
    "Builds": {"NS":  ["2212121"] },
    "Language": {"S": "python" },
    "Contact": {"S": "test_team@testcompany.com" }
}

在上传文件之前,我们想先查看一下文件的一些标注。你会注意到每个字段前都有数据类型标注。这里我们使用了字符串类型字段,标注为 S,数值类型字段标注为 N,最后,对于我们的构建,使用 NS 来表示一个数值列表。

现在我们可以打开终端,运行以下命令将项目添加到我们之前创建的 DynamoDB 表格中。在运行以下命令之前,请确保你已导航到下载文件所在的目录:

aws dynamodb put-item \
    --table-name projects \
    --item file://project_item.json \
    --return-consumed-capacity TOTAL

执行完上述命令后,你应该会收到类似以下内容的返回信息:

{
    "ConsumedCapacity": {
        "TableName": "projects",
        "CapacityUnits": 1.0
    }
}

恭喜!现在你在 DynamoDB 表中已经有了一个项。不过,仅有一个项对于查询来说并不理想,因此我们需要添加更多数据。通过 CLI 向表格添加多于一个项需要使用不同的命令和文件格式。

projects.json文件中,我们提供了10项,你可以通过batch-write-item命令将它们快速添加到表中。你还会注意到,在batch-write-item命令中,与put-item命令不同,你不需要指定表格。这个信息已经在表格中指定。

扫描数据

现在我们已经将测试数据加载到表格中,我们可以使用表扫描来查看这些数据项。扫描操作将返回表格中的所有项,或者在指定的索引中返回。

如果你还没有这样做,请返回到本书的 GitHub 仓库,并下载名为scan-values.json的文件,因为我们将在下一个练习中使用这个文件。

返回到终端(如果之前关闭了,重新打开)并输入以下命令:

aws dynamodb scan \
    --table-name projects \
    --filter-expression "Dept = :d" \
    --expression-attribute-values file://scan-values.json 

我们不会显示此命令的所有输出,但需要关注的是命令底部的部分,它会显示计数(Count),即返回的行数,以及扫描计数(Scanned Count),即扫描的总行数。

注意

这是一个高消耗的操作,因为你需要读取表格中的所有数据。如果你已经知道需要的数据,最好执行查询,只返回你需要的项和记录。

什么是 DynamoDB 中的扫描?

当你在 DynamoDB 表中执行scan命令时,表格或二级索引中的每一项都会被读取。如果你没有指定任何筛选条件,那么扫描将一次性返回所有项,只要结果数据不超过 1 MB。

查询数据

如果我们只想从表中检索某些值,或者希望 DynamoDB 告诉我们符合某个条件的记录数该怎么办呢?在这种情况下,与其使用扫描,使用查询会更高效。

在我们开始查询之前,确保你已经从本书的 GitHub 仓库下载了名为query-values.json的文件,该文件位于chapter five目录下。

让我们再次打开终端,这样我们就可以执行查询并查看返回的结果:

  1. 首先,确保你处在下载了query-values.json文件的同一目录下,或者将该文件复制到当前工作目录中。

  2. 第二,确保你已经创建了projects DynamoDB 表;否则,查询将不会成功。

  3. 在你的终端窗口中,输入以下命令:

    aws dynamodb query \
        --table-name projects \
        --projection-expression "Dept" \
        --key-condition-expression "Project_Name = :v1" \
        --expression-attribute-values file://query-values.json \
        --return-consumed-capacity TOTAL
    You should receive a result like the following one:{
        "Items": [
            {
                "Dept": {
                    "S": "Training"
                }
            }
        ],
        "Count": 1,
        "ScannedCount": 1,
        "ConsumedCapacity": {
            "TableName": "projects",
            "CapacityUnits": 0.5
        }
    }
    

请注意,在projection-expression的值中,我们标注了希望从表中返回的字段。我们已经知道了项目名称(因为它是我们的主键),所以我们是在查找这个项目所属的部门。这就是查询相比扫描所有数据在 DynamoDB 中查找和返回值时效率更高的方式之一。

DynamoDB 中的二级索引,包括全局和本地

如你所见,在我们之前的查询中,我们必须在执行命令时使用主键。在我们表的情况下,我们使用的是主键(Project_Name)。DynamoDB 中的表可以有多个不同的索引,这允许你的应用程序拥有多种不同的查询模式,而不必依赖扫描操作。这些索引可以包含表中所有数据或只是其中的一个子集。

注意

你必须在查询中声明索引,以便 DynamoDB 知道你是针对那个特定的索引执行操作。如果你没有声明特定的索引,查询将会直接作用于表本身。

本地二级索引(LSI)

本地二级索引LSI)使你有机会更改表中最初定义的排序键。LSI 必须始终使用与其创建的表相同的主键。

LSI 也共享与创建它的表相同的吞吐量。关于 LSI 的最后一点,它们只能在表创建时进行创建。如果在创建表时没有创建 LSI,那么你需要删除并重新创建表,或者创建一个新表然后迁移数据,或者改用全局二级索引GSI)。此外,你不能在不删除基础表的情况下删除本地二级索引。

GSI

如果我们想使用不同的主键进行搜索,那么我们必须创建一个 GSI。GSIs 和 LSIs 之间的另一个关键区别是,LSI 必须在表创建时声明和创建,而 GSI 可以在任何时间创建。如果你发现查询没有请求正确的信息,想要返回只包含部分信息的 GSI,或者某些查询需要更多的 RCU 或 WCU 配额时,GSI 尤其有用。

现在,如果我们想在创建完 GSI 后查看它,我们可以运行以下命令:

aws dynamodb describe-table \
    --table-name projects \
    --query "Table.GlobalSecondaryIndexes"

这将显示我们表上创建的任何 GSI(如果有的话)。

理解如何创建索引以优化查询性能是利用 DynamoDB 强大功能的关键概念之一。接下来,我们将继续了解 DynamoDB 的其他功能,例如使用流复制项目。

理解 DynamoDB 流

有时,您在 DynamoDB 中有一张表,您想要在变更发生时进行更新,或者发生事件驱动的流程。这正是 AWS 创建Dynamo Streams 的确切原因。流是项目修改的按时间顺序排列的序列,例如插入、更新和删除操作。

当 DynamoDB 中的流写入数据时,它会按严格的排序格式进行。这意味着当您向表中写入数据时,根据流的配置设置,它将按照写入到表中的顺序推送项目。

全局表

有时候,您需要在出现服务(如 DynamoDB)的区域性中断时设置高可用性计划,或者除了您最初创建数据的区域外,还需要更快的本地访问您的数据。

全局表,即使它们是原始表的副本,也都由单个账户拥有。

在设置全局表时,第一步是在您的主要区域创建一个初始表。

接着,您需要在初始表上启用 DB 流。

然后,对于您希望复制全局表的每个区域,您必须在不同的区域中设置启用流的同一表。

然后,在原始区域中,您可以定义全局表的设置,AWS 管理控制台使这一切变得轻而易举。

如果您的组织有通过服务级别协议SLA)传达的需求,需要保持一定的运行时间,那么您可以使用流和全局表的组合来处理这些问题。接下来,我们将介绍如何通过 DynamoDB 加速器加快查询时间。

使用 DynamoDB 加速器(DAX)

即使有成千上万的请求,DynamoDB 本身也能以毫秒级的延迟响应时间提供服务。这满足了许多公司和客户的需求,但有一些应用程序需要微秒级的性能,这就是DynamoDB 加速器DAX)的用武之地。

DAX 几乎等同于 DynamoDB 表的涡轮按钮。它缓存最常请求的结果,然后通过端点提供这些结果。无需启动第三方缓存,也无需管理节点,实现起来非常简单。您只需转到 DynamoDB 主页下的 DAX 菜单,然后启动您的 DAX 集群:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_5.5_B17405.jpg

图 5.5 – DAX 示例架构

在设计和实施系统以进行数字广告竞价时,广告技术等行业可以利用 DAX 的缓存属性和速度。在竞标时的毫秒级延迟可以等同于该行业中的实际资金。

知道如何处理在 DynamoDB 中执行时间超过预期的查询,这正是我们刚刚通过 DAX 的缓存功能介绍的。现在,我们将看看如何在 DynamoDB 中授权访问。

在 DynamoDB 中进行身份验证和授权

与 AWS 中的其他服务一样,DynamoDB 通过 IAM 服务允许精细的访问控制。你可以根据你如何构建 IAM 策略,选择在服务、表或属性级别允许或拒绝用户访问。

AWS 推荐作为最佳实践,使用最小权限原则,仅允许用户访问他们需要的数据表,而不是提供通用访问权限。

Web 身份联合

DynamoDB 是一个特别受移动应用和游戏开发者欢迎的后端数据库。这可能导致成千上万的用户需要访问单一的表。在这种使用场景下,为每个用户创建一个 IAM 用户是不可行的:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_5.6_B17405.jpg

图 5.6 – Web 身份联合到 DynamoDB 表

理解通过 Web 身份提供者(如 FacebookGoogle)进行身份验证的用户如何访问 DynamoDB 表中的数据,最好的方法是查看授予授权的步骤:

  1. 应用程序通过如 Amazon 等 Web 身份提供者进行身份验证。身份提供者然后返回一个身份令牌。

  2. 然后,应用程序调用安全令牌服务,以基于之前定义的角色获取临时访问凭证。

  3. 该角色应当不仅仅提供对整个 DynamoDB 表的访问权限,还应通过 IAM 策略授予用户对其项目的访问权限。

由于 DynamoDB 是托管在 AWS 上的移动应用的首选数据存储,我们探讨了如何通过 IAM 和 STS 令牌的组合授权 Web 身份用户访问特定数据。接下来,我们将继续监控我们的 DynamoDB 表,以确保不会被限流所困扰。

监控 DynamoDB

当你查看在监控 DynamoDB 时需要关注哪些指标,有几个指标会特别突出:

  • 我们的 GETPUT 请求在我们预期的范围内

  • 我们没有受到读写容量的限制

从 DynamoDB 控制台本身,我们可以获得关于表健康状况的许多指标。

首先,我们可以一眼看到读写容量。

你选择的任何表的指标中也有一个关于基本延迟的部分,显示四个关注点:GETPUT查询扫描延迟。

让我们登录到 Amazon 管理控制台,亲自查看这些基本指标:

  1. 使用你之前为 DynamoDB 中的项目表创建的账户登录到 Amazon 管理控制台

  2. 在顶部的搜索框中,输入 DynamoDB,以便服务名称出现在搜索结果中。点击 DynamoDB 进入 DynamoDB 服务。在右上角,仔细检查你是否处于创建表的正确区域。

  3. 一旦您到达 DynamoDB 主屏幕,单击左侧菜单中的Tables。单击后,您应该可以看到之前创建的名为projects的表:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_5.7_B17405.jpg

    图 5.7 – 显示左侧菜单中的 DynamoDB 表选项

  4. 单击主窗口中名为Projects的表。这将打开另一个窗格,添加更多有关您的表的信息。

  5. 在这里,我们可以从最右侧窗格的顶部选项卡栏中选择指标标签:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_5.8_B17405.jpg

    图 5.8 – 进入 DynamoDB 表后,顶部菜单栏

  6. 如果在指标显示中,您没有看到太多活动,那么可以尝试运行我们在本章中先前创建的 CLI 查询。这应该会促使指标计量器开始显示更多的数据 PUT 和 GET 对象。

贡献者洞察

启用贡献者洞察,可以让您更好地了解正在访问和受限的项。这使您能够在需要时相应地调整表或模式。

一旦启用贡献者洞察,如果您只有主键,DynamoDB 会为您创建两个规则:

  • 最常访问的项(分区键)

  • 最多受限的键(分区键)

如果您有全局二级索引或排序键,DynamoDB 将为您创建两个附加规则。这些规则是针对二级索引的:

  • 最多访问的键(分区键和排序键)

  • 最多受限的键(分区键和排序键)

总结

在本章中,我们了解了被称为 DynamoDB 的 NoSQL 服务。我们探讨了如何创建和分区表,以及如何从 DynamoDB 写入和查询数据。我们还研究了如何将数据从表流向其他源,并使用DynamoDB 加速器DAX),一种专门的缓存,来加速查询。

我们现在已经完成了第一部分,建立基础,在这一部分中,我们回顾了亚马逊 Web 服务。接下来,我们将进入第二部分开发、部署和使用基础设施即代码。在接下来的章节中,我们将整合我们刚才讨论的许多服务,并将它们付诸实践。

复习问题

  1. 我们的应用程序正在将项目数据存储在 DynamoDB 表中。您需要运行查询,找出上个月由特定部门执行的所有构建。您会在查询中使用哪些属性?

    a. Build_Date 的分区键和 Department 的排序键

    b. 由 DepartmentBuild_Date 组成的复合主键

    c. Department 的分区键和 Build_Date 的排序键

    d. Build_Date 的分区键和 Dept_ID 的排序键

  2. 以下哪项 AWS 服务提供了一个针对 DynamoDB 优化的内存写通缓存?

    a. ElastiCache

    b. CloudFront

    c. DAX

    d. Athena

  3. DynamoDB 中的扫描操作适用于以下哪种场景?

    a. 返回表的所有内容,并根据主键或排序键进行过滤

    b. 基于主键属性在表中查找项

    c. 基于排序键属性在表中查找项

    d. 返回表中的所有项

  4. 您的开发人员创建了一个 DynamoDB 表,并发现他们的性能总是在测试过程的 20-25 分钟后变慢。通过 AWS 控制台的基本监控,他们看到请求被限制。您可以做什么来帮助找出问题的根本原因?

    a. 增加表上的读取容量单位RCUs),以使查询不再受限制。

    b. 在表上启用Contributor Insights,以便显示被限制最多的键。

    c. 添加增强的Cloud Watch监控,并在发生限制时触发警报。

    d. 向表中添加自适应容量,使额外的读取容量单位RCUs)均匀分布到变热的分区中。

  5. 以下哪一项适合作为分区键?

    a. OrderID

    b. Ship_From_Location

    c. Total

    d. Product_Brand

查看答案

  1. b

  2. c

  3. d

  4. b

  5. a

第二部分:开发、部署和使用基础设施即代码

在本部分中,我们将应用自动化 CI/CD 流水线所需的概念。你将学习如何进行测试、管理工件以及部署/交付策略。

本书的这一部分包括以下章节:

  • 第六章理解 CI/CD 和 SDLC

  • 第七章使用 CloudFormation 模板部署工作负载

  • 第八章使用 CodeCommit 和 CodeBuild 创建工作负载

  • 第九章使用 CodeDeploy 和 CodePipeline 部署工作负载

  • 第十章使用 AWS Opsworks 管理和部署你的应用栈

  • 第十一章使用 Elastic Beanstalk 部署你的应用

  • 第十二章Lambda 部署与版本控制

  • 第十三章蓝绿部署

第六章:理解 CI/CD 和 SDLC

软件开发生命周期SDLC)是考试中最重的部分。理解 SDLC 的概念,以及 持续集成CI)和 持续部署CD)是通过 亚马逊 Web 服务AWS开发运维DevOps)考试的关键。SDLC 包括多个阶段,AWS 和第三方服务与这些阶段相对应。

了解 AWS 服务所扮演的角色—以及关键的第三方工具—不仅对通过考试至关重要,也是作为 DevOps 工程师日常工作中的必备知识。

在本章中,我们将讨论以下主要内容:

  • SDLC 介绍

  • 开发团队

  • 了解不同类型的部署

SDLC 介绍

SDLC 包括以下六个基本周期或阶段:

  • 源代码

  • 构建

  • 测试

  • 部署(发布)

  • 监控

  • 计划

以下是这些阶段的示意图:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_6.1_B17405.jpg

图 6.1 – CI/CD 阶段

这四个阶段属于 DevOps 的开发侧。第五个阶段属于运维侧,最后一个阶段是团队合作完成的。你可能注意到,前面的示意图中没有规划阶段。再次强调,虽然规划阶段是 SDLC 的重要部分,但它不属于 CI 或 CD 流程的一部分。

在本节的讨论中,我们需要理解的一个重要概念是缩写 CI/CD 的使用。我们在讨论 CI 阶段时,实际上是在谈论管道的前三个步骤。

CI

CI 是一种软件开发实践,开发人员定期将代码更改合并到中央仓库中。然后,启动一个或多个自动化构建,并对已提交的代码以及之前的现有代码库运行测试。

AWS 原生 CI 工具

接下来,我们将看看 AWS 在其生态系统中提供的一些工具,以帮助实现 CI。

AWS CodeCommit

AWS CodeCommit 允许你以高度可扩展的方式托管私有源代码控制仓库。

以下是 CodeCommit 的主要优势:

  • 协作能力:软件团队可以使用已知的 Git 功能,如拉取请求、分支和合并,共同协作开发代码库。

  • 加密:CodeCommit 仓库使用 AWS 密钥管理服务KMS)在静态时自动加密。代码在往返仓库的传输过程中,也会通过 安全超文本传输协议HTTPS)或 安全外壳协议SSH)加密。

  • 访问控制:与 AWS 身份与访问管理IAM)服务完全集成,允许你指定哪些用户可以访问哪些仓库,而无需通过第三方系统进行管理。

  • 高可用性:AWS CodeCommit 由亚马逊简单存储服务Amazon S3)和亚马逊 DynamoDB支持,用于代码和提交存储。这是一种高度冗余且可扩展的设置,确保你的仓库可访问。

  • 通知:CodeCommit 可以与亚马逊简单通知服务Amazon SNS)集成,使得与仓库相关的重要事件可以广播到正确的渠道。CodeCommit 发送的通知包括状态信息和指向相应仓库的链接。

AWS CodeBuild

当你准备编译你在源代码控制仓库中提交的代码并为部署创建软件包时,AWS CodeBuild 允许团队使用 YAML Ain’t Markup LanguageYAML)语言自定义他们的构建和测试过程。

这些是 AWS CodeBuild 的主要优点:

  • 完全托管:使用 CodeBuild,无需设置单独的构建服务器。这意味着不再需要进行软件修补或更新,也无需管理任何东西。作业设置好并提交后,便会运行。

  • 安全:CodeBuild 与 IAM 服务集成,因此用户只能被分配到特定的构建项目。CodeBuild 生成的任何工件都使用 AWS KMS 进行加密。

  • 可扩展:CodeBuild 会根据提交的作业数量自动进行扩展。当有大量构建作业或测试即将发生时,无需考虑垂直或水平扩展,因为 CodeBuild 会自动处理所有这些。

  • 支持 CI 和 CD:作为AWS 开发者服务的一部分,CodeBuild 自然地集成到其他提供的 CI/CD 工具中,例如 CodeCommitCodePipeline。它还与生态系统中的其他工具进行了集成——例如,Jenkins 可以将 CodeBuild 作为可扩展的工作节点使用。

AWS CodeArtifact

随着软件构建变得越来越规范化,公司和团队开始寻找一种方式,确保每个人都在使用相同的已批准的软件包及其版本。这就是托管工件库CodeArtifact的作用所在。

如果你对构建过程的安全性感兴趣,CodeArtifact 提供了许多功能,帮助开发团队创建一个更安全的环境。首先,构建过程中所需的包和工件可以通过使用 AWS PrivateLink 终端节点从虚拟私有云VPC)中访问。这意味着,如果你在 CodeArtifact 服务中存储了构建所需的库和文件,那么这些文件可以传输到你的函数和实例中,而无需穿越公共互联网。

其次,通过 CodeArtifact 服务,作为账户管理员的你可以批准使用特定的包。这个批准过程也可以通过结合使用 CodeArtifact 应用程序编程接口API)和 Amazon EventBridge 服务来自动化。

第三,许多包仓库最近开始对其服务器设置下载限制。由于仓库当前不接受来自当前互联网协议IP)地址的下载请求而导致部署或构建失败,不仅令人沮丧——它还可能成为部署的真正障碍。例如,如果你是在实时构建实例,而不是使用预先构建的Amazon 机器镜像AMI),并且需要从公共Node Package Managernpm)服务器获取某些节点包,那么如果你处于自动扩展状态并且试图扩大规模以满足客户的流量需求,这种情况就不仅仅是个小问题。然而,如果你将包存储在 AWS CodeArtifact 上,那么你就不受任何第三方服务器的限制,可以根据需要多次下载所需的包,正如下图所示:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_6.2_B17405.jpg

](https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_6.2_B17405.jpg)

图 6.2 – AWS CodeArtifact 与外部仓库的连接

你可以配置 CodeArtifact 从公共仓库获取流行的包,并为你的团队进行存储和版本控制。CodeArtifact 可以与许多开发者熟悉并且舒适使用的包管理工具协同工作,包括pipyarnnpmMavenGradle

这些是 CodeArtifact 的主要优点:

  • 安全存储和共享制品:如果与 KMS 服务集成,你在 CodeArtifact 中存储的制品可以被加密。

  • 减少运营开销:CodeArtifact 消除了设置和维护制品服务器的需求。它是一个高度可用的服务,可以根据存储的制品数量自动扩展。

  • 发布和共享包:CodeArtifact 为你提供了一个中心位置来发布你的团队创建的包,消除了在互联网上到处寻找的需求。

  • 只需点击几下,便可连接npm注册表、NuGet.orgMaven Central,无需复杂的脚本。

持续交付

如果生产环境的部署是通过持续交付完成的,那么很可能会有一个手动批准的过程,而不是自动部署。

AWS 原生工具用于持续交付

让我们简要了解一些用于持续交付的 AWS 工具。

AWS CodeDeploy

这些是 CodeDeploy 的主要优点:

  • 自动化部署:CodeDeploy 完全自动化软件部署。

  • 易于采用:CodeDeploy 可以轻松集成到你现有的部署工具中,如 Jenkins、GitHub 或 AWS CodePipeline。

  • 集中控制:在一个视图中,CodeDeploy 可以同时显示你的部署状态,并提供向一个或多个团队成员发送推送通知的功能,告知他们构建的通过或失败状态。

  • 最小化停机时间:CodeDeploy 允许你逐步引入更改,从而帮助保持应用程序的可用性。如果发现问题,它还可以帮助你回滚到之前的版本。

AWS CodePipeline

AWS CodePipeline 允许你自动化构建、测试和部署步骤,以及你在生产软件和 基础设施即代码IaC)过程中经过的各个阶段。它还可以与 GitHub 等第三方服务集成。

这些是 CodePipeline 的主要优势:

  • 快速交付:CodePipeline 在你将代码通过结构化流程推进到部署过程中,快速地向你和你的团队提供反馈。缺陷可以在没有太多努力的情况下被发现并修复。

  • 易于集成:如果你已经在 CI/CD 流程中使用了现有的组件,CodePipeline 允许你轻松集成这些组件。包括已经设置好在云端或本地运行测试的 Jenkins 服务器,或者甚至是像 GitHub 这样的第三方源代码库。

  • 可配置工作流:每个软件发布的过程都有些微不同,取决于配置的测试或所部署的服务。CodePipeline 使你能够以多种方式自定义步骤,包括使用 AWS 管理控制台 界面、命令行界面CLI)或可用的 AWS 软件开发工具包SDKs),甚至可以通过编写 CloudFormation 模板 来构建管道。

  • 提高质量:CodePipeline 使你能够自动化所有流程,按照易于遵循的步骤执行,从而确保在部署过程中不会遗漏任何步骤。自动运行的测试确保了代码的一致性,并为开发者提供即时反馈。

CD

使用 CD,不需要手动批准流程,因为代码修订会被推送到生产环境中。相反,依赖于测试实践和指南来确保代码的完整性,在被自动部署到生产环境之前,必须通过质量检查。任何不符合这些指南的修订将会作为构建过程失败,并且会将反馈提供给开发者或开发团队。最初的反馈可能非常简单,比如通知构建失败,可以通过电子邮件或 短消息服务SMS)消息的形式发送,甚至可以使用 SNS 服务 发送。另一种选择是通过 SlackMicrosoft Teams 等消息服务发布,结合使用 SNS 和 AWS Lambda 来发布消息。

注意

持续交付并不是CD。这是许多人常犯的错误。然而,你需要理解的是,持续交付意味着每次提交都必须通过一组自动化测试,然后才会推送到生产环境中。

让我们看看 SDLC 如何在 AWS 提供的不同开发工具中得以实现。从以下图示中,你可以看到几乎每个阶段都有自己的专用服务。例外的是构建和测试阶段,AWS CodeBuild 可以同时执行这两项任务:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_6.3_B17405.jpg

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_6.3_B17405.jpg

图 6.3 – AWS 工具在 CI/CD 中的应用

Amazon 代码工具的角度来看,CI 和持续交付有几个工具可以帮助你完成这些任务。

测试

测试在软件开发生命周期(SDLC)中起着至关重要的作用。它可以帮助你提升应用程序的可靠性、可扩展性、性能和安全性。

注意

你有没有注意到测试所提供的许多内容正是 AWS 的支柱?尽管将测试排除在最初的管道设计之外看似更快,但它是确保工作负载稳定性、安全性和能力的关键部分。

如果你的代码中存在潜在的弱点,测试是发现其中许多问题的途径之一。这可以防止你将致命缺陷部署到生产环境中。作为一名 DevOps 工程师,在自动化这个过程时,构建管道的初期投入可能会有些费力。一旦管道和测试建立完成,随后多种类型的代码——包括基础设施即代码(IaC)和应用程序代码——都可以以快速和可重复的方式进行测试和部署。

相关测试类型

有多种不同类型的测试可以确保你的代码库按预期运行。每种类型的测试执行特定任务,有些测试需要的时间较长。以下是一个展示不同测试阶段的图示:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_6.4_B17405.jpg

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_6.4_B17405.jpg

图 6.4 – 测试的不同阶段

通过查看图 6.4,我们可以看到测试执行的相对速度。现在我们可以更详细地查看每种测试类型。

单元测试

单元测试虽然覆盖的代码量较小,但为开发者提供即时反馈,尤其是因为它们可以直接在开发者的个人机器上运行。它们可以添加到 CI/CD 管道中,主动防止已知缺陷进入代码库。

服务集成和组件测试

集成测试用于检查系统中不同组件是否能够协同工作。这些测试也可以包括对任何第三方服务或 API 的测试。例如,集成测试可能会测试 Web 层是否将一个测试值插入数据库以确保连接正常,或在事件发生后发送通知。

性能和合规性测试

一旦你构建了应用程序,你需要知道它能够有效地处理你预计的流量。这包括根据需要扩展或缩减资源,并在系统承受较大负载时进行检查。性能测试将帮助完成这项任务,揭示系统在正常使用或高负载情况下可能表现出的性能问题或瓶颈。两种最常见的性能测试类型是压力测试和浸泡测试。压力测试会在短时间内或设定的例程数量内模拟大量用户使用资源,比如回放 web 服务器日志以模拟过去的用户。浸泡测试则会在更长时间内(如一周或更长)持续提供稳定的用户流,尝试揭示如内存泄漏或在短时间内未能显示的问题。

添加安全性和合规性测试,如静态应用安全测试SAST)和动态应用安全测试DAST),可以揭示已报告和发现的已知漏洞。将这些类型的测试添加到你的 CI/CD 管道中,是开发-安全-运维DevSecOps)框架的一部分。

用户界面测试

在金字塔的顶端是用户界面UI)测试。这些测试不仅测试图形用户界面GUI),还测试整个系统。测试可以涵盖像确保用户能够正确登录或重置密码的例程。它们可能包括上传和下载文件或访问特定页面,这些页面涉及数据存储和中间件组件。

虽然在这个阶段可能出于必要性引入手动测试,但最好将手动测试保持在最低限度。

在整个过程中不断成熟

当你最初开始构建 CI 系统时,可能只有几个步骤,比如从源代码仓库拉取代码并部署到测试服务器。

随着时间的推移,代码库将获得更广泛的测试覆盖,设置也将调整,以便团队成员对部署过程更加自信,甚至依赖它作为日常工具之一。

随着你的成熟,你会发现自己开始获得以下几个好处:

  • 速度:团队通过自动化管道和发布过程变得更加自给自足。无需再等待特定人员或团队来安装已开发的软件包或更新。

  • 可靠性:自动化过程消除了对单个了解流程的人的依赖。任何启动过程的团队成员都会有信心每次启动时都能得到相同的结果。

  • 一致性:创建具有标准步骤的部署管道可以使每次启动过程时都保持一致的流程。这可以防止测试等步骤被遗忘或跳过。

  • 可扩展性:随着组织的扩展,更新的频率通常会增加。自动化流水线拥有构建、测试和部署到不同环境的步骤,帮助你在不增加额外人员的情况下实现扩展。

  • 效率:将测试从手动过程转移到自动化过程,不仅可以加速测试过程,还可以使测试团队将精力集中在开发新的和改进的测试上,而不是花时间手动测试系统。

现在我们已经了解了实际的 SDLC 过程,接下来我们将讨论如何优化 CI/CD 过程中的团队设置。

开发团队

AWS 建议在实现 CI/CD 环境时,拥有三个开发团队:应用团队基础设施团队工具团队。亚马逊推崇“两块披萨团队”的概念,即任何团队的规模都不应超过两块披萨能够喂饱的程度。较小的团队有助于更好的协作,完全拥有自己的特性或应用程序,承担完整的责任,最后但同样重要的是,这一切与 DevOps 的敏捷模型一致。

应用团队

应用团队成员负责创建应用程序本身。该团队的成员精通一种或多种编程语言,并且深入理解平台和系统配置。

应用团队成员负责创建待处理的事项清单,以及为工作中的故事创建任务。除了具备创建和维护应用程序的编程技能外,该团队还应该掌握自动化技术,以便在工具链创建完成后,团队成员可以创建自己部分的流水线。

基础设施团队

为了使应用团队成员能够运行他们的应用程序,必须有一些基础设施来支持它们的运行。即便是无服务器应用,它仍然需要在 IAM 中创建权限。如果不是无服务器设置,则需要配置和管理服务器。

基础设施团队合作,这一过程通过 IaC(基础设施即代码)完成,可以通过 CloudFormation,使用 AWS CLI 脚本,或使用 AWS 的云开发工具包CDK)。

许多时候,工具团队还需要负责例如Active Directory(AD)服务器单点登录(SSO)集成等任务,特别是因为它们与 IAM 权限紧密相连。

工具团队

工具团队负责构建和管理 CI/CD 流水线。该团队必须熟练构建和集成流水线的各个部分和组件,以确保依赖的应用团队能够顺利进行工作。虽然工具团队不是“两块披萨团队”的一部分,但它负责创建使其他团队能够执行任务的工具和系统。

团队可能会选择实现诸如 AWS CodeCommit、CodePipeline、CodeBuild 和 CodeDeploy 等工具和服务,以及 Jenkins、GitHub、Bitbucket、Artifactory 等第三方工具。

许多组织会将工具团队归类为 DevOps 团队,但这是一个误称,因为 DevOps 更多的是一种人和过程的实践,而不是单纯的工具使用。

并非每个工具团队都已经准备好完全采用 AWS 工具集,AWS 也理解这一点。甚至有一份关于自动化服务器 Jenkins 的完整白皮书。了解第三方工具如何与 AWS 生态系统交互并互补,是 DevOps 专业考试的必备知识。

随着团队成员现在可以集中精力在各自的领域中,以最大化其效率,我们将继续讨论部署类型,并了解如何选择最适合我们需求的部署策略。

了解不同类型的部署

当你考虑部署时,尤其是我们一直在讨论的软件开发生命周期(SDLC),你可能会认为我们在讨论应用程序代码。然而,当你在 AWS 中自动化更多系统时,部署可能会有多种含义。部署可以指应用程序代码,但也可以指基础设施代码、配置代码或其他层级。

在处理 AWS 上的部署时,有五种主要的部署策略需要考虑。每种方法都有其优缺点。

在选择部署策略时,以下是你需要考虑的主要事项:

  • 你能多快完成部署?

  • 是否需要任何域名系统DNS)的更改?

  • 如果部署失败,会有什么影响吗?

  • 回滚过程将是什么样的?

  • 代码会链接到哪里?(新实例还是现有实例?)

考虑到这一点,让我们深入研究五种不同的部署策略。

就地部署

当你执行就地部署时,你是在更新已经部署到环境中的实例。可以使用负载均衡器在部署过程中注销每个实例,进行健康检查,然后将健康的实例重新投入服务。就地部署可以一次性完成,也可以以滚动部署的方式进行。

让我们来看一下就地部署的优缺点,如下所示:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/012.jpg

表 6.1 – 就地部署的优缺点

不可变部署和蓝绿部署

蓝绿部署中,会创建一个全新的基础设施,并且通常在进行 DNS 切换之前进行测试。这是最安全的部署方法,但它需要时间并且成本最高,因为你需要为一段时间同时搭建两个完整的环境,直到进行 DNS 切换。切换后,你可以选择在第二个环境不再使用时将其关闭以节省成本,或者将其保持运行以节省部署时间,并将其用作故障转移环境。如果部署失败,客户将完全感知不到任何问题,因为使用蓝绿部署时,只有当第二个(或绿色)环境上线并健康时,才会切换 DNS。

不可变部署指的是使用新的配置或新应用程序代码部署整个资源集。这项任务在云端比在本地硬件上简单得多,因为资源可以通过简单的 API 调用进行配置。

以下表格显示了不可变部署的优缺点:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/02.jpg

表 6.2 – 蓝绿部署的优缺点

参见第十三章蓝绿部署,深入了解蓝绿部署的更多内容。

金丝雀部署

在新的实例规范名称CNAMEs)上为 0%,或者通过将新实例从负载均衡器中移除来实现。此时,新实例将被下线,任何先前更新过的启动配置都可以更新为使用一个之前工作的 AMI 版本。

在下表中,我们对比了使用金丝雀部署方法的优缺点:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/03.jpg

表 6.3 – 金丝雀部署的优缺点

滚动部署

使用滚动部署时,并非所有实例都会同时更新。这一策略可以防止停机,因为如果某个进程失败,只有部分实例会在某个特定时间进行升级。当初始实例部署时,它们必须在进一步部署其他实例之前确保健康并在线。

需要注意的是,由于无论是应用程序代码还是系统升级,组内的所有成员并非同时部署,因此用户可能会体验到多个版本。在部署过程中,使用粘性会话有助于提供尽可能无缝的客户体验,但无法完全消除这种体验的差异。

尽管优缺点列表不长,但请看下表,了解使用滚动部署方法的利弊:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/04.jpg

表 6.4 – 滚动部署的优缺点

线性部署

在线性部署中,流量会按照预设的多个增量平等地切换到不同的资源上。线性部署是蓝绿部署的一种子集。与直接部署到应用当前运行的实例或资源不同,你首先需要搭建一套新的基础设施,然后在一段时间内将流量从旧的代码库迁移到新的代码库,可以使用如 Route 53 和加权路由这样的服务。这样,你可以密切监控新环境,如果出现问题,能够迅速将所有流量切换回原始环境,从而避免停机。

线性部署还可以通过 Lambda 别名和 Fargate 容器来实现,将部分流量切换到新版本的代码。

例如,如果你的部署窗口是 1 小时,并且希望在该小时内将 100% 的流量平均分配到新资源上,那么你的线性部署策略可能如下:

  • 最少 0-16% 的流量切换到新资源

  • 最少 10-32% 的流量切换到新资源

  • 最少 20-48% 的流量切换到新资源

  • 最少 30-64% 的流量切换到新资源

  • 最少 40-80% 的流量切换到新资源

  • 最少 50-96% 的流量切换到新资源

  • 最少 60-100% 的流量切换到新资源

使用线性部署方法有优缺点,因此我们在此进行比较:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/05.jpg

表 6.5 – 线性部署的优缺点

我们将在 第十二章 中深入探讨 Lambda,Lambda 部署与版本管理

一次性全部部署

在这种部署方式中,所有流量会同时从原始环境切换到新环境。这是所有部署方法中最快的。这也意味着,如果需要回滚,所需的时间将是最长的,因为代码需要重新部署到所有实例上。如果遇到问题,你可能会有停机时间,因为你需要等待回滚过程完成后才能恢复在线状态。

使用 一次性全部部署方法 的优缺点在下表中列出:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/06.jpg

表 6.6 – 一次性全部部署的优缺点

注意

一次性全部部署也可以称为就地部署。请熟悉这两个术语,因为它们都可能出现在测试题中。

复习问题

  1. 一家中型软件公司聘请你作为 DevOps 顾问,帮助搭建其部署流水线。员工希望能够快速将经过测试的代码推送到生产环境,但又不想面临客户停机的风险。他们的 DNS 托管在第三方服务商上,DNS 的变更需要提交变更工单。你会推荐哪种部署方式?

    a. 蓝绿部署

    b. 原地部署

    c. 一次性部署

    d. 滚动部署

  2. 一家医疗设备公司希望通过 Jenkins 设置其开发流水线,以自动化部署代码库。由于这只是开发环境,他们希望保持成本最低,并且如果部署失败,应用团队重新部署也是可以接受的。应该使用哪种策略?

    a. 蓝绿部署

    b. 原地部署

    c. 一次性部署

    d. 滚动部署

  3. 一家移动游戏公司正在努力加快其最受欢迎游戏的生产时间,以便开发新的功能。员工注意到,在最近两次发布的日期,用户在社交媒体上抱怨出现了更多的故障。有些故障是已知的,由负责游戏开发的团队处理。该游戏公司已经设置了一个自动化部署流水线,使用 AWS CodePipeline,并将代码存储在 AWS CodeCommit 中。最具成本效益的方式是什么,以减少每次发布时出现的故障数量?

    a. 启动一个新环境,并在将代码发布到生产环境之前运行完整的 UI 测试。

    b. 在当前的 CodePipeline 中添加一个步骤,启动一个运行 Jenkins 软件的 EC2 实例,并使用 Simple Systems Manager (SSM) Parameter Store 下载当前的 CodeCommit 仓库,然后运行单元测试来判断构建是否通过。

    c. 在当前的 AWS 流水线中添加一个 CodeDeploy 步骤,该步骤运行当前的一组单元测试,并将其连接到 AWS SNS 主题,以便在测试失败时,当前构建失败,并通知开发团队。

    d. 在当前的 AWS 流水线中添加一个 CodeBuild 步骤,该步骤运行当前的一组单元测试,并将其连接到 AWS SNS 主题,以便在测试失败时,当前构建失败,并通知开发团队。

  4. 一家研究公司正在进行一个机密项目,管理团队希望能够在任何进展发生时立即了解情况。开发人员使用 AWS CodeCommit 进行源代码版本控制,并使用 CodeBuild 运行单元测试。你可以采取哪些措施来让管理团队获得他们想要的更新?(选择所有适用项)

    a. 为管理团队创建一个 SNS 主题,并添加他们所有的电子邮件。

    b. 让 AWS CodeCommit 在每次提交或功能分支与主分支合并时,将通知推送到 SNS 主题。

    c. 让 CodeCommit 创建每日提交活动报告,并将报告推送到 S3,以便管理团队可以从他们有权限访问的存储桶中查看该报告。

    d. 在 AWS CodeBuild 上启用通知,当作业通过或失败时,通知推送到 SNS 主题。

  5. 一家正在成长的公司目前有一个在 EC2 上运行的 Jenkins 服务器。开发人员抱怨他们等待构建启动和完成的时间太长。你被要求帮助工具团队提出一个能够随着开发团队的增长和速度扩展,但又能以最快和最具成本效益的方式实施的解决方案。哪种解决方案最不需要工具团队的管理?

    a. 从 Jenkins 服务器创建一个 AMI,并使用该 AMI 创建三个额外的工作节点,当前的 Jenkins 系统作为主节点。

    b. 使用1将 Jenkins 服务器重建为一个容器化系统。

    d. 从 Jenkins 服务器创建一个 AMI,并使用该 AMI 创建一个启动配置,用于自动扩展组,当队列超过1时启动新的 Jenkins 实例。

回顾答案

  1. d

  2. b

  3. d

  4. a, b, d

  5. c

总结

在本章中,我们讨论了SDLCCI持续交付CD。我们还开始了解 AWS 提供的工具,这些工具可以帮助我们在 SDLC 的不同阶段中发挥作用。接着,我们探讨了不同类型的团队及其职责。最后,我们回顾了 AWS 中可用的不同类型的部署策略,以及如何最佳地使用它们。

在下一章中,我们将深入探讨 AWS 的 CloudFormation 基础设施即代码(IaC)服务。我们将看到如何创建可重用的资源,以及在 CloudFormation 模板中可用的脚本方法。

第七章:使用 CloudFormation 模板部署工作负载

CloudFormation 模板为 DevOps 工程师提供了一种简单的方法,能够自动创建、管理和配置相关资源。它们还允许你快速地重复搭建相同的基础设施,无论是用于开发、测试、生产还是灾难恢复。它们不仅是一个重要的概念,也是 DevOps 专业认证考试中需要理解的内容。

在本章中,我们将涵盖以下主要主题:

  • CloudFormation 的基本主题

  • 创建带有依赖关系的嵌套堆栈

  • 向 CloudFormation 模板添加辅助脚本

  • 了解如何检测以前创建的堆栈中的漂移

  • 使用 Cloud Development KitCDK)作为开源框架

技术要求

在处理 CloudFormation 模板时,本章比前几章更加注重实践,而前几章更多关注理论。你应该对 YAML 语法感到熟悉,并且此时你应该对 AWS 管理控制台以及 CLI 都有一定的了解。本章讨论的大多数模板由于过于庞大,无法在接下来的页面上完全列出,因为一些 CloudFormation 模板可能会有几千行。我们已经将这里讨论的模板包含在本书的 GitHub 仓库中的 Chapter-7 部分:github.com/PacktPublishing/AWS-Certified-DevOps-Engineer-Professional-Certification-and-Beyond/tree/main/Chapter-7

CloudFormation 的基本主题

在我们希望构建可重复的基础设施并通过自动化实现的过程中,拥有正确的 基础设施即代码IaC)工具,可以实现这些可重复的流程。正是这些可重复的流程使 CloudFormation 服务发挥作用。CloudFormation 是一种 IaC,可以检查到源代码管理系统,如 CodeCommitGitHub。它作为一段代码的特点,使得它可以进行版本控制,并且可以与多个团队成员协作。它也可以作为 CI/CD 过程的一部分,添加到自动化构建管道中。

CloudFormation 模板可以使用 JSONYAML 编程语言构建。使用 YAML 允许在模板中添加注释并使用简短的代码。然而,你确实需要遵循严格的 YAML 格式化规则。

一旦你创建了一个模板,特别是一个包含正确映射且没有硬编码引用的模板,它就具备了反复使用的能力。这意味着你可以在多个区域和多个账户中使用它。

CloudFormation 模板的结构

一个 CloudFormation 模板可以包含许多不同的部分。在创建 CloudFormation 模板时,只有一个强制性的部分,那就是资源部分。部分不一定需要按照特定顺序添加;然而,当你查看不同的示例时,会发现部分的结构有一个逻辑顺序,因为某些部分引用了其他部分。

格式版本

这是 CloudFormation 遵循的版本。它是一个可选部分。如果添加,通常是模板的第一个部分。

描述

描述是一个小段文本,告诉用户有关模板的信息。它必须始终位于模板的格式版本之后。描述非常有用,尤其是当你开始收集更多的模板时,它能帮助你快速了解模板的目的以及它将创建哪些类型的资源。这是一个可选部分。

元数据

该部分包含提供有关模板的附加信息的对象。这是一个可选部分。

参数

这是一个值的部分,可以在运行时传递到模板中。默认值也可以定义,以替代需要用户输入的值。这些值在创建资源时可以使用。你也可以引用模板中的资源输出部分的参数。这是一个可选部分。

规则

规则用于验证在运行时传递到模板的一个或多个参数。规则可以帮助强制执行一些要求,比如确保在生产环境中启动一个足够大的 EC2 实例,或者使用特定的子网。规则通常用于验证参数的输入。这是一个可选部分。

映射

使用内建的 Fn:FindInMap 函数,CloudFormation 可以找到与匹配值对应的键。映射部分最常见的使用场景之一是声明特定区域使用的正确Amazon 机器映像AMI),确保模板可以在多个区域中重用。这是一个可选部分。

当我们查看内建的 Fn:FindInMap 函数时,我们将深入了解映射。

条件

尽管 CloudFormation 模板没有很多可用的逻辑编程,但模板中的条件允许基于某些值的存在,分配特定值或创建特定资源。一个好的例子是,如果堆栈在测试环境中创建,那么它会创建一个数据库。然而,如果在生产环境中创建,它就不会创建。这是一个可选部分。

资源

本部分实际上声明了将由 CloudFormation 模板创建的资源及其属性。资源可以是各种各样的 AWS 服务,从 EC2 实例到 IAM 用户,甚至是聊天机器人Step Functions。AWS 提供的几乎所有服务都可以通过 CloudFormation 模板创建。这个部分是必需的。

输出

输出允许声明一个键值对及其对应的描述,该描述可以在堆栈创建完成后供最终用户使用,或者供另一个堆栈使用。在最终用户的情况下,你可能想要输出刚刚启动的 EC2 实例的 URL 或 IP,以便你不需要在控制台中四处寻找。或者,在为其他堆栈创建输出供其使用时,Amazon 资源名称ARNs)是可以在其他堆栈中作为参考点使用的主要项之一。这是一个可选部分。

启动 CloudFormation 模板

一旦你准备好了模板,就可以通过 AWS 管理控制台或SQSqueues.yml来启动它。如果你想跟随以下练习,请去仓库并下载这个模板。或者,你可以使用你自己的 CloudFormation 模板,但要记住,参数和资源会有所不同,尽管过程仍然遵循相同的步骤:

  1. 将下载的模板上传到你的 S3 存储桶,我们在第四章中创建了该存储桶,Amazon S3 Blob 存储。(在我们的例子中,存储桶的名称是devopspro-beyond):

    $aws s3 cp sqs-queues.yml s3://devopspro-beyond/sqs-queues.yml
    
  2. 现在模板已上传,登录到 AWS 管理控制台并导航到 CloudFormation 服务页面:us-east-2.console.aws.amazon.com/cloudformation/

  3. 点击右侧标有创建堆栈的橙色按钮。

  4. 前提条件 – 准备模板下,确保已选择模板已准备好选项的单选按钮:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_7.1_B17405.jpg

    图 7.1 – CloudFormation 前提条件

  5. 指定模板下,确保已选择Amazon S3 URL选项,然后在 URL 字段中输入模板所在位置的值,在我们的例子中是devopspro-beyond.s3.us-east-2.amazonaws.com/sqs-queues.ymlhttps://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_7.2_B17405.jpg

    图 7.2 – CloudFormation 指定模板屏幕

  6. 点击页面底部的橙色下一步按钮。

  7. 我们现在需要填写一些细节,才能继续操作。我们从SQSqueue开始(不允许有空格)。

  8. 接下来,填写其余的参数,为AlarmEmail字段添加你的地址,为QueueName字段添加队列的名称。你可以将另外两个值保持为默认值。完成后,点击页面底部的橙色下一步按钮:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_7.3_B17405.jpg

    图 7.3 – 输入模板的参数

  9. 在下一页,标记为配置堆栈选项,向下滚动到页面底部并点击橙色的下一步按钮。

  10. 我们现在可以查看我们输入的内容,如果一切看起来正确,向下滚动到页面底部并点击橙色按钮,标签为创建堆栈

一旦我们开始创建过程,我们将被带到Stacks屏幕,在那里我们可以看到CREATE_IN_PROGRESS通知,表示我们的堆栈正在创建中。

在这一部分的顶部有一个菜单,允许你查看每个堆栈创建的具体资源、堆栈的具体信息、堆栈创建后你声明的任何输出、创建堆栈时输入的参数、用于创建堆栈的实际模板以及在堆栈上使用的变更集。

当你启动一个 CloudFormation 模板时,该模板会保存在一个 S3 桶中。如果你之前没有将模板保存到 S3 桶中,AWS 会在你启动模板的区域创建一个 S3 桶。每次你更新模板或启动新版本时,模板的一个新副本会被添加到这个桶中。

使用 CLI 启动模板

在通过管理控制台启动模板的所有步骤之后,我们可以看到,如果我们打算将部署自动化为 CI/CD 流水线的一部分,那么每次都这样做显然是不实际的。AWS CLI 确实有一个deploy命令,它允许我们通过一条命令启动一个堆栈。在运行该命令之前,确保你已经从 GitHub 仓库的Chapter-7文件夹中下载了 YAML 模板。下载后,打开你的终端窗口,并将模板复制或移动到你的工作目录中,或者将工作目录更改为你下载模板的位置:

启动模板的 CLI 命令示例如下所示:

$aws cloudformation deploy --template my-template.json --stack-name CLI-stack --parameter-overrides Key1=Value1 Key2=Value2

通过这一条命令,我们已经复制了之前经历的所有步骤。正如前面所提到的,我们的模板应该存储在一个随机命名的 S3 桶中,因为我们在创建过程中上传了它,而 CloudFormation 服务为我们存储了它。

使用变更集

如果你的 CloudFormation 堆栈需要更新,有时你可能希望了解并理解当前正在运行的现有资源会如何受到影响。变更集允许你预览更改如何影响当前运行的资源,在任何更改发生之前,然后如果更改对当前资源有害,你可以取消更新,或者如果更改按预期执行,则可以继续。

注意

变更集不能告诉你 CloudFormation 执行时是否会成功运行。它们无法预见你可能遇到的账户限制更新,也无法判断你是否具备更新资源所需的正确 IAM 权限。

执行变更集的步骤

让我们看看执行变更集所需的强制性步骤和可选步骤:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_7.4_B17405.jpg

图 7.4 – CloudFormation 变更集

在掌握了如何执行变更集的基础之后,我们将使用变更集来更新原始的 CloudFormation 堆栈——SQSqueue

使用变更集更新我们的堆栈

如果你还没有这样做,那么从 GitHub 仓库的 Chapter-7 文件夹中下载名为 sqs-queues_change_set.yml 的模板。这就是我们将用来创建变更集的文件。还要确保你已经打开浏览器,进入 AWS 管理控制台,并导航到 CloudFormation 服务,然后按照以下步骤操作:

  1. 在 CloudFormation 堆栈页面,你应该会看到你的 SQSqueue 堆栈处于 CREATE_COMPLETE 状态。点击堆栈名称,进入堆栈的详细信息页面。在这里我们可以执行变更集:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_7.5_B17405.jpg

    图 7.5 – 我们之前创建的 CloudFormation 堆栈

  2. 在堆栈名称下方的横向菜单中,你会看到多个选项,包括最右侧的变更集。点击变更集选项:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_7.6_B17405.jpg

    图 7.6 – CloudFormation 堆栈菜单,右侧高亮显示变更集选项

  3. 进入变更集部分后,点击标记为创建变更集的按钮。

  4. 此时,将出现一个新屏幕,标题为先决条件 – 准备模板。你将看到三个选择。选择中间的选项,标题为替换当前模板https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_7.7_B17405.jpg

    图 7.7 – CloudFormation 变更集准备模板屏幕

  5. 这将使另一组选择项出现在初始单选按钮下方。这一次,我们不是在创建变更集之前将模板上传到 S3,而是使用我们之前从 GitHub 仓库下载的YAML文件(sqs-queues_change_set.yml)在此处上传模板。上传文件后,点击橙色的下一步按钮。

  6. 下一屏幕,参数,应确认我们在首次创建模板时输入的参数。此时我们不会更改任何参数,因此只需点击页面底部的橙色下一步按钮。

  7. 在下一屏幕,配置堆栈选项,我们不进行任何更改。您可以向下滚动到页面底部,然后点击橙色的下一步按钮。

  8. 现在,最终在审查页面,我们需要在页面底部勾选一个选项,确认我们的新堆栈将创建一个 Lambda 函数所需的 IAM 角色。在权限标题下,勾选确认此新模板正在创建 IAM 权限的复选框。完成后,您可以点击标有创建变更集的橙色按钮。

  9. 此时应该会弹出一个窗口,允许您在实际创建变更集之前为其命名。如果愿意,您可以为变更集命名,或者只需点击右下角的橙色创建变更集按钮。

  10. 一旦变更集创建完成,您应该会看到CREATE_PENDING状态,因为 CloudFormation 正在根据您使用变更集创建的新模板计算当前堆栈实际要更改的内容。完成后,橙色的执行按钮将出现在右上菜单中。向下滚动并查看变更标题下,查看将在堆栈上执行的两个更改。确认更改无误后,向上滚动并点击橙色的执行按钮:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_7.8_B17405.jpg

    图 7.8 – 变更集将在堆栈上执行的更改

  11. 现在,您将被带回到SQSqueue堆栈,并看到UPDATE_IN_PROGRESS状态,直到更新完成。

仅仅因为您创建了一个变更集并不意味着您必须执行它。您可以在变更集标签中有多个变更集,等待执行,直到您和您的团队决定应该实施哪些更改。值得注意的是,除非您删除变更集,否则任何拥有堆栈权限的人都可以执行它。

到目前为止,我们已经更新了原始堆栈,添加了 Lambda 函数以及该 Lambda 函数操作所需的 IAM 角色。我们的操作非常顺利,但如果模板中有冲突、缺失信息或错误会发生什么呢?接下来我们将讨论 CloudFormation 的回滚功能。

CloudFormation 的回滚功能

如果在创建或更新 CloudFormation 堆栈时操作失败,堆栈将回滚到之前的状态。此外,还有一个叫做 回滚触发器 的功能。通过这些触发器,你可以设置用户定义的警报,CloudWatch 可以监控这些警报,并在发生故障时回滚堆栈。

在创建堆栈或更新更改集时,监控周期可以设置为 0 到 180 分钟。接下来我们将看一个包含回滚触发器的更改集更新示例。

我们可以使用以下类似的 CLI 命令创建一个 CloudWatch 警报来监视我们的堆栈:

aws cloudwatch put-metric-alarm --alarm-name "SQS_stack_errors"  \
   --alarm-description "example alarm" --namespace "SQS_log_errors"  \
   --metric-name Errors --statistic Maximum --period 10 \
   --evaluation-periods 1 --threshold 0  \
   --treat-missing-data notBreaching  \
   --comparison-operator GreaterThanThreshold 

一旦我们创建了警报,就可以使用返回的 ARN 在回滚触发器中使用。如果需要查找 ARN,可以使用 CloudWatch 的 describe-alarms 命令:

aws cloudwatch describe-alarms --alarm-names "SQS_stack_errors"

我们需要创建一段 JSON 代码并将其推送到变量中,以便将 ARN 传递给命令行选项:

RB_TRIGGER=$(cat <<EOF
{
  "RollbackTriggers": [
    {
      "Arn": "arn:aws:cloudwatch:us-east-2:470066103307:alarm:SQS_stack_errors",
      "Type": "AWS::CloudWatch::Alarm"
    }
  ],
  "MonitoringTimeInMinutes": 5
}
EOF
)

这将为我们提供创建回滚触发器所需的信息:

aws cloudformation create-change-set \
    --change-set-name "SQS-UPDATE" \
    --stack-name "SQSqueue" \
    --template-url "https://devopspro-beyond.s3.us-east-2.amazonaws.com/sqs-queues_change_set.yml" \
    --change-set-type "UPDATE" \
    --parameters ParameterKey=QueueName,ParameterValue=chapter7 \
    --capabilities CAPABILITY_IAM \
    --rollback-configuration "$RB_TRIGGER" 

目前,回滚触发器仅支持使用 CloudWatch 警报作为监控工具。

我们将在 第十五章 中更详细地讨论 CloudWatch 警报,CloudWatch 指标和 Amazon EventBridge

CloudFormation 中的内置函数

CloudFormation 内置了多个函数,这些函数可以与 JSON 和 YAML 模板一起使用,扩展模板的功能和能力。我们可以堆叠或组合内置函数。

内置函数只能在 CloudFormation 模板的某些部分使用。根据本书出版时的情况,内置函数可以在资源属性、输出、元数据属性和更新策略属性中使用。

接下来我们将看一些常见的内置函数,并提供一些使用示例。YAML 模板中还可以使用其他函数。在函数标题中,如果有短格式,原始代码后面会用管道符号分隔并显示短格式:

  • Fn::FindInMap | !FindInMap

    FindInMap 函数根据 Mappings 部分中的键返回一个值:

    Mappings: 
    RegionMap: 
    us-east-1: 
          HVM64: "ami-032930428bf1abbff"
        us-east-2:
          HVM64: "ami-027cab9a7bf0155df"  
    us-west-1: 
          HVM64: "ami-088c153f74339f34c"
    eu-west-1: 
          HVM64: "ami-015232c01a82b847b"
    ap-southeast-1: 
          HVM64: "ami-0ba35dc9caf73d1c7"
    ap-northeast-1: 
          HVM64: "ami-0b2c2a754d5b4da22"
    Resources: 
    EC2Instance: 
        Type: "AWS::EC2::Instance"
    Properties: 
          ImageId: !FindInMap
            - RegionMap
            - !Ref 'AWS::Region'
            - HVM64
          InstanceType: t2.small
    
  • Fn::GetAZs | !GetAZs

    GetAZs 函数将返回给定区域中的可用区列表。这对于创建跨区域动态模板特别有帮助:

    PublicSubnet1:
        Type: AWS::EC2::Subnet
        Properties:
          AvailabilityZone:
    Fn::Select: 
            - 0
            - Fn::GetAZs: ""
    
  • Fn::GetAtt

    GetAtt 函数对于获取资源的属性(特别是 ARN)非常有用,尤其是在模板中之前已创建的资源。这个函数特别适用于使 CloudFormation 模板具有更高的动态性:

    SourceSecurityGroupName: !GetAtt EC2.SourceSecurityGroup.GroupName
    

条件函数

可选条件部分包含定义在基于动态选项的情况下,资源是否可以或不可以创建或配置的语句。

在 CloudFormation 模板中使用条件的场景包括以下内容:

  • 您正在尝试使用相同的模板为 DEV 和 PROD 环境提供支持,而不需要更改任何内容,除了可能的参数值。

  • 您希望通过下拉列表指定要挂载的 EBS 卷数量。

  • 您希望根据用户选择来创建或不创建 CloudWatch 仪表板。

    注意

    在堆栈更新过程中,您不能单独更新条件。您只能在包含添加、修改或删除资源的更改时更新条件。

您可以使用条件函数帮助评估诸如 AWS 提供的变量或从参数收集的输入项,并在某些条件适用时创建额外的资源:

  • Fn::And

    如果所有传入的指定条件返回true,则此函数返回true

  • Fn::Equals

    此函数比较两个不同的值,并在值相等时返回true

    在以下示例中,模板将根据在模板的 Parameters 部分传递的值,决定是否创建 Public Subnets

    Conditions:
      PublicSubnetsCondition:
          Fn::Equals: [ !Ref CreatePublicSubnets, "true" ]
      NoPublicSubnetsCondition:
          Fn::Equals: [ !Ref CreatePublicSubnets, "false" ]
    
  • Fn::If

    如果指定的条件评估结果为true,则此函数返回一个值;如果指定的条件评估结果为false,则返回另一个值。

  • Fn::Not

    如果条件评估结果为false,则返回true,如果评估结果为true,则返回false

  • Fn::Or

    如果任何指定条件的评估结果为true,则返回true

CloudFormation 最佳实践

当您开始在 CloudFormation 模板中构建基础设施即代码(IaC)时,AWS 提供了一些最佳实践和建议。这些建议有助于您更有效地组织和规划资源创建,同时最大限度减少在模板初次运行时的故障排除时间。

不要在模板中嵌入敏感信息。

与其直接在 CloudFormation 模板中放置可能会泄露的机密信息,不如将机密存储在 AWS Secrets Manager 中。更好的做法是使用动态引用。动态引用允许您引用Systems Manager(SSM)参数存储或 AWS Secrets Manager 中的外部值。对于 SSM 参数存储,它支持ssm(明文值)和ssm-secure(加密值)。

因此,您可以像这样在 RDS 资源块中使用数据库用户名和密码,而不是使用基于模板的参数:

  MySQLInstance:
    Type: 'AWS::RDS::DBInstance'
    Properties:
      DBName: MyRDSInstance
      AllocatedStorage: '20'
      DBInstanceClass: db.t2.micro
      Engine: mysql
      MasterUsername: '{{resolve:secretsmanager:MyRDSSecret:SecretString:username}}'
      MasterUserPassword: '{{resolve:secretsmanager:MyRDSSecret:SecretString:password}}'  

使用 AWS 特定的参数类型

为了简化 AWS 特定参数输入,尤其是在请求可能需要在账户中查找的项目时,可以定义 AWS 特定类型的参数,而不是使用字符串表示参数类型。这些参数可能包括安全组 ID、VPC ID 或 Route53 托管区域 ID。一个很好的例子是AWS::EC2::KeyPair::KeyName,这将提供一个可用 EC2 密钥对的下拉菜单。

利用参数约束

如果你没有使用 AWS 特定的参数,而是使用字符串参数,则使用参数约束可以帮助在模板开始创建之前捕捉用户在输入参数时的错误,避免浪费时间进行回滚。参数约束的构造方式类似正则表达式,还可以为用户提供描述,帮助他们更好地理解需要输入的内容。

了解如何使用 AWS::CloudFormation::Init 将软件部署到 EC2 实例

当你从 CloudFormation 模板启动 EC2 实例时,可以使用cfn-init助手脚本和AWS::CloudFormation::Init资源来安装和配置运行在该实例上的软件。使用这些助手脚本不仅可以安装系统脚本,还可以通过操作系统包管理器(如aptyum)安装必要的系统包。

模块化你的模板

使你的模板模块化可以同时完成几件事。首先也是最重要的是使模板可重用。随着我们开始讨论嵌套模板,这变得尤为重要。第二点是让多个团队成员集中精力在他们具有更多专业知识的小模板上。

在尝试启动之前对模板进行 Lint 检查

就像任何其他形式的代码一样,CloudFormation 模板应该经过验证过程,确保模板没有格式问题,然后再尝试启动。AWS CLI 中有一个内置的模板检查器,你可以使用它来发现模板中可能存在的任何问题。

AWS CloudFormation Linter(cfn-lint)是一个开源工具,可以集成到大多数 IDE 中,也可以通过命令行、IDE 内部或集成到 CI/CD 管道中运行。该工具将验证 JSON 和 YAML 模板,并包括符合 CloudFormation 最佳实践的附加检查。

注意

尽管这些最佳实践通常不会出现在测试题目中,但它们对于日常使用 CloudFormation 并让你成为最优秀的 DevOps 专业人士来说更为重要。

创建具有依赖关系的嵌套堆栈

当你开始按逻辑组织你的模板时,你会发现将更大的模板拆分成更小、更易管理的部分是一种明智的策略。这不仅会使它们更容易使用,还能通过使每个模板具备特定目的来提高重用性,例如创建一个带有子网的 VPC 或一组可重用的 IAM 角色。为这些较小的模板添加输出可以使其他模板使用其他模板之前创建的资源,就像一个个堆叠在一起的积木,最终构建出一个完整的解决方案。这也使得多个团队成员可以在云基础设施的不同部分独立工作,因为每个人可以集中精力在自己擅长的领域。如果你有一位擅长网络的团队成员,他们可以专注于堆栈中的 VPC 和网络部分。如果你有另一位具有数据库背景的团队成员,他们可以专注于创建和配置数据库(包括特定数据库引擎的任何特殊参数组)的嵌套部分。

嵌套堆栈始于根堆栈或父堆栈,如图 7.9中所示,标有字母A。根堆栈接着将其他子堆栈作为其资源,而不是其他 AWS 服务。我们还可以在图中看到,标有B的堆栈提供的输出被C级堆栈消费。C级堆栈创建了另一个子堆栈,并创建了资源,其输出被D级堆栈消费:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_7.9_B17405.jpg

图 7.9 – CloudFormation 嵌套堆栈

嵌套堆栈还提供了一个额外的好处,即能够突破 CloudFormation 模板的 200 个资源限制。

注意

嵌套堆栈在故障排除时可能更加复杂。如果在创建和部署嵌套 CloudFormation 堆栈时遇到错误,可以尝试只部署单个导致问题的模板,然后更新你的更改。

为部署打包你的嵌套堆栈

一旦你准备好所有要上传到 S3 的模板,你可以使用 AWS CLI 将它们打包在一起。由于嵌套堆栈需要其子模板在 S3 中以供部署,这样可以节省你单独上传每个模板的时间。然后,它将为我们生成一个新模板,并为我们提供使用该新模板部署完整嵌套堆栈的命令。创建 CloudFormation 包的通用代码如下所示:

$aws cloudformation package \
 --template-file /path_to_template/template.json \
 --s3-bucket bucket-name \
 --output-template-file packaged-template.json

当我们通过 AWS CLI 创建嵌套模板的练习时,我们将更深入地查看此命令。

让我们回顾一下package命令的作用:

  • 它创建一个 ZIP 文件,包含所有子模板文件和额外代码,例如lambda代码。

  • 它将这些项目上传到你指定的 S3 桶中。

  • 它生成一个新的模板,将本地模板替换为 S3 URI。

使用 AWS CLI 创建嵌套堆栈

在下面的练习中,我们将使用 GitHub 存储库中Chapter-7/nested目录下的一组模板创建嵌套堆栈。在开始以下练习之前,请下载所有这些 YAML 模板。还要记下要部署包的 S3 存储桶。正如我们之前在展示示例命令时所指出的,CLI 命令的一部分需要 S3 存储桶:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_7.10_B17405.jpg

图 7.10 – 创建嵌套堆栈练习中的项目

图 7.10 中的图示显示了我们即将使用嵌套模板打包和部署的内容:

  1. 打开终端,以便您可以访问 AWS CLI。

  2. 现在导航到您已下载所有文件以创建嵌套堆栈的文件夹。如果您已经下载了整本书的 GitHub 存储库,则路径将为Chapter-7/nested

  3. 由于嵌套堆栈的打包只能工作一层深,我们必须手动上传我们的nested_dynamo.yml模板(确保在执行以下命令时替换自己的存储桶名称):

    aws s3 cp nested_dynamo.yml s3://devopspro-beyond/
    
  4. 打开nested_root.yml文件,并编辑您放置nested_dynamo.yml文件的存储桶的 HTTPS 值的默认值。

  5. 进入嵌套目录后,执行以下命令:

    aws cloudformation package \
      --template-file nested_root.yml \
      --s3-bucket devopspro-beyond \
      --output-template-file packaged_template.yml
    
  6. 完成后,package命令应告诉您成功,并提供一个剪切和粘贴命令供您运行,需要在命令的最后替换堆栈名称:

    成功打包工件并将输出模板写入文件packaged_template.yml

    执行以下命令以部署打包的模板:

    aws cloudformation deploy --template-file /AWS-Certified-DevOps-Engineer-Professional-Certification-and-Beyond/Chapter-7/nested/packaged_template.yml --stack-name <YOUR STACK NAME>
    
  7. 运行以下命令以创建您的嵌套堆栈,但请确保更改堆栈名称并添加--capability CAPABILITY_IAM标志:

    aws cloudformation deploy --template-file /AWS-Certified-DevOps-Engineer-Professional-Certification-and-Beyond/Chapter-7/nested/packaged_template.yml --stack-name Chapt7 --capabilities CAPABILITY_IAM
    
  8. 登录 AWS 控制台并转到 CloudFormation 服务。此时,您应该能够看到您创建的根堆栈和嵌套堆栈。通过单击资源选项卡,您可以看到刚刚创建的所有资源。

  9. 如果不想产生费用,则删除堆栈。

使用 DependsOn 来排序资源

虽然 CloudFormation 按照模板中指定的顺序创建资源,但在开始构建下一个资源之前,并不等待任何一个资源的完成,除非有特别的指示。DependsOn结构允许您暂停特定资源的创建,直到其他资源完成。

存在许多情况需要调用DependsOn。第一组场景涉及需要访问互联网的资源,因此在继续之前需要完成互联网网关。

将等待条件添加到模板中

WaitCondition 会在模板执行堆栈任务时添加一个暂停,直到接收到成功信号,表示可以继续进行。

每当将 WaitCondition 作为资源添加到 CloudFormation 模板中时,必须将其与 WaitConditionHandle 资源结合使用。

注意

尽管 DependsOn 构造和 WaitCondition 资源在功能上似乎相似,但它们在几个方面有所不同。首先,DependsOn 是一个更简单的实现,因为它不需要辅助脚本。DependsOn 还不会在资源创建后检查其是否成功或失败,因此仅仅控制模板中项目的顺序。而 WaitCondition 则需要显式接收成功信号,模板(或变更集)会在收到该信号前暂停。

使用 curl 进行信号传递

当使用 curlWaitCondition 发出信号,表明资源(大多数情况下是 EC2 实例)已经完成配置时,这可以动态完成。第一步是创建 WaitHandle,然后构建 CloudFormationcurl 命令中使用的 URL。此时,我们可以在模板的 UserData 部分内调用 curl 命令。接下来,我们将看到一个简化模板片段中的示例:

ServerWaitCondition:
    Type: 'AWS::CloudFormation::WaitCondition'
    DependsOn: Server
    Properties:
      Handle: !Ref ServerWaitHandle
      Timeout: '1200'
…
      UserData: !Base64 
        'Fn::Join':
          -"
          - - |
              #!/bin/bash -v
            - |
              # Send Wait Condition URL 
            - '/usr/local/bin/aws s3 cp s3://'
            - !Ref BucketFolder
            - |
              /templates/success.json /tmp/a 
            - SignalURL=
            - !Ref ServerWaitHandle
            - |+
            - |
              echo $SignalURL 
            - curl -T /tmp/a "
            - !Ref AdminServerWaitHandle
            - |
              "

WaitCondition 是与 CloudFormation 中提供的少数几个辅助脚本之一一起使用的信号。接下来,我们将查看 CloudFormation 模板中可用的不同辅助脚本。

将辅助脚本添加到 CloudFormation 模板

在 CloudFormation 中,有一些不同的辅助脚本,它们是用 Python 编写的,可以在请求和配置 EC2 实例作为模板的一部分时安装软件并启动服务:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/013.jpg

表 7.1 – CloudFormation 助手脚本

如你所见,使用 CloudFormation 提供的这些辅助脚本可以大大简化 EC2 配置。接下来,我们将看到如何在 CloudFormation 模板中检测漂移,如果你的基础设施与模板代码发生偏离。

了解如何检测 CloudFormation 模板中的漂移

CloudFormation 模板允许你以代码的形式在你管理的多个 AWS 账户中创建和管理基础设施与资源。采用这种将资源作为代码进行配置的方式,能够进行版本控制,且是最佳实践,因为它是可重复的,而不是像传统方式那样手动构建和维护云资源。

你能阻止他人更改你以这种方式配置的资源吗?除非你使用了 IAM 策略来防止小组修改通过 CloudFormation 模板或代码部署管道提交的资源,否则有可能会出现由 CloudFormation 模板创建的某些资源发生漂移的情况。

当您启动漂移检测时,CloudFormation 服务会将当前堆栈和当前配置的资源与当初用于创建或更新该堆栈的模板中指定的内容进行比较。然后,它会报告所发现的任何差异。

在我们对 CloudFormation 模板有了深入了解之后,现在我们将讨论一个补充服务——AWS 服务目录。服务目录是 AWS 管理工具箱中的另一个工具,它允许您的用户快速、轻松地配置已预先创建并设置了相关保护措施的资源。

使用服务目录管理模板

在继续讨论 CloudFormation 模板的过程中,我们开始研究在组织中管理模板的其他方法。AWS 的服务目录产品允许我们使用 CloudFormation 模板,并为用户创建一个自服务门户,以便他们可以在获得适当访问权限的情况下配置已知的项目模式。这些模板现在成为我们服务目录中的产品,甚至可以进行参数化,这样用户就可以选择项目,例如在 EC2 的情况下,经过验证的、预定义的 EC2 实例大小和 AMI。

首先,您需要理解与服务目录相关的一些概念。第一个概念是产品。产品是您希望在 AWS 上提供的 IT 服务。它可以是一个简单的 S3 存储桶,也可以是一个复杂的 EC2 实例,配备 RDS 数据库和预定义的 CloudWatch 警报。接下来,您需要理解服务目录中的另一个概念——产品组合。产品组合是特定产品及其配置信息的集合。产品组合还与特定的用户组关联,并赋予这些用户组启动产品的权限。

查看 图 7.11,我们可以看到从管理员和用户的角度出发,服务目录中提供的两种不同工作流。顶部视图展示了管理员如何加载一个包含 EMR 集群、S3 存储桶和 CloudWatch 警报的模板,作为数据用户组的产品供重复使用。

数据用户组中的任何用户都可以迅速配置不仅是 EMR 集群,还可以配置相应的 S3 存储桶及相关的 S3 警报,只需在服务目录界面中输入几项相关信息:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_7.11_B17405.jpg

图 7.11 – 服务目录工作流

服务目录还允许您更新包含产品的模板,并发布带有更新功能的新版。这可以让您的用户选择使用哪个版本:他们熟悉的版本,或是包含新功能的版本。

在许多情况下,这种方法可能会变得非常有用:

  • 当解决方案架构师需要快速配置一个演示环境以供客户销售电话使用时。

  • QA 团队希望搭建一个用于测试的 QA 环境。

  • 在营销部门,他们希望一个促销应用程序在特定的时间段内运行。

  • 一位数据科学家需要一套专门的软件进行配置,比如 EMR 集群或配置有 R Studio 的服务器,但他没有系统管理员的背景,无法安装、配置和正确地确保所有必要的软件安全。

服务目录中的访问控制通过 IAM 进行处理。服务目录管理员为目录中的产品创建特定的 IAM 角色,以便用户仅拥有运行目录中预配置服务所需的足够权限。

在您的服务目录中,您可以对产品设置多种不同类型的约束,以便应用治理。

有基于模板的约束,可以减少用户在启动产品时可用的选项数量。例如,EC2 实例或 RDS 实例的大小,或者允许用于 Lambda 产品的语言。

基于标签的约束要么强制要求在启动产品时填写特定标签,要么禁止用户使用任何除预定义标签外的附加标签。

您可以指定一个特定的 SNS 主题,通过通知约束接收有关产品的更新。

定义哪些 IAM 角色可以用于运行特定产品,并通过启动约束进行控制。这为服务目录管理员提供了一组额外的控制手段,指明哪些服务允许由服务目录产品进行治理。

我们刚刚发现,服务目录能够让非开发人员快速启动预定义的 AWS 基础设施模式供用户使用。这些用户无需担心如何配置底层资源,因为这一切都由底层的 CloudFormation 模板处理。

接下来,我们将探讨另一种创建 CloudFormation 模板的方法,它比仅使用 JSON 或 YAML 的 Cloud Development Kit 提供了更大的灵活性。

使用 Cloud Development Kit

开发人员习惯于创建可重用的库并使用循环等技术来处理重复任务。Cloud Development Kit (CDK) 允许具备编程背景的人使用多种语言(TypeScript、JavaScript、Python、Java 和 C#)创建 CloudFormation 模板,使用他们熟悉的技术,具体如以下几种:

  • 逻辑(if 语句、for 循环)

  • 面向对象的技术

  • 通过逻辑模块进行组织

这与 CloudFormation 模板形成对比,后者要求您、开发人员或 DevOps 人员以 JSON 或 YAML 格式编写模板,尽管这两种选项在本质上都有一定的普遍性,并且无论是否有编程背景,都可以在短时间内掌握。CloudFormation 模板在创建堆栈时,提供的编程选项和逻辑也非常有限:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_7.12_B17405.jpg

图 7.12 – CDK 工作流程

图 7.12中,你可以看到开发人员如何使用 CDK 创建应用程序的工作流程。这个应用程序随后创建一个堆栈,将 CloudFormation 模板部署到 AWS 云环境中。

AWS CDK 的概念

在 AWS CDK 中,有三个基本组件——应用程序(apps)、堆栈(stacks)和构造体(constructs)——开发人员可以利用这些组件来创建云服务。

应用程序(Apps)

使用 AWS CDK 时,你是在构建一个应用程序,该应用程序本身就是一个应用,并由 CDK App 类组成。

堆栈(Stacks)

在 AWS CDK 中,部署单元是堆栈,堆栈范围内定义的所有资源都作为一个单一单元进行提供。由于 CDK 堆栈是作为 CloudFormation 堆栈实现的,因此 CloudFormation 堆栈需要遵守的任何边界或限制同样适用于 CDK 堆栈。

构造体(Constructs)

AWS CDK 的构建模块是构造体。这些构造体可以是像负载均衡器这样的单个 AWS 资源,或者是由多个资源组成的单一组件,例如 VPC 和子网。构造体创建可重用的组件,可以像其他代码片段一样共享。

使用 AWS CDK 的优点

我们将探讨使用 CDK 相较于普通 CloudFormation 模板的一些优势。

更快的开发过程

使用 AWS CDK,你可以使用你熟悉的编程语言,如 Python、TypeScript、.NET、Go 和 Java。在这些语言的帮助下,你可以创建对象、循环和条件,而无需学习特定领域的函数和解决方法。

在 IDE 中进行代码补全

使用流行的 IDE(如 Visual Studio Code)可以在编程时根据你选择的语言实现代码补全功能,尤其是在使用 AWS CDK 时。

同步部署代码和基础设施即代码(IaC)的能力

由于 AWS CDK 使用的是与编写代码时相同的原生语言,因此将基础设施组件与运行应用程序的代码结合起来变得更加简单,无需切换上下文。

总结

在本章中,我们探讨了如何使用 CloudFormation 模板和 CDK 创建基础设施即代码(IaC)。我们研究了模板构建和组织的一些最佳实践,并通过 AWS 管理控制台和命令行界面(CLI)亲手实现了将 CloudFormation 模板部署和更新为堆栈。

在下一章中,我们将开始研究一些属于 SDLC 过程的 AWS 代码工具,从 CodeCommit 和 CodeBuild 开始。我们将使用 CodeCommit 创建一个代码库并提交,然后使用 AWS CodeBuild 构建代码。最后,我们将看到如何通过从 CodeCommit 仓库的推送触发 CodeBuild 作业来将这两项服务结合在一起。

复习问题

  1. CloudFormation 的两个主要组件是什么?

  2. 一家公司雇佣你帮助审查和优化其 CI/CD 流程,特别是在基础设施即代码(IaC)方面。该公司目前有一个 CloudFormation 模板,经过一段时间的开发,用于创建 IAM 账户角色、VPC、子网、Lambda 函数、CloudWatch 警报、SNS 主题及其他资源,包括数据库和 EKS EC2 实例及其相应的 AutoScaling 组。你会如何着手为他们的流程优化提出建议?

    a. 检查当前模板,确保其嵌入了正确的 DependsOnWaitCondition,以便所有资源可以顺利启动,不会发生冲突。

    b. 创建一个计划,说明如何拆分他们的大模板。

    c. 使用 CloudFormation 的 package 命令将所有模板打包在一起。

    d. 将较小的模板打包并通过一个 deploy 命令进行部署。

  3. 在评估客户的需求后,你决定构建一个 CloudFormation 模板,作为交付成果交给客户,该模板适用于可重复使用的三层 Web 应用程序。中间件 Linux 服务器有一个复杂的用户数据脚本,需要一段时间才能完全安装。它们位于网络负载均衡器资源之后,在添加之前需要完全操作并配置好。你如何确保这些服务器在连接到网络负载均衡器资源之前已经完全操作并正确配置?(选择两个。)

    a. 确保网络负载均衡器资源位于模板中的中间件服务器后面,在 CloudFormation 资源部分中。

    b. 添加一个依赖于中间件服务器的 WaitCondition。一旦用户数据完成,它会使用 cfn-signal 通知表示已准备好。

    c. 从嵌套模板中启动所有内容,其中中间件服务器位于从负载均衡器模板启动的模板中。

    d. 添加一个依赖于中间件服务器的 WaitCondition。一旦用户数据完成配置中间件服务器,它会使用 curl 命令通知预签名的 URL,表示它们已经准备好。

  4. 你在一家大型企业公司工作,背后有多个待部署的项目,需要将它们部署到不同的 AWS 云环境中。为了最小化每次部署所需的时间,你希望创建一套可重用的组件集合,可以根据每个项目的架构轻松替换。当前已有一个基本的 CodePipeline 服务实例用于添加测试和部署步骤。无论你选择什么解决方案,都应该能够提交到代码版本控制系统,并且易于测试。你应该如何组织资源以实现最佳的可重用性?

    a. 使用 AWS CDK 创建由共享组件库组成的应用程序。添加测试库,并在 CodePipeline 中部署到开发环境之前运行测试。

    b. 创建一个小型资源特定的 CloudFormation 模板库,可以根据架构指南轻松嵌套和打包。使用yamllintcfn-lint命令对 CloudFormation 模板进行语法检查,作为 CodeBuild 中的测试步骤,以捕捉任何错误。

    c. 开发 5-10 个蓝图模式的基础,这些模式适用于所有项目。使用这些蓝图,开发一个包含参数和条件的 CloudFormation 模板库,以满足大多数项目的需求。使用cfn-lint命令对 CloudFormation 模板进行语法检查,作为 CodeBuild 中的测试步骤,以捕捉任何错误。

    d. 为每个解决方案创建 CloudFormation 模板,包含必要的参数值和条件,以确保它们能够在任何区域无缝工作,并可用于任何环境(DEV、TEST 和 PROD)。将模板上传到 CodeCommit 进行版本控制。

审查答案

  1. 模板和堆栈

  2. b

  3. b 和 d

  4. a

第八章:使用 CodeCommit 和 CodeBuild 创建工作负载

AWS 提供了一套值得称赞的工具,帮助开发人员和组织完全依赖 Amazon 生态系统来运行他们的 CI/CD 操作。

持续集成从源代码版本控制过程开始,然后以可重复、自动化的方式构建和测试代码。AWS 代码服务套件中的两个工具,CodeCommitCodeBuild,帮助工程师实现这些目标。

在本章中,我们将涵盖以下主要主题:

  • 使用 CodeCommit 进行代码版本控制

  • 设置你的 CodeCommit 仓库

  • CodeCommit 中的审批

  • 使用 AWS CodeBuild

  • 创建 buildspec 文件

技术要求

当我们开始这条路时,假设有几个前提,尤其是在追求专业 DevOps 认证时。第一个前提是你对使用软件版本控制系统 Git 有基本的了解。这个基本知识包括创建一个裸仓库、创建一个分支、对该分支进行提交,然后将提交推送到远程仓库。如果你需要熟悉 Git,建议使用教程 《Git 和 AWS CodeCommit 入门》。你可以在 docs.aws.amazon.com/codecommit/latest/userguide/getting-started.html 找到该教程。

第二个假设是你已经在笔记本电脑或工作站上安装了 Git。假设你还没有安装 Git,或者由于缺乏管理员权限而无法访问它,完美的替代方案是启动一个 Amazon EC2 实例,在你的 AWS 账户中安装 Git,这样你就可以跟随练习进行操作。

如果 Git 没有安装在你的本地工作站上,并且你无法安装它或不想安装它,AWS 提供了 Cloud9 开发环境,它允许你在浏览器窗口中创建代码。

使用 CodeCommit 进行代码版本控制

关于存储代码的地方,无论是在本地还是在 SaaS 解决方案中,你有很多选择。功能和价值是驱动决策的因素,决定使用哪种产品。AWS CodeCommit 提供了强大的功能集,并且是按使用付费的服务,包含与 AWS 服务的原生连接,以及符合多个保证计划,如 SOC2、PCI、HIPAA 等。

第六章了解 CI/CD 和软件开发生命周期 (SDLC) 中,我们讨论了软件开发生命周期的四个主要阶段:源代码、构建、测试和部署。初始阶段,即源代码阶段,是我们将在本节中集中讨论的内容。简要回顾一下,源代码阶段允许你将代码检查到中央仓库,并且允许多人在同一代码库上进行协作。

什么是 CodeCommit?

CodeCommit 是一个安全、高度可扩展的托管源代码控制服务,承载私有 Git 仓库。这听起来可能有些陌生,但如果你使用过 BitBucket 或 GitHub 私有仓库,你可能已经使用过类似的 SaaS 服务来托管代码。

CodeCommit 中的基本对象是仓库。仓库是用户存储代码和任何类型、大小对象的地方。CodeCommit 还存储和跟踪对上传文件所做的更改,以及对文件所做的更改。你可以配置仓库,以便在发生事件时发送通知,例如分支合并或向代码中添加评论。它还允许用户在本地系统上工作,然后将更改推送到 CodeCommit 存储系统。

CodeCommit 的好处

作为 AWS 生态系统的一部分,CodeCommit 可以与 KMS 等服务集成以实现加密,还可以与 CloudWatch 集成,以便为我们的仓库整合指标和警报,甚至不包括与 CodeCommit 服务紧密集成的某些开发工具。除了与众多其他 AWS 服务紧密耦合外,CodeCommit 还提供许多其他好处:

  • CodeCommit 的 IAM 提供高服务可用性和耐久性。

  • CodeCommit 仓库在静态和传输过程中都进行了加密,因此你可以放心,代码始终是安全的。

  • 它可以轻松扩展,并且对仓库的大小、以及你可以存储的文件类型和大小没有限制。

  • 无缝集成多个 AWS 服务(Lambda、SNS、CodePipeline)。

  • 允许你轻松地从其他远程 Git 仓库迁移。

  • 允许你使用你已经熟悉的 Git 工具和命令。

在了解了 AWS CodeCommit 的概述和好处之后,我们将查看可用的访问控制功能,然后再创建我们的仓库和专门用于 CodeCommit 访问的新用户组。

控制对仓库的访问

在我们开始创建 CodeCommit 仓库的过程之前,我们需要做一些权限方面的预先工作。直到这一点为止,我们大部分操作都是以管理员用户身份进行的。现在我们开始将开发人员和开发团队加入其中,其中一些只需要访问 CodeCommit 仓库而不需要访问其他服务。我们将创建一个新的 IAM 用户组,然后将一个开发者实体添加到该用户组。这将演示良好的 GitFlow 实践,即开发者提交代码后,请求将其分支合并到主分支。

当所有开发者都属于同一个账户时,可以顺利创建 CodeCommit 仓库。然而,还有其他一些场景需要注意。例如,当另一个账户中的开发者需要访问我们账户中的 CodeCommit 仓库时该怎么办?CodeCommit 可以为另一个 AWS 账户中的用户和角色提供跨账户访问。这可以解决不必将外部开发者添加到 IAM 用户列表中的问题,前提是他们已经拥有 AWS 账户。

设置你的 CodeCommit 仓库

可以通过 CLI 创建 CodeCommit 仓库。然而,当使用 AWS 管理控制台时,有一些附加功能,如信息面板,这些功能只有在该环境中才可用。

在创建仓库之前,确保打开浏览器访问 AWS CodeCommit 主页,console.aws.amazon.com/codesuite/codecommit/home,并在提示时登录。

一旦你登录,我们可以开始创建 CodeCommit 仓库的过程:

  1. 一旦你进入了你所在地区的CodeCommit主页(在我们的示例中,我们使用的是俄亥俄地区/us-east-2),点击右上角的橙色创建仓库按钮,开始创建新仓库的过程:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.1_B17405.jpg

    图 8.1 – 创建仓库按钮

  2. chapter8中设置仓库名称。如果你愿意,可以为仓库添加描述,但这不是必要的。你可能希望此时启用 CodeGuru 审阅器;然而,由于这是一个新功能,我们将不进行讨论:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.2_B17405.jpg

    图 8.2 – 新的 CodeCommit 仓库设置

    注意

    Amazon CodeGuru 审阅器是一个可选功能,是 AWS 的附加服务,在发布时仅支持 Java 和 Python 语言。未来可能会支持更多语言。

  3. 创建仓库后,你将看到一个显示连接步骤的页面,这些步骤展示了如何通过多种方式连接到你的新仓库,包括 HTTPS、SSH 和通过 HTTPS 的 git-remote-connect 协议。花一点时间浏览这些步骤。我们将在开发者账户创建完成,并且使用其权限集时,更加深入地使用这一部分。向下滚动,越过连接步骤,页面底部会看到一个名为创建文件的按钮。点击该按钮以便设置我们的主分支:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.3_B17405.jpg

    图 8.3 – 为我们的 CodeCommit 仓库创建初始文件

  4. Welcome to my repository。完成此操作后,在 sample.txt 中,你还需要为提交输入一个名称和一个电子邮件地址,如以下截图所示:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.4_B17405.jpg

    图 8.4 – 通过 Web 界面提交更改到 CodeCommit

  5. 输入这些信息后,你可以点击橙色的 Commit changes 按钮。接下来,你将被带到仓库中的文件,但更重要的是要注意,在屏幕的右上角,我们已经成功创建了 main 分支:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.5_B17405.jpg

图 8.5 – 我们的 CodeCommit 仓库的主分支

现在我们已经创建了仓库和主分支,我们可以开始创建开发人员用来将代码推送到仓库的权限集。根据你的组织结构,你可能会赋予所有开发人员创建新仓库和将拉取请求合并到主分支的权限。

在我们的示例场景中,当我们进行练习时,我们将区分开发人员可以做的事情与管理员或 DevOps 高级用户的职责。准备考试时,考虑如何划分责任是非常重要的,此外,还有一些可能出现的问题和场景需要注意。

为开发人员创建 IAM 组

在我们开始之前,请确保从本书的 GitHub 仓库下载文件,路径是 Chapter-8 文件夹。我们将首先为开发人员创建 IAM 策略。一旦策略上传完毕,我们将创建开发人员组,并将策略附加到新创建的组上:

  1. 打开终端,以便可以访问你的 AWS CLI。

  2. 我们想为我们的代码提交开发人员创建一个组。你可能以前创建过一个开发人员组,但我们现在要为本章创建一个新的组:

    aws iam create-group --group-name CC_Developers
    
  3. 现在你已经创建了组,我们将把策略附加到该组。我们需要从之前创建的 CC_Developers 策略中获取策略 ARN:

    aws iam attach-group-policy 
      --policy-arn arn:aws:iam::aws:policy/AWSCodeCommitPowerUser –group-name CC_developers
    
  4. 既然我们已经创建了 CC_Developers 组,我们可以创建我们的开发人员,并允许他们登录并添加他们的 SSH 密钥以开始使用 CodeCommit

创建你的开发人员

在本节中,我们将创建一个虚拟的开发人员,名为 Mariel。如果你愿意,你可以将开发人员的名称从 Mariel 改为其他名字。如果你还没有下载,先下载 change-password.json 文件并按照以下步骤操作:

  1. 如果你的终端仍未打开,请重新打开它,以便可以在 AWS CLI 中执行命令。使用 iamcreate-user 命令:

    $aws iam create-user --user-name mariel
    
  2. 当这个命令运行完成后,它应该返回一个 JSON 语句,显示包括用户 ID 在内的其他信息,如以下示例所示:

    {
        "User": {
            "Path": "/",
            "UserName": "mariel",
            "UserId": "AIDAW24Q7QQFVGQHQJM3Y",
            "Arn": "arn:aws:iam::000066100007:user/mariel",
            "CreateDate": "2021-05-02T11:06:47+00:00"
        }
    }
    
  3. 我们创建的用户,可以将其添加到CC_Developers组,并允许他们继承该组的所有权限:

    $aws iam add-user-to-group --user-name mariel --group-name CC_Developers
    
  4. 现在我们已经创建了用户并将其添加到CC_Developers组中,我们需要为该用户创建一个初始密码,以便他们可以登录到管理控制台并上传他们的SSH密钥。要求他们重置密码也是一个好主意:

    aws iam create-login-profile --user-name mariel --password Dev0psPRO123! --password-reset-required
    

这样,我们就为用户创建了一个初始密码,以便他们能够在控制台中配置SSH密钥设置,并通过控制台查看 CodeCommit 分支。

现在我们已经使用 AWS CLI 创建了开发者用户,我们可以切换上下文并继续假设为开发者角色。

添加开发者的 SSH 密钥

现在我们已经创建了开发者用户,我们将从 CLI 切换到工作环境中的SSH密钥对,以便在创建代码时用于身份验证。

小贴士

当为账户、客户或特定用途使用特定的仓库或仓库集时,最好为该项目、账户或客户创建一个专用的密钥。使用不同的密钥是整体风险管理策略的一部分,以防服务器、SaaS 服务或工作站出现任何问题。

我们首先创建一个专门供开发者使用的SSH密钥对,以便能够将其添加到 AWS IAM 控制台中。

在终端中,使用以下命令为 Linux 或 macOS 用户生成一个新的密钥对文件:

$ ssh-keygen -t rsa -b 4096

运行此命令时,会首先要求你回答一些提示问题,第一个问题是你希望将密钥保存在哪里。默认情况下应该保存在本地的.ssh文件夹中,但名称为id_rsa。我们将使用一个自定义的密钥名称,以便我们知道这是专门为我们的代码提交项目准备的:

Enter file in which to save the key (/Users/abook/.ssh/id_rsa): /Users/abook/.ssh/cc_developer

选择保存密钥的位置和名称后,你将看到一个提示,要求输入passphrase

Enter passphrase (empty for no passphrase):

我们不需要设置密码,因此只需按Enter键两次以保持空白。此时,你应该会看到一些信息,说明你的身份和公钥已保存,并显示类似 ASCII 艺术的内容。

你需要使用cat命令查看你的公钥,并在登录 AWS 控制台时准备好它,作为开发者用户进行登录。

生成密钥后

现在我们已经生成了密钥,需要使用我们刚创建的开发者用户名和凭证登录 AWS 控制台(而不是我们一直在使用的具有管理员权限的 DevOps 用户)。

小贴士

你可能需要使用不同的浏览器,或者开启隐身/私密会话,以确保没有遗留的 Cookies。

在新的浏览器中,登录为我们刚刚创建的开发者用户:

  1. 现在我们将使用开发者账户,而不是管理员账户。请登录到 aws.amazon.com/,并使用开发者的名字(mariel,在我们的例子中)和密码(Dev0psPRO)首次登录 AWS 管理控制台。

  2. 登录后,系统会立即提示您将初始密码更改为您选择的密码。如果您之前在 IAM 账户 设置中设置了密码策略,则必须在更改密码时遵守这些指南:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.6_B17405.jpg

    图 8.6 – 开发者用户强制密码更改

  3. 一旦您更改了密码,您将进入 AWS 管理控制台的主页。现在,我们需要在搜索框中输入 IAM,以进入 IAM 服务

  4. 一旦您进入了 IAM 服务,您会发现似乎没有权限进行任何操作。然而,这只是因为开发者角色的权限范围有限。这个用户可以列出用户并更新他们的用户信息。在左侧菜单中点击 用户 菜单项。

  5. 进入用户菜单后,您将看到一列用户。点击我们创建的开发者的名字(在我们的例子中是 mariel):https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.7_B17405.jpg

    图 8.7 – IAM 用户列表

  6. 在用户的 概览 页面上,您会看到一些红框,但这里我们感兴趣的是 安全凭证 标签。点击此标签,您可以开始修改 安全凭证 页面:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.8_B17405.jpg

    图 8.8 – IAM 用户概览顶部菜单

  7. 向下滚动,确保 SSH 公钥 不仅已准备好,而且已经复制到剪贴板,随时可以粘贴。点击 SSH 公钥 按钮继续。

  8. 当弹出窗口出现时,将您的公钥粘贴到文本框中,然后点击蓝色的SSH``SSH 密钥 ID 列表。请注意这一点,因为我们接下来会用到这个 ID 来进行本地设置:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.9_B17405.jpg

    图 8.9 – 一旦上传了 SSH 公钥,IAM 控制台将显示 SSH 密钥 ID

  9. 返回到您的工作站,我们需要创建一个 .ssh/config 文件,或者通过添加几行与代码提交相关的内容来修改现有的 config 文件。使用您喜欢的编辑器创建或打开 ~/.ssh/config,然后添加以下几行。确保将示例的用户 ID 替换为您在上传密钥后 AWS 控制台返回的 ID。另外,如果您为 SSH 密钥创建了不同的名称,您需要在 IdentityFile 行中替换成该名称:

    Host git-codecommit.*.amazonaws.com
    User APKAW24Q7QQFSRFEETDF
    IdentityFile ~/.ssh/cc_developer
    
  10. 返回到浏览器和 AWS 管理控制台,我们现在将切换到 CodeCommit 服务,以便获取仓库信息并克隆该仓库。在顶部的搜索框中输入 CodeCommit,然后点击图标进入 CodeCommit 服务页面。https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.10_B17405.jpg

    图 8.10 – AWS 管理控制台搜索栏中的 CodeCommit 图标

  11. 一旦在右侧的 SSH 链接上复制了 克隆 URL 属性:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.11_B17405.jpg

    图 8.11 - CodeCommit 仓库在开发者用户端的显示方式

  12. 切换回终端,进入你的主文件夹根目录。然后,将复制的 URL 粘贴到 git clone 命令后,如下所示:

    $cd ~
    $git clone ssh://git-codecommit.us-east-2.amazonaws.com/v1/repos/chapter8
    
  13. 最后,进入 chapter8 目录。现在,你准备好开始添加一些代码或对象了。

此时,我们已经创建了一个SSH密钥并将其添加到我们的开发用户中。然后,我们更新了本地的SSH配置,告知 CodeCommit 在处理代码提交时使用哪个用户和密钥对。最后,我们下载了管理员用户之前创建的仓库。现在我们准备创建开发者分支并开始提交一些更改。

创建开发者分支并将提交推送到该分支

现在我们已经成功将仓库克隆到本地工作站,接下来是创建一个分支并提交。所有这些操作将在你克隆仓库所在的目录中进行。如果你遵循了前面的命名约定,那么你应该进入你的主目录,并找到 chapter8 文件夹。

我们做的第一件事是从主分支创建一个特性分支:

$git checkout -b feature1
Switched to a new branch feature 1

现在我们已经在自己的分支中,可以开始添加一些文件来进行提交。GitHub 仓库的 Chapter-8 文件夹中有两个示例文件(hello.pyloops.py)。你可以查看这些文件,然后将原始内容剪切并粘贴到我们下载的 chapter8 CodeCommit 仓库中新创建的同名文件中。

在我们进行提交之前,我们应该检查目录中文件的状态:

$git status

使用status命令后,我们应该看到类似以下的输出:

On branch feature1
No commits yet
Untracked files:
  (use "git add <file>..." to include in what will be committed)
 hello.py
 loops.py
nothing added to commit but untracked files present (use "git add" to track)

现在,我们需要将这两个文件添加到提交中。由于它们都是相同类型的文件,我们可以在提交命令中使用通配符。或者,你也可以使用纯粹的通配符,一次性将所有未跟踪的文件添加到提交中:

$git add *.py 

此时,我们需要将文件提交到我们的特性分支:

$git commit -m "adding python files for feature 1"

最后,将这两个文件提交到特性分支后,就可以将该特性分支推送到 CodeCommit:

$git push origin feature1

成功推送新特性分支后,你应该会从命令行收到确认信息:

* [new branch]      feature1 -> feature1

现在我们已经将提交推送到我们的功能分支,并上传到了 CodeCommit 仓库,接下来是发起合并请求。这个合并请求将允许我们的代码成为主分支的一部分,供其他所有使用相同代码仓库的开发者使用,同时保持与主分支同步。

我们将作为开发者用户返回到 AWS 控制台以创建拉取请求。如果你仍然打开着开发者的单独会话,可以切换回该浏览器会话;否则,请登录aws.amazon.com/,然后使用开发者的用户名(在我们的例子中是mariel)和你为开发者用户更改的新密码:

  1. 在顶部的搜索框中,输入CodeCommit,然后点击CodeCommit图标,进入服务页面。

  2. 你应该能看到你的仓库,如图 8.7所示。点击仓库名称(chapter8)。

  3. 在顶部菜单中,你会看到一个下拉框,当前显示为main。点击该下拉框,选择你的分支(feature1)。完成后,你上传的两个文件将会显示出来。

  4. 现在你在顶部菜单中看到了你的分支名称,应该会看到一个名为创建拉取请求的按钮。点击这个按钮开始合并请求:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.12_B17405.jpg

    图 8.12 – 创建拉取请求按钮与分支名称一起显示

  5. 应该会出现一个绿色框,显示我们目前没有分支与主分支之间的冲突。在创建合并请求之前,你需要在Python 文件中添加一些内容。填写标题后,点击屏幕底部的橙色创建拉取请求按钮:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.13_B17405.jpg

    图 8.13 – 显示没有冲突的拉取请求

  6. 一旦你创建了拉取请求,系统将带你进入一个页面,在那里你可以查看当前打开的拉取请求的详细信息。

现在我们已经进入了拉取请求页面,这就是开发者用户停止的地方。我们分配的 IAM 策略不会允许他们合并分支,这是有意设计的。

接下来,使用我们的管理员身份,我们将学习如何将请求合并到主分支中。

CodeCommit 中的审批

随着开发者更新代码并将这些更新推送到 CodeCommit 仓库,尤其是当他们使用自己的功能分支时,需要有一个过程将他们的更改合并到主分支中。让我们一起看看如何将开发者在分支上创建的代码合并到主分支。

将开发者分支与主分支合并

此时,我们还没有为仓库启用任何通知,但在实际情况下,这是一个很好的方法,用来添加通知,当有人创建拉取请求时。我们的开发者已经在仓库中创建了一个分支,现在可以进行合并。作为具有合并权限的帐户用户,我们将登录并合并功能分支和主分支:

  1. 打开你的控制台,并以你到目前为止使用的主管理员用户登录Amazon Web Console,而不是开发者用户。

  2. 在屏幕中间的顶部搜索栏中导航到 CodeCommit。一旦CodeCommit图标显示出来,点击它:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.14_B17405.jpg

    图 8.14 – 在服务的顶部搜索框中搜索 CodeCommit

  3. 一旦进入主 CodeCommit 屏幕,只要你处于正确的区域,你应该能看到我们之前由开发者用户创建的名为chapter8的仓库。点击此仓库名称,即可进入该仓库:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.15_B17405.jpg

    图 8.15 – CodeCommit 中的 chapter8 仓库

  4. 点击仓库名称后,屏幕左侧会出现一组菜单选项,位于Repositories下。这里,你会看到一个子标题叫做Pull requests,它会展示我们任何未完成的拉取请求,包括之前由开发者用户创建的那个。点击Pull requests菜单项,进入拉取请求屏幕:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.16_B17405.jpg

    图 8.16 – CodeCommit 仓库菜单中的拉取请求

  5. 我们的拉取请求名称应该是Python 文件,并以数字 1 为前缀。Python 文件是我们的开发者用户在最初创建拉取请求时使用的名称。我们还应该在拉取请求名称的右侧看到蓝色状态标记开放。点击拉取请求名称1:Python 文件,进入合并屏幕:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.17_B17405.jpg

    图 8.17 – 带状态的拉取请求

  6. 现在,在拉取请求屏幕上,屏幕顶部会显示1:Python 文件,在标题下方你应该能看到三个彩色标签:开放(蓝色),无审批规则(深灰色),以及无合并冲突(绿色)。后者表示我们可以轻松地将拉取请求合并到主分支。点击屏幕右上角的橙色合并按钮来完成此操作:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.18_B17405.jpg

    图 8.18 – 关于 CodeCommit 拉取请求的通知

  7. 目前,我们将进入合并拉取请求屏幕。这个屏幕主要是关于合并策略,但在这个练习中,我们将保持默认设置不变。包括保持底部勾选框,该框将删除被合并的分支,并使用快速前进合并策略。点击页面右下角的橙色合并拉取请求按钮,将功能分支合并到主分支。

  8. 最后,你应该会看到屏幕顶部有一个绿色的通知,告诉你你的feature1分支已经合并到主分支。

我们刚刚彻底了解了 CodeCommit 服务,并从多个团队成员的角度看了如何进行提交和合并。整理好源代码后,我们将来看一个可以生成软件包和测试软件的 AWS 服务:AWS CodeBuild。

使用 AWS CodeBuild

buildspec文件和任务启动时,CodeBuild 将分配指定的资源。

这与其他构建系统不同,在其他系统中,你需要手动为工作节点配置计算资源,或者执行复杂的设置,以确保在高负载构建和测试期间有自动扩展的环境可用。

你可以将 AWS CodeBuild 作为独立服务运行,或者将其与其他服务(如CodeCommitAWS CodePipeline)集成,创建一个可重复的、自动化的过程,成为你持续集成生命周期的一部分。

了解 CodeBuild 的功能

以下是你应该了解的一些 CodeBuild 的功能:

  • 它是一个完全托管的构建服务:无需设置、修补或更新任何服务器或软件。

  • 它可以根据需求进行扩展:CodeBuild 能够根据你的需求进行自动扩展和收缩。

  • 它由 AWS 提供安全保障:通过 KMS 支持的可选加密功能,以及通过 IAM 对特定任务的权限控制,你可以放心地确保你的构建环境的安全性。

  • 它是 AWS 开发者工具之一,能够与 CodeCommit、CodeDeploy 和 CodePipeline 紧密集成。

  • CodeBuild 与CloudWatch Events原生集成,以便触发失败的构建和项目,例如发送 SNS 消息。

  • 日志可以设置为输出到 S3 或CloudWatch 日志

  • 可以使用 CloudWatch 指标和警报来监控 CodeBuild 的阈值。

创建 CodeBuild 任务

CodeBuild 在执行任务时非常灵活。以我们的例子为例,我们将创建一个buildspec文件来创建一个 Docker 镜像,然后将该 Docker 镜像推送到 ECR:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.19_B17405.jpg

图 8.19 – 示例 CodeBuild 任务的布局

如果你还没有从本书的 GitHub 仓库下载Chapter-8文件,那么现在正是最佳时机,因为我们将在第一个 CodeBuild 练习中使用docker目录:

  1. 导航到您下载 Chapter-8 文件的目录。不要进入 docker 目录,因为我们将使用递归命令一次性上传所有文件:

    $ aws s3 cp docker s3://{yourS3bucket}/docker/ --recursive
    
  2. 首先,我们将创建我们的 ECR 仓库,以便容器在构建完成后有地方存放:

    $aws ecr create-repository \
        --repository-name chapter8
    
  3. 创建了 ECR 仓库后,我们将打开 AWS 控制台,完成 CodeBuild 项目的其余部分。确保使用管理员用户而不是开发者用户进行此操作。一旦 AWS 控制台打开,搜索框中输入 CodeBuild,然后点击图标以进入 CodeBuild 服务。

  4. 在 CodeBuild 服务中,点击右上角的橙色按钮,按钮上写着创建构建项目

  5. 为了创建我们的项目,我们将从初始部分开始:chapter8_docker

    b. chapter 8 的一个示例构建

    https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.20_B17405.jpg

    图 8.20 – CodeBuild 创建构建项目页面上的项目配置

  6. 接下来,我们将移动到 devopspro-beyond。最后,我们将提供请求的密钥,这是我们上传文件所在的文件夹。在我们的例子中,这将是 docker/。我们没有对存储桶进行版本控制,因此可以将此字段留空:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.21_B17405.jpg

    图 8.21 – CodeBuild 项目中的源声明

  7. 接下来,我们将进入

    b. aws/codebuild/standard:5.0

    e. 镜像版本始终使用此运行时版本的最新版本

    f. 环境类型Linux

    g. 服务角色新建服务角色

    注意

    对于 CodeBuild 项目中的镜像,我们在这里指定了版本 5.0。然而,您可能想查找 AWS 提供的最新版本。

  8. 在这一点上,您可以将其余选项保持不变,滚动到页面底部,然后点击橙色的创建构建项目按钮。

  9. 现在,您应该进入到构建项目的页面。顶部会看到一条绿色横幅,显示您的构建项目已创建:https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.22_B17405.jpg

    图 8.22 – 在 AWS CodeBuild 中创建的成功项目

  10. 现在,我们可以尝试运行我们的任务,看看结果如何。如果您想运行任务并开始构建,请点击屏幕右上角的橙色开始构建按钮。

这只是一个基础项目,并不需要是停止点。如果我们愿意,仍然可以编辑任务和 buildspec 文件,向任务添加增强功能。

通过控制台使用 S3 存储桶作为源创建项目后,我们将仔细查看实际运行 CodeBuild 任务的文件:buildspec 文件。

构建 buildspec 文件

buildspec 文件是驱动 CodeBuild 过程的文件,并且有一些严格的要求:

  • 它必须命名为 buildspec.yml,不能使用其他名称。

  • 它必须位于源代码文件夹的 root directory 中。

  • 它必须使用 YAML 语言。

如果你在完成前面的练习后打开 buildspec 文件进行检查,你会注意到它包含了三个主要部分:

  • Version:此字段告诉 CodeBuild 服务你正在使用的语法版本,它是少数几个必需的部分之一。

  • Install:此步骤仅用于在构建环境中安装软件包。如果你需要安装测试框架,例如 pytestMocha,可以在此步骤执行此操作。

    b. pre-build:这是在实际构建命令运行之前执行的命令。预构建命令可以包括登录到 Build:在此阶段,会运行一些构建命令、创建容器,或者执行测试软件的命令。

    d. post-build:一旦构建完成,这些是随后的命令,可以包括将软件打包成 .jar.war 文件,或创建 Python 的 egg 文件。它甚至可能涉及将容器上传到 ECR 或 DockerHub 等仓库。

  • Artifacts:这是构建输出。这可以包括文件的名称、文件本身,或两者兼有。工件阶段还允许你保留文件创建时的目录结构,或者将其去除,仅保留文件本身。

根据你的使用场景,buildspec 文件中还提供了许多其他选项。你可以使用环境变量、生成报告,甚至以特定用户或 Linux 操作系统身份运行。完整选项列表,请参考 AWS 构建规范文档:docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html

我们刚刚深入了解了如何构建 buildspec 文件以及它包含的组件。接下来,我们将重点讨论 CodeBuild 生成的工件,以及如何将它们导出并存储到其他地方。

存储 CodeBuild 工件

当你创建一个软件包时,可以让 AWS CodeBuild 自动将该工件保存到 S3 存储桶中,以便在部署过程中使用。

buildspec 文件中,如果你打算创建工件,你可以声明一个工件,也可以声明多个工件。在 创建 CodeBuild 作业 部分,buildspec 文件在最后声明了一个工件。

注意

虽然 CodeArtifact 的名称可能会让您认为可以在构建后自动存储 CodeBuild 构建产物,但实际上不能。CodeArtifact 可以与 CodeBuild 配合使用,提供语言包,就像 NuGetPyPinpm 服务器 在构建过程中提供的那样,帮助您的团队使用标准化的包,并避免来自公共服务器的下载限制。

使用 CodeBuild 进行测试

虽然人们首先想到使用 AWS CodeBuild 可能是为了创建用于部署的包和构建 Docker 容器,但这个服务还可以在软件开发生命周期(SDLC)过程中发挥双重功能,那就是进行测试。CodeBuild 允许您运行预定义的单元测试,并在控制台中查看图形和文本形式的报告,了解测试结果。

报告在创建后 30 天过期,一旦过期,您和任何有权限访问报告的人都无法查看报告。如果您需要将报告的结果保留超过 30 天,您可以选择将报告的原始结果导出到 S3 存储桶中,这样它们就不会过期,只会根据存储桶的生命周期策略逐步淘汰。

CodeBuild 支持以下测试报告文件格式:

  • Cucumber JSON

  • Junit XML

  • NUnit XML

  • TestNG XML

  • Visual Studio TRX

在您的 buildspec 文件中指定一个报告组名称,并提供关于测试用例的信息,如果尚未存在,CodeBuild 会为您创建一个报告组。

测试创建后,AWS CodeBuild 可以在控制台上显示报告,快速总结所有测试的状态。

通过 CodeCommit 触发 CodeBuild 作业

AWS CodeCommit 可以用作构建的输入源。CodeCommit 本身不能原生地向 CodeBuild 发出信号,告诉它已经收到新的提交或合并到分支中。然而,借助 Lambda 服务,您可以添加触发器来启动 CodeBuild 作业。

拥有像这样的自动化过程,无需手动干预,帮助团队更迅速地找到 bug 和已部署的软件。创建一个触发器,自动向 CodeBuild 项目发出信号启动构建,是为您的软件开发生命周期SDLC)添加持续反馈的好方法:

https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/aws-cert-dop-engi/img/Figure_8.23_B17405.jpg

图 8.23 – 从 CodeCommit 触发 CodeBuild 作业

现在我们已经了解了如何使用 CodeCommit 服务自动启动 CodeBuild 作业,我们也知道如何在新代码成功合并到项目中时自动启动 CodeBuild 作业。

在下一章,第九章使用 CodeDeploy 和 CodePipeline 部署工作负载 中,我们将学习如何使用 CodePipeline 服务启动来自 CodeCommit 的构建过程。

接下来,我们将了解 AWS CodeBuild 的一些高级功能。

AWS CodeBuild 的高级功能

本节中我们将讨论的一些功能对于 DevOps 专业考试不是强制要求的。由于本书标题中有 beyond,以下是一些有助于让服务使用更便捷的功能。它们也是一些可以与团队成员和客户分享的好技巧。

使用 AWS Session Manager 帮助排查构建问题

如果你在排查构建问题时遇到困难,而不是寻找 ssh 进入基于 AWS 的 Docker 镜像会话管理器,AWS Session Manager 将允许你进入构建环境并尝试排查发生了什么。你可以通过在 buildspec 文件中添加 codebuild-breakpoint 来暂停构建:

phases:
  pre_build:
    commands:
      - echo Entered the pre_build phase...
      - echo "Hello World"> /tmp/test.txt
      - codebuild-breakpoint

完成故障排除后,你可以通过命令提示符传递 codebuild-resume,以便从 buildspec 文件中中断的位置继续。

总结

在这一章中,我们讨论了如何使用 AWS 原生的源代码工具 CodeCommit 让团队共享代码。我们还探讨了如何使用 CodeBuild 工具对软件进行打包、构建和测试。

在下一章中,我们将继续讨论 AWS Developer Tools。这包括使用 CodeDeploy 部署工作负载,然后通过 AWS CodePipeline 将一切串联起来。

复习题

  1. 你被要求为你的组织设置一个 CodeCommit 仓库,供开发团队使用。开发人员需要能够将提交推送到他们的分支,但不能将提交合并到主分支,也不能将提交推送到主分支。项目经理还需要在合并或提交到主分支时收到通知。哪个步骤组合能以最短时间保护主分支并发送通知?

    为 CodeCommit 仓库附加一个资源策略,拒绝 IAM 开发者组成员对主分支执行推送提交、合并请求和添加文件的操作。

    b. 为开发者 IAM 开发者组附加一项 IAM 策略,拒绝其对主分支执行推送提交、合并请求和添加文件的操作。

    配置 AWS CloudTrail 将日志事件发送到 Amazon CloudWatch 日志。创建一个基于定义的度量标准过滤器的 CloudWatch 警报,以识别 CodeCommit 仓库事件。使用 SNS 主题作为目标,项目经理已订阅该主题以接收 CloudWatch 警报。

    d. 创建一个 Amazon CloudWatch Events 规则,该规则会在主分支的 CodeCommit 仓库状态更改事件触发时运行。使用一个项目经理已订阅的 SNS 主题作为目标。

    e. 创建一个 Lambda 函数,检查仓库的变更,如果发现变更,则将事件发送到项目经理已订阅的 SNS 主题。让 AWS CloudWatch Events 每 15 分钟运行一次 Lambda。

  2. 你在账户中有一个 CodeCommit 代码库,开发者对该代码库有有限的操作权限。来自不同组织单元的两位新开发者需要访问这个 CodeCommit 代码库,但他们的用户位于不同的 AWS 账户中。授予这两位新开发者访问权限的最有效方式是什么?

    a. 为代码库启用公开访问权限。

    b. 为每个新开发者创建 IAM 用户,并授予他们对代码库的访问权限。

    c. 为外部开发者创建一个 IAM 组,添加 IAM 用户,然后为其提供对代码库的访问权限。

    d. 在你的账户中创建一个跨账户角色,为该角色分配必要的权限,然后将角色 ARN 提供给开发者,以便他们可以假设该角色。

  3. 一位客户正在寻找一个新的代码版本控制服务,并且不再希望管理自己服务器的麻烦。目前,他的团队规模较小,预计在接下来的四个季度不会急剧增长,但他非常关注任何他考虑的服务是否具备加密功能。关于 AWS CodeCommit 如何保护对象和代码的加密能力,你能向他解释什么?

    a. 所有传输内容在传输过程中都是加密的,并且只能通过 HTTPS 或 SSH 协议进行。

    b. 通过 SSH 协议发送时,传输内容在传输过程中是加密的。

    c. CodeCommit 代码库会自动使用 KMS 进行加密。

    d. CodeCommit 代码库可以使用 KMS 进行加密。

  4. 你正在设置一个新的构建过程,使用 S3 作为代码源。你希望对你和其他开发者之前创建并放置在名为 test/ 的目录中的代码进行单元测试,该目录位于主源代码目录的子目录中。你计划在这个构建过程中工作 60 天,并希望能够查看历史的测试报告,甚至是第一次构建的报告。你如何通过原生 AWS 服务配置这一过程?

    a. 测试报告将在 buildspec 文件中提供。

    b. 在每次构建后将 CodeBuild 测试数据导出到 S3,并使用 AWS QuickSight 创建测试报告。

    c. 如果你在 buildspec 文件中指定了报告部分,则测试报告将可在控制台的 CodeBuild 部分的 Reports 选项卡中查看。创建一个 Lambda 函数,该函数由 CloudWatch 事件触发,导出从测试报告中获取的原始数据,并将其保存到 S3 存储桶中,供后续查看。

    d. 使用原生的 AWS 服务无法实现此操作。

查看答案

  1. b, d

  2. d

  3. a, c

  4. c

内容概要:本文为《科技类企业品牌传播白皮书》,系统阐述了新闻媒体发稿、自媒体博主种草与短视频矩阵覆盖三大核心传播策略,并结合“传声港”平台的AI工具与资源整合能力,提出适配科技企业的品牌传播解决方案。文章深入分析科技企业传播的特殊性,包括受众圈层化、技术复杂性与传播通俗性的矛盾、产品生命周期影响及2024-2025年传播新趋势,强调从“技术输出”向“价值引领”的战略升级。针对三种传播方式,分别从适用场景、操作流程、效果评估、成本效益、风险防控等方面提供详尽指南,并通过平台AI能力实现资源智能匹配、内容精准投放与全链路效果追踪,最终构建“信任—种草—曝光”三位一体的传播闭环。; 适合人群:科技类企业品牌与市场负责人、公关传播从业者、数字营销管理者及初创科技公司创始人;具备一定品牌传播基础,关注效果可量化与AI工具赋能的专业人士。; 使用场景及目标:①制定科技产品全生命周期的品牌传播策略;②优化媒体发稿、KOL合作与短视频运营的资源配置与ROI;③借助AI平台实现传播内容的精准触达、效果监测与风险控制;④提升品牌在技术可信度、用户信任与市场影响力方面的综合竞争力。; 阅读建议:建议结合传声港平台的实际工具模块(如AI选媒、达人匹配、数据驾驶舱)进行对照阅读,重点关注各阶段的标准化流程与数据指标基准,将理论策略与平台实操深度融合,推动品牌传播从经验驱动转向数据与工具双驱动。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值