亚马逊AWS官方博客

借助 Cloud Foundations 实现 Terraform 基础设施即代码的自动化管理及其持续集成和持续部署

基础设施即代码是利用代码来管理基础设施的方式。代码化管理有很多优点,例如幂等性、版本控制、高效简洁、减少错误等。Terraform是业界流行的混合云编排工具。使用专门的配置语言来描述基础设施,编排并执行计划从而创建或销毁资源。要全自动的代码化管理资源,持续集成和持续部署是资源管理过程中不可或缺的。亚马逊云科技提供了从代码存储库(以下简称“存储库”)、构建项目到流水线的全套开发构建服务,用以搭建持续集成和持续部署流程。如何利用上述思想、工具和服务,自动化资源管理?亦即如何基于Terraform 实现亚马逊云科技资源的持续集成和持续部署,是本文想解决的主要问题。

借助亚马逊云科技的 Cloud Foundations 解决方案,您可以专注于工作负载相关资源的基础设施即代码开发测试工作,把剩下繁杂的自动化资源管理工作交给 Cloud Foundations 处理。

持续集成和持续部署典型应用场景

对于某个工作负载所需资源进行持续集成和持续部署测试时,按不同阶段可分为测试和生产。测试阶段可采用性能较弱的资源,部署至测试账户验证部署正确性和可靠性,同时节约开销;生产阶段可采用性能较强的资源,部署至生产账户应对实际业务需求。利用 Terraform 模块功能,把工作负载所需资源置于公共模块并参数化其性能配置,为测试和生产分别创建模块,引用公共模块并分别适配不同的性能参数,达到上述目的。简要绘制场景如下所示:

  1. 在应用资源模块构建工作负载所需资源的基础设施即代码,并参数化其性能配置;
  2. 在测试参数模块引用应用资源模块,适配测试参数并合并衍合到存储库;
  3. 触发测试部署流水线,通过 Terraform 构建项目将资源部署到一个或多个测试账户;
  4. 测试并验证资源部署情况符合要求;
  5. 在生产参数模块引用应用资源模块,适配生产参数并合并衍合到存储库;
  6. 触发生产部署流水线,通过 Terraform 构建项目将资源部署到一个或多个生产账户;

上述过程为一种管理模式。您可以根据实际情况适用其他更合适的持续集成和持续部署方法论管理基础设施即代码。本解决方案要解决的问题,就是通过自动化管理工具,为您搭建上述持续集成和持续发布的资源、服务和流程。您无需浪费时间在这些繁杂琐碎的构建准备中,只需关心和业务紧密相关的开发测试事务。

解决方案概览

自动化资源管理工作解决方案的设计思想紧紧围绕“基础设施即代码”展开。即除了基础设施资源本身代码化以外的准备工作都自动化完成。这部分内容主要回答以下问题:

  1. 在何处存储代码?
  2. 谁有权克隆提交代码?
  3. 如何持续集成和持续部署?
  4. 如何及时响应代码变更事件?
  5. 如何同时应对不同部门的资源管理?
  6. 如何有效管理组织内跨账户资源部署?

上述几点环环相扣,缺一不可。由此可见,“基础设施即代码”的构建准备千头万绪。Cloud Foundations 提供的存储库工厂和流水线工厂 Service Catalog 产品(以下简称“产品”),为您一扫开启构建基础设施即代码的障碍,让您把有限的精力和资源集中投入到和业务紧密相关的工作中。

架构图

以下是解决方案的架构示意图。有关 Cloud Foundations 的总架构图和设计思想请参阅《快速构建安全规范和架构完善的云上多账户运行环境》。

设计架构围绕为“基础设施即代码”的构建准备展开:

  1. 存放代码的 Amazon CodeCommit 代码存储库;
  2. 有权提交代码到存储库的 Amazon IAM 角色;
  3. 持续集成持续部署的Amazon CodePipeline 流水线及其 Amazon CodeBuild 构建项目;
  4. 触发持续集成和持续部署的 Amazon EventBridge 事件规则;
  5. 管理上述资源的 Amazon Service Catalog 产品;
  6. 安全规范承载上述资源以及所有新建工作负载资源的 Cloud Foundations

前提条件

要完成本文的示例操作,您需要满足以下条件之一:

  • 拥有一个亚马逊云科技管理账户,且已将 Cloud Foundations 部署于 Amazon Organizations 组织内;
  • 拥有数个亚马逊云科技普通账户,且已将 Cloud Foundations 部署于自定的虚拟组织内;

虽然 Cloud Foundations 为您扫清了基础设施即代码构建准备的绝大多数障碍,但仍有部分必要工作需要您根据业务应用和工作负载的实际情况预先规划,才能有效治理、事半功倍。例如:

  • 以何粒度管理存储库?对于小型部门或企业,您可以用一个存储库管理所有资源代码。对中大型部门或企业,您可以按部门、业务、项目来划分存储库。根据您的实际情况来划分存储库,过多过少都不妥。又如,可把跨部门通用模块至于单独的共享存储库;
  • 以何粒度管理 Terraform模块?一般以文件目录划分不同模块。对于简单应用,可以一个模块创建一个应用所需全部资源。对于复杂应用,可以按服务分层,几个模块一起共同有序构建所有资源。又如,可把改动频率少,创建耗时、影响范围大的资源归入一个模块,例如关系数据库,数据仓库等。

演示步骤

以 Cloud Foundations 为基础,基础设施即代码的构建准备过程简化为下列一、三、四共三步。您只需专注于和工作负载资源管理息息相关的第二步即可。我们按以下步骤演示,以下操作皆在基础账户中进行:

  1. 启动存储库工厂产品创建存储库;
  2. 克隆代码,编写基础设施即代码,并提交;
  3. 启动流水线工厂产品创建流水线。流水线创建一次可重复利用;
  4. 自动触发流水线发布更改,审阅流水线创建资源。

启动存储库工厂产品创建存储库

存储库工厂产品用于创建 Amazon CodeCommit 存储库,并在新建的存储库中预置持续集成和持续部署所需的自动化脚本和构建配置文件。

  1. catalog-user 身份登陆 Amazon Service Catalog 控制台启动存储库工厂产品;
  2. 输入存储库名称、存储库说明。例如为部门甲创建的存储库,输入 department1 ;Cloud Foundations 会添加前缀以符合命名规范,最终存储库名为 前缀-codecommit-department1
  3. 选择启动产品,并等待预置产品状态为可用

编写基础设施即代码

Cloud Foundations 在基础账户中预置了构建角色iac-builder,可以访问所有存储库。您可以根据业务实际情况和权限管理要求,按部门或项目创建受限访问指定存储库的构建联合认证角色,安全可控的开展基础设施即代码构建工作。

  1. 推荐通过GCR方式克隆代码到本地目录;
    git clone codecommit::cn-northwest-1://配置文件@前缀-codecommit-department1
  2. 在项目根目录下新建目录 terraform/project1/application1;模块目录须保存在 terraform/ 目录下。后续创建流水线时,以 terraform/ 目录为模块相对路径的根目录;
  3. 编写基础设施即代码。首先准备主配置文件 main.tf
    variable "partition" { default = "aws-cn" }
    variable "target_account" { type = string }
    terraform {
        required_version = ">= 1.3.0"
        required_providers {
            aws = {
                source  = "hashicorp/aws"
                version = ">= 4.40.0"
            }
        }
        backend "s3" { encrypt = true }
    }
    
    provider "aws" {
        assume_role {
            role_arn = "arn:${var.partition}:iam::${var.target_account}:role/OrganizationAccountAccessRole"
        }
    }
  1. 在此编写符合您工作负载实际情况的基础设施即代码内容。可按需分拆文件,或者引用其他公共模块。在此示例创建一个安全组和一台实例,其中镜像和子网信息动态读取,网络资源已经预先准备好:
    data "aws_ami" "amazon_linux" {
        most_recent = true
        owners      = ["amazon"]
        filter {
            name   = "name"
            values = ["amzn2-ami-kernel-5.*"]
        }
        filter {
            name   = "architecture"
            values = ["x86_64"]
        }
    }
    
    data "aws_vpc" "main" { state = "available" }
    data "aws_subnet" "private" {
        vpc_id     = data.aws_vpc.main.id
        cidr_block = cidrsubnet(data.aws_vpc.main.cidr_block, 4, 2)
    }
    
    resource "aws_security_group" "application" {
        name        = "application-security-group"
        description = "Application security group"
        vpc_id      = data.aws_vpc.main.id
    }
    resource "aws_instance" "application" {
        instance_type          = "t3.micro"
        ami                    = data.aws_ami.amazon_linux.id
        subnet_id              = data.aws_subnet.private.id
        vpc_security_group_ids = [aws_security_group.application.id]
        tags                   = { Name = "Hello World" }
    }
  2. 提交代码以触发流水线发布。首次提交时流水线可能还未创建,后续提交即可正常触发。

启动流水线工厂产品创建流水线

流水线工厂产品由于创建 Amazon CodePipeline 流水线产品,包含两条标准流水线,分别用来创建和销毁资源。标准流水线包含四个固定阶段(暂不支持增删自定义阶段):

  1. 源阶段:从 Amazon CodeCommit 的指定存储库指定分支拉取基础设施即代码;
  2. 构建阶段:通过 Amazon CodeBuild 构建项目以指定模块编排 Terraform 计划;
  3. 审批阶段:检查 Terraform 计划并确认无误后手动审批通过;
  4. 构建阶段:通过 Amazon CodeBuild 构建项目在指定账户执行 Terraform 计划;

Cloud Foundations 在基础账户中预置了构建角色pipeline-approver,可以查看构建项目、审批所有流水线。您可以根据业务实际情况和权限管理要求,按部门或项目创建受限访问指定流水线和构建项目的运维联合认证角色。我们继续前面的演示:

  1. catalog-user 身份登陆 Amazon Service Catalog控制台启动流水线工厂产品;
  2. 输入包含前缀的存储库全名:前缀-codecommit-department1分支名:master、拟执行的模块相对路径:project1/application1适用账户模式:多账户、适用账户标识:对于已知账户和全账户模式,毋需输入账户标识、单账户模式输入一个账户标识、多账户模式以半角逗号分隔多个账户标识;
  3. 选择启动产品,并等待预置产品状态为可用

流水线创建成功后可反复多次利用。一个模块对应的相对路径名只能创建一个流水线产品。如果某模块拟部署于多账户,可以在一个流水线产品中指定多账户,而非创建多个单账户部署的流水线。

审阅流水线创建资源

  1. pipeline-approver 身份登陆 Amazon CodePipeline 控制台,搜索名称含有 project1-application1 的创建流水线 前缀-pipeline-project1-application1-apply-fresh
  2. 发布更改。后续每次提交代码也会自动触发发布;构建项目会以指定模块编排 Terraform 计划。有两种方式查看计划,一是选择构建项目的详细信息,读取构建日志;二是在审阅对话框中查看计划文件所在位置,下载后读取。此类记录亦可备日后审计用。
  1. 确认流水线执行 ID 正确并手动审批通过;
  2. 等待持续部署流水线执行完毕且状态为成功

至此,您利用一套动态生成的持续集成和持续部署流程将工作负载资源部署到了多个账户。

删除资源

当资源不再需要时可及时删除以节约成本。删除前务必事先备份重要数据。删除资源需按序进行:

  1. pipeline-approver 身份登陆 Amazon CodePipeline控制台。执行并审阅销毁流水线前缀-pipeline-project1-application1-destroy 删除工作负载资源;
  2. catalog-user 身份登陆 Amazon Service Catalog控制台,终止预置流水线工厂产品删除创建和销毁流水线;
  3. 终止预置存储库工厂产品删除存储库;

总结

本文介绍并演示了利用 Cloud Foundations 的存储库工厂产品和流水线工厂产品动态生成持续集成和持续部署流水线,自动化管理工作负载基础设施即代码的流程,且步步可溯源、过程可审计。借助该功能,您可以集中精力到业务相关的资源代码化开发测试、快速构建工作负载环境、规范化工作负载的创建和销毁过程中。Cloud Foundations 致力于构建安全合规,完备高效的云上运行环境。我们诚恳期待您的宝贵使用意见和建议,期待与您共同构建更加完善的云上之旅。

本篇作者

袁文俊

亚马逊云科技专业服务部顾问。曾在亚马逊美国西雅图总部工作多年,就职于 Amazon Relational Database Service (RDS) 关系型数据库服务开发团队。拥有丰富的软件开发及云上运维经验。现负责业务持续性及可扩展性运行、企业应用及数据库上云和迁移、云上灾难恢复管理、云上良好架构框架等架构咨询、方案设计及项目实施工作。

周闻

亚马逊云科技专业服务团队数据库顾问。专注于企业云上数据库及相关基础设施的架构设计、云上数据库迁移方案设计、最佳实践以及落地实施。

周涛

亚马逊云科技专业服务团队云架构顾问。专注于企业整体云上基础设施架构设计、迁移方案设计、最佳实践以及落地实施。

刘育新

AWS ProServe 团队高级顾问,长期从事企业客户入云解决方案的制定和项目的实施工作。