亚马逊AWS官方博客

在大规模部署基础设施期间采用 AWS CodePipeline 和开放源工具

AWS 提供各种开发人员工具,以便托管代码、构建,以及将您的应用程序和/或基础设施部署到 AWS。这其中包括用于持续集成和持续部署编排的 AWS CodePipeline;完全托管的源代码控制服务 AWS CodeCommit;编译源代码、运行测试和制作软件包的完全托管持续集成服务 AWS CodeBuild;以及将软件自动部署到各种计算服务的完全托管部署服务 AWS CodeDeploy。这些服务可一起被用于在 AWS 上构建功能强大的 CI/CD 管道。

除此以外,AWS 开发人员工具也允许您利用开放源软件 (OSS) 在 AWS 上构建 CI/CD 管道,因此您可以继续使用自己熟悉的工具。例如,您可以使用 GitHub 作为 AWS CodePipeline 的源代码提供者,或者运行由 Jenkins 编排的 CodeBuild 作业。实际上,各种 OSS 和第三方工具都可以与 AWS CodeBuild 轻松集成,使您能够扩展管道的功能。由于 CodeBuild 是完全托管的服务,您无需对构建服务器进行管理,这是它带来的额外好处之一。

在这篇博客文章中,我们将向您介绍如何运用 AWS 开发人员工具和热门的开放源工具(如,CFN-Nag、CFN-Python-Lint 和 Stacker 等)在 AWS 上构建无服务器基础设施部署管道(即,您无需管理构建服务器)。管道会对照 CloudFormation 模板运行自动验证检查;若模板有效,它将部署对应的 CloudFormation 堆栈。

如需本博文的配套源代码,请见 GitHub 存储库中的 aws-codepipeline-at-scale-infrastructure-blog

开放源工具

首先,我们来简单了解一下本文中讨论的开放源工具,它们将在之后被用于构建基础设施管道。

CFN-Nag

CFN-Nag 是由 Stelligent 开发并提供给开放源社区,用于帮助在 AWS CloudFormation 模板中尽早发现安全问题的热门开放源工具。CFN-Nag 会在 AWS CloudFormation 模板中查找可能表明基础设施不安全的模式,例如:

  • IAM 规则过于宽松(通配符)
  • 安全组规则过于宽松(通配符)
  • 访问日志未被启用
  • 加密未被启用

要使用工作站的 CFN-Nag,您需要安装 Ruby v.2.5 或更高版本。假设您已满足此前提条件,只需运行:

gem install cfn-nag

如果使用 MacOS,您可以使用 HomeBrew 来安装:

brew install ruby brew-gem
brew gem install cfn-nag

通过命令行运行 CFN-Nag:

cfn_nag_scan --input-path <path to cloudformation json>

如需进一步信息,请查看 CFN-Nag GitHub 存储库

CFN-Python-Lint

CFN-Python-Lint 作为 CloudFormation lint 由 AWS 面向开放源社区发布。它会对照 AWS CloudFormation 规范来验证 AWS CloudFormation 模板(YAML 和 JSON),并进行额外的检查,包括确保资源属性的有效值和最佳实践,例如,若在模板中定义输入参数但从未被引用,lint 将发出警告。

要在工作站中安装 CFN-Python-Lint,您可以使用 pip:

pip install cfn-lint

如果 pip 不可用,您可以使用 Python 命令行:

python setup.py clean --all then python setup.py install

如果使用 Mac OS,您还可以通过 HomeBrew 安装 CFN-Python-Lint:

brew install cfn-lint

要从命令行调用 CFN-Python-Lint:

 cfn-lint <path to yaml template> 

这将运行您的模板的标准 lint。

如需进一步信息,请查看 CFN-Python-lint GitHub 存储库

Stacker

Stacker 是由 Remind 工程团队制作的开放源工具和库,并面向开放源社区发布。它被用于编排与管理一个或多个账户的 CloudFormation 堆栈。Stacker 可以自动管理堆栈的依赖关系,并且允许特定堆栈的输出参数传递给其他堆栈作为输入(甚至是部署于其他账户的堆栈!),确保以正确的顺序创建堆栈。它还可以并行部署无依赖关系的堆栈,从而大幅缩短部署时间。

要在工作站中安装 Stacker,您可以使用 pip:

pip install stacker

要调用命令行工具,在安装堆栈后运行此命令:

stacker build <path to cloudformation yaml or json template>

Stacker 将基于您的配置启动或更新您的 AWS CloudFormation 堆栈。Stacker 可以检测模板或其参数是否有更改。若未检测到某堆栈有更改,Stacker 将不会更新该特定堆栈。

如需进一步信息,请见 Stacker GitHub 存储库Stacker 文档,版本 1.7.0。

基础设施管道概览

基础设施管道概览。

 

上图显示的是我们将在本博客文章中构建的基础设施部署管道。它采用 AWS 服务,如 AWS CodePipeline、AWS CodeCommit 和 AWS CodeBuild,以及开放源软件,如 CFN-Nag、CFN-Python-Lint 和 Stacker。

管道的运作方式如下:开发人员制作 CloudFormation 模板,对 AWS 上的基础设施资源进行预置(如,有子网、路由表和安全组等的 VPC)。在完成以后,开发人员会将模板推送到 AWS CodeCommit 存储库,并触发基础设施管道。OSS 工具 CFN-Nag 和 CFN-Python-Lint 将在 CodeBuild 环境中并行运行,以对模板进行验证。CFN-Nag 将对照众所周知的安全漏洞检查模板,而 CFN-Python-Lint 将执行最佳实践并验证其是否符合 CloudFormation 规范。如果模板未通过验证测试,管道将以失败状态停止以防止出现部署问题。若模板通过验证,Stacker 将为每个模板创建或更新 CloudFormation 堆栈。如果 Stacker 失败,管道将以失败状态停止以显示部署问题。否则,堆栈将被创建或更新,以便对所需的 AWS 资源进行预置。

您可能也已经注意到,本文描述的是通用的基础设施管道,可被用于在 AWS 上的多个 AWS 账户部署任意资源,并同时针对已提交的模板执行验证规则。为了方便说明,我们将在本文中使用 Stacker 进行单一 AWS 账户部署,但该工具的特色是它的大规模跨账户部署功能。

使用管道部署什么?

在本文中,我们将使用基础设施部署管道部署以下三个简单的堆栈:

堆栈 #1:创建私有 S3 存储桶。
堆栈 #2:创建 EC2 IAM 角色,允许将对象置于在堆栈 #1 中创建的 S3 存储桶。
堆栈 #3:创建 EC2 实例和 EC2 配置文件,以代入在堆栈 #2 中创建的 IAM 角色,并且上传简单的文件到在堆栈 #1 中创建的 S3 存储桶。堆栈 #3 将取决于堆栈 #1 和 #2。

以下是我们刚才提到的用于三个堆栈的 Stacker 配置文件的代码段:

#-------------------------------------------------------------------------#
# Variable definitions
#-------------------------------------------------------------------------#
namespace: cposs
stacker_execution_profile: &stacker_execution_profile stacker_execution
stacker_bucket: ""  # not using S3 buckets to store CloudFormation templates

# any unique S3 bucket - doesn't matter much for demo purposes
s3_bucket_name: &s3_bucket_name cposssamples3bucket182755552031
# cheapest EC2 instance for testing purposes
ec2_instance_type: &ec2_instance_type t2.micro

#-------------------------------------------------------------------------#
# Stack Definitions (https://stacker.readthedocs.io/en/latest/config.html)
#-------------------------------------------------------------------------#
stacks:
  - name: sample-s3-bucket
    profile: *stacker_execution_profile
    template_path: templates/s3-bucket-template.yaml
    variables:
      S3BucketName: *s3_bucket_name

  - name: sample-ec2-iam-role
    profile: *stacker_execution_profile
    template_path: templates/ec2-role-template.yaml
    variables:
      S3BucketName: ${output sample-s3-bucket::S3BucketName}

  - name: sample-ec2-instance
    profile: *stacker_execution_profile
    template_path: templates/ec2-template.yaml
    variables:
      InstanceType: *ec2_instance_type
      S3BucketName: ${output sample-s3-bucket::S3BucketName}
      EC2IamRoleName: ${output sample-ec2-iam-role::EC2RoleName}

我们会在文件顶部定义变量。namespace 预留给 Stacker 用于为堆栈附加前缀名称。其他定义的变量使用可在模板其他部分被引用的 YAML 锚点。例如,变量 ec2_instance_type  会创建引用值 “t2.micro” 的锚点 ec2_instance_type 。此锚点值会在之后分配给堆栈 sample-ec2-instance 的输入变量 InstanceType(见上述 Stacker 配置文件代码段中的 “InstanceType: *ec2_instance_type”)。

堆栈会话将对我们的三个堆栈进行定义。针对每个堆栈,我们将给出堆栈的名称、Stacker 应该用来部署堆栈的 AWS 配置文件(凭证)、CloudFormation 模板的本地路径,以及堆栈的输入参数。请注意:我们使用 ${output ...} 来指代堆栈输出参数,并将其传递给其他堆栈作为输出参数。例如,堆栈 sample-s3-bucket 的 S3BucketName 输出参数被其他两个堆栈用作输入参数。

先决条件

要按照上图所示的步骤预置部署管道,请确保您满足以下先决条件:

步骤

首先,我们将对前面介绍过的基础设施管道进行预置。

1) 获取提供的源代码
使用先决条件部分提供的代码复制 Git 存储库。

$ git clone https://github.com/aws-samples/aws-codepipeline-at-scale-infrastructure-blog/tree/master

然后,您应该会看到以下文件结构:

  • codepipeline/:用于部署 CI/CD 管道的 CloudFormation 模板,包括 AWS CodePipeline、AWS CodeCommit、AWS CodeBuild 和 OSS CFN-Nag、CFN-Lint 和 Stacker
  • stacker:Stacker 所需用于执行 CloudFormation 堆栈部署的配置文件
  • stacker/buildspec.yaml:将为 CFN 预置安装与调用 Stacker 的 CodeBuild buildspec
  • stacker/stacker-config.yaml:包含堆栈描述和输入参数的 Stacker 配置文件
  • stacker/stacker-profiles:Stacker 用于部署不同堆栈的 AWS 配置文件
  • templates/*:管道将验证和部署上述堆栈的示例模板

2) 为管道构件创建本地 git 存储库

在获得源代码后,您将创建另一个本地 Git 存储库,然后仅将以下文件夹复制到存储库中:stacker/templates/。这是因为,为了方便说明,我们在同一个存储库中提供管道预置代码和通过管道推送的代码。

您应该执行以下操作。假设已将提供的 Git 存储库复制到文件夹 ~/sample-oss-pipeline/,您可以将目录命名为 sample-pipeline-artifacts/。接下来,将您的 stacker/templates/ 文件夹移动到此目录。此目录的内容将被推送到存储库,而且我们很快会在 AWS CodeCommit 中创建。

cd ~
mkdir sample-pipeline-artifacts/
cd sample-pipeline-artifacts/
git init
cp -r ~/Codepipeline-oss-blog/ ~/sample-pipeline-artifacts
rm README.md 
rm -r  blog codepipeline
git add --all
git commit -m "sample artifacts for OSS infrastructure pipeline"

在运行这些命令后,您的本地存储库应该出现 stacker/ 和 templates/ 文件夹。

3) 编辑 Stacker-Profile 文件

然后,在您首选的文本编辑器中打开文件 stacker/stacker-profiles

此文件将指定在运行 Stacker 的 CodeBuild 环境中可用的 AWS 配置文件。每个配置文件指代一个特定的 IAM 角色。stacker_master 配置文件被用于在 AWS CodeBuild 环境中调用 Stacker。Stacker 会代入 IAM 角色,以访问管道部署账户内的资源。为了执行堆栈部署,Stacker 需要一个或多个配置文件。由于要部署到单个目标账户(在我们的例子中即为部署管道的账户),我们会定义一个名为 stacker_execution 的配置文件。如果有多个目标账户,我们可以定义多个配置文件(如,stacker_execution_accountA、stacker_execution_accountB,等等)。

您将需要修改 stacker/stacker-profiles 中指定的 AWS 账户 id 123456789012 ,然后使用您自己的 AWS 账户 ID 替代该值。这将为 Stacker 提供部署目标账户。在您更新账户 ID 后,保存已编辑的文件并提交:

git commit -am "Updated target AWS accound id in stacker-profiles"

4) 编辑 Stacker 配置文件

在您首选的文本编辑器中打开文件 stacker/stacker-config.yaml。和讨论的一样,此文件包含 Stacker 用于为您创建 AWS 资源的参数。使用全局唯一的名称为还不存在的 S3 存储桶更新参数 s3_bucket_name,Stacker 将创建该存储库作为 CloudFormation 堆栈部署的一部分。它只是 Stacker 将为您创建的简单的私有 S3 存储库。另请注意,参数 ec2_instance_type 表示要部署的 EC2 实例的类型。默认将预置 “t2.micro” 实例。在部署时,EC2 实例将创建与上传简单的文件到您指定的 S3 存储桶。

5) 预置管道

现在,我们来使用提供的示例代码部署基础设施管道。我们将创建以下两个 CloudFormation 管道堆栈:

管道堆栈 #1:第一个堆栈将预置我们在之前介绍过的基础设施管道。该堆栈将会预置 CodeCommit 存储库、CodePipeline 管道和三个 CodeBuild 项目。第一个 CodeBuild 项目有内置的 buildspec 配置,它将安装并使用 CFN-Nag 检查 CloudFormation 模板中的安全漏洞。第二个 CodeBuild 项目有内置的 buildspec 配置,它将安装并使用 CFN-Python-Lint 检查 CloudFormation 模板代码。第三个 CodeBuild 项目不含内置的 buildspec 配置。不过,buildspec 文件将被推送到 CodeCommit 存储库,以指示 CodeBuild 应如何安装和运行 Stacker,以便预置和编排 CloudFormation 堆栈。

buildspec 文件可被构建到 CloudFormation 模板中,或由开发人员进行显式传递。将 buildspec 文件构建到 CloudFormation 模板的好处是,它可以帮助确保通过管道部署代码的团队遵守常见的标准。(如果将 buildspec 文件构建到 CloudFormation 模板,开发人员无法对 buildspec 文件进行编辑或修改。)

通过下述步骤预置管道:

  • 登录您的 AWS 账户
  • 导航至 CloudFormation 控制台
  • 创建名为 cposs-codepipeline-stack 的堆栈,以代表基础设施管道

在 CloudFormation 堆栈页面上,单击“创建堆栈”按钮:

创建堆栈映像。

第 1 步:在下页(创建堆栈)完成以下部分的操作:

  • 先决条件 – 准备模板:保持选择默认的单选按钮—模板准备就绪。
  • 指定模板 – 选择单选按钮—上传模板文件。
  • 选择选择文件按钮,然后在您的私有存储库—codepipeline/codepipeline-template.yaml 中选择文件。
  • 单击下一步

AWS Cloudformation 创建堆栈页面。

第 2 步:指定堆栈详情页面上完成以下部分的操作:

  • 堆栈名称:输入名称 cposs-codepipeline-stack
  • 参数:保留默认信息或按要求更改(如,您可以为您的 CodeCommit 存储库挑选名称,或者接受默认的 “samplerepo”)。确保填写以下两个必填字段:

    • CodePipelineArtifactsS3BucketName:指定可被 CodePipeline 用于存储您的构件的唯一 S3 存储桶名称。我们建议您挑选以前缀 “cposs” 开头的名称,如 cposs-pipeline-artifacts-XXXXXX ,其中 X 为由您选择的随机数字或您的 AWS 账户 id。
    • TargetAccount:复制您的 AWS 账号,并粘贴到此字段。
  • 单击下一步按钮。

第 3 步:配置堆栈选项页面上保留默认信息并选择“下一步”。

第 4 步:检查页面上花点时间检查输入的信息:

  • 确保您已使用唯一的 S3 存储桶名称并且已输入正确的账号,否则此项目将无法正常运行。
  • 在确定输入的所有详细信息均正确无误后,勾选“我确认,AWS CloudFormation 可能创建具有自定义名称的 IAM 资源”复选框。 您必须这样做,因为模板将为不同的 CodeBuild 项目和 CodePipeline 管道创建 IAM 角色。
  • 选择“创建堆栈”。您可能需要花几分钟时间创建您的第一个堆栈。您应该会看到如下信息:

在成功创建堆栈后,您将看到的输出类似于:

在创建第二个堆栈前,导航至 CodeCommit 控制台。选择存储库,然后您应该会看到已创建的示例存储库,类似于(如果您更改过默认值,存储库的名称将有所不同):

 AWS CodeCommit 存储库将显示示例存储库

接下来,导航至 IAM 控制台并选择角色。您将可以看到由您的堆栈所创建的五个角色:

创建的 IAM 角色将在此处显示。

我们来更仔细地观察每一个角色,并且确保理解每个角色的用途:

  • cposs-CodeBuildCFNLintRole:这是为 CFN-Python-Lint CodeBuild 环境创建的 IAM 服务角色
  • cposs-CodeBuildCFNNagRole:这是为 CFN-Nag CodeBuild 环境创建的 IAM 服务角色
  • cposs-CodeBuildDeployerRole:这是为 Stacker CodeBuild 环境创建的 IAM 服务角色
  • cposs-CodePipelineRole:这是 CodePipeline 的 IAM 服务角色,它允许管道执行从构件 S3 存储桶读取构件或将构件写入构件 S3 存储桶等任务,以便触发不同的 CodeBuild 环境
  • cposs-StackerMasterRole:这是用于启动 Stacker 的 IAM 角色,它允许 Stacker 代入 cposs-StackerExecutionRole(将在后续创建)以通过 CloudFormation 将 AWS 资源部署到不同的目标账户。为了方便说明,我们将在例子中使用单个账户,即为管道所在的账户。

文件 stacker/buildspec.yaml 包含 AWS CodeBuild buildspec,以便为 CloudFormation 模板预置安装并调用 Stacker。buildspec.yml 文件将定义由 AWS CodeBuild 执行的步骤,在将 AWS CloudFormation 模板部署到生产环境前对它进行测试。如前文所述,您可以通过两种主要的方法指定您的 CodeBuild buildspec 配置。第一种方法是,在 CloudFormation 模板(内置 buildspec)中指定 buildspec,与我们为 CFN-Nag 和 CFN-Python-Lint 所执行的操作相同。以下代码段显示通过 CloudFormation 为 CFN-Python-Lint CodePipeline 操作创建的 CodeBuild 项目。注意下方的 BuildSpec 属性,以及我们该如何在 CodeBuild Python 3.6.5 环境中用它安装 (见 pip install cfn-lint)与调用 CFN-Python-Lint 工具。

  CFNLintCodeBuildProject:
    Type: AWS::CodeBuild::Project
    Properties:
        Name: !Sub ${Namespace}-cfn-lint-code-build-project
        Description: CodeBuild Project to validate CloudFormation templates using cnf-python-lint
        Artifacts:
          Type: CODEPIPELINE
        Environment:
            Type: LINUX_CONTAINER
            ComputeType: BUILD_GENERAL1_SMALL
            Image: aws/codebuild/python:3.6.5
            EnvironmentVariables:
              - Name: CFNTemplatesPath
                Value: !Ref CFNTemplatesPath
        ServiceRole:
          !GetAtt CFNNagCodeBuildServiceRole.Arn
        Source:
            Type: CODEPIPELINE
            BuildSpec: |
              version: 0.2
              phases:
                install:
                  commands:
                    - pip install --upgrade pip
                    - env && ls -l && python --version
                    - pip install cfn-lint
                    - cfn-lint ${CFNTemplatesPath}*.yaml

在 CloudFormation 中使用 BuildSpec 属性意味着将代码推送到管道的开发人员无法修改 CodeBuild 环境的行为,以及我们使用 CFN-Python-Lint 检查 CloudFormation 模板代码的方式。

另一种配置 CodeBuild 环境的方法是允许开发人员创建自定义 buildspec.yml 文件,并将其推送到 CodeCommit 存储库。该方法给他们提供更大的灵活性,使其能够控制 CodeBuild 执行环境,因此,他们可以根据需要安装安装与运行软件,等等。如果管道或管道构件归属于不同的团队,管道构建团队应仔细规划他们要为开发人员提供多大程度的自定义控件,以及哪些构建步骤是不可变的。

以下是我们用于 CodeBuild 项目并且运行 Stacker 的自定义 buildspec.yml YAML 文件。注意,我们会定义一些环境变量并运行若干命令,以便配置 AWS 凭证,安装 (pip install stacker==1.7.0) 并运行 Stacker (stacker build)。

version: 0.2

env:
  variables:
    stacker_master_profile_name: "stacker_master"
    stacker_profiles_file: "stacker-profiles"
    stacker_orchestration_file: "stacker-config.yaml"

phases:

  pre_build:
    commands:
      - pip install --upgrade pip
      - pip install stacker==1.7.0
      - env && ls -lha && python --version

  build:
    commands:
      - export AWS_CONFIG_FILE="${CODEBUILD_SRC_DIR}/${StackerConfigPath}/${stacker_profiles_file}"
      - echo "AWS_CONFIG_FILE=${AWS_CONFIG_FILE}"
      - stacker build "${CODEBUILD_SRC_DIR}/${StackerConfigPath}/${stacker_orchestration_file}" --profile $stacker_master_profile_name --recreate-failed

管道堆栈 #2:我们要创建的第二个堆栈会预置 Stacker 将 AWS 资源部署到特定目标 AWS 账户所需的 IAM 角色。我们为管道和 Stacker 执行角色使用独立的模板,因为如果我们希望管道将堆栈预置到多个账户,后者现在即可被部署到多个目标账户。

由于我们在本文中使用单个 AWS 账户,因此我们将在与管道相同的账户中创建 Stacker 执行角色。角色中的 IAM 策略必须将权限设置为部署模板中引用的全部类型 AWS 资源。在我们的例子中,Stacker 需要创建 S3 存储桶、EC2 实例和 IAM 角色等所需的权限。请检查模板的以下详细信息。

  • 创建您的第二个堆栈,它的名称为 cposs-stacker-execution-role-stack,并且使用 codepipeline/stacker-execution-role-template.yaml 文件。第二个堆栈将在您的账户中创建 IAM 角色,因此 Stacker 可以在其所在的相同账户中部署输出。如上所述,虽然我们在此项目中使用单个账户,但此方法同样适用于多个账户。

CloudFormation 堆栈页面上,选择创建堆栈

  • 第 1 步:在创建堆栈页面完成以下部分的操作:
    • 先决条件 – 准备模板:保持默认选择—模板准备就绪
    • 指定模板 – 选择单选按钮—上传模板文件
    • 选择选择文件按钮,然后在您的私有存储库—codepipeline/stacker-execution-role-template.yaml中选择文件。
    • 单击下一步
  • 第 2 步:在指定堆栈详情页面上完成以下部分的操作:
    • 堆栈名称:输入名称 cposs-stacker-execution-role-stack
    • 参数:保留默认。不过,要确保填写以下两个字段:

      • Namespace:保留原来的默认值,即 cposs。
      • StackMasterAccountID:复制您的 AWS 账号,并粘贴到此字段。
    • 选择下一步
  • 第 3 步:在配置堆栈选项页面上保留默认信息并选择下一步
  • 第 4 步:在检查页面上花点时间检查输入的信息。
    • 确保您已使用唯一的 S3 存储桶名称并且已输入正确的账号,否则此项目将无法正常运行。
    • 在页面底部单击“我确认,AWS CloudFormation 可能创建具有自定义名称的 IAM 资源”复选框。
    • 单击创建堆栈。创建您的堆栈将花费一到两分钟时间。您应该会看到如下信息:

显示正在创建堆栈 2 的屏幕截图

在成功创建您的堆栈后,控制台屏幕将显示如下信息:

显示堆栈 2 已成功创建的屏幕截图

使用 AWS CodePipeline 基础设施管道

管道已准备就绪,而且我们也已对管道构件进行过配置,现在使用管道部署我们的堆栈。

先决条件

为了将代码推送到 CodeCommit 并触发管道,您将需要确保:

  • 已安装本地 Git 客户端。
  • 正确配置 AWS 凭证,以允许您的 Git 客户端验证并将代码推送到 CodeCommit 存储库。

在确认满足上述先决条件后,按照以下步骤进行操作:

  • 在您的 AWS 账户中,导航至 CodeCommit 控制台并查找名为 samplerepo 的存储库。
  • 在 Clone URL 标题下方,单击蓝色的 HTTPS 文本。此操作将复制 HTTPS 地址到您的剪贴板。

AWS CodeCommit 存储库的屏幕截图

此时,您的本地 git 存储库中应该有 stacker/templates/ 文件夹(已在之前创建)。将 Git remote 添加到您的 CodeCommit 存储库,如下:

git remote add cc <HTTPS URL for the samplerepo>

此处的 cc 是 CodeCommit 的缩写。确保您的本地 Git 存储库没有任何要提交的待处理更改(git 状态)。

将您的代码推送到 CodeCommit 存储库的主分支:git push cc master:master。

在推送您的代码后,导航至 AWS CodePipeline 控制台以验证管道已被成功触发。在 CodePipeline 控制台中,选择管道,然后再选择您的管道—cposs-cicd-pipeline。如果一切顺利,您的模板将被验证和部署,而管道应该如下方屏幕截图所示:

 

管道成功触发屏幕截图

那么,我们究竟部署了什么? 我们部署了前面提到的三个堆栈:S3 存储库、IAM 角色,以及代入 IAM 角色并将文件写入 S3 存储库的 EC2 实例(以及其他资源,如安全组、EC2 配置文件等)。在您所指定 stacker/stacker-config.yaml 的 S3 存储桶中应该有一个名为 “hello.txt” 的文件。

现在查看 AWS CodeCommit 控制台中的示例存储库,以检查您通过无服务器管道推送了什么:

显示通过您的无服务器管道所推送文件的 CodeCommit 控制台。示例存储库中文件结构的屏幕截图

我们之前在本文中介绍过文件结构,并解释了将被推送到 codepipeline 的文件及其用途。我们来简单做一下总结:

  1. buildspec.yaml:这是 AWS CodeBuild buildspec。正如我们所讨论的那样,它的用途是为 CloudFormation 资源预置安装与调用 Stacker。
  2. stacker-config.yaml:这是包含堆栈描述和输入参数的 Stacker 配置文件
  3. stacker-profiles:此文件包含 Stacker 在部署期间用于代入角色的 AWS 配置文件

测试管道失败场景

我们在 templates/ 下方对其中一个模板进行更改,使管道模板验证阶段失败。例如,在模板 s3-bucket-template.yaml 中为 S3BucketName 输入参数指定一个无效类型,类似于:

Original template:

Parameters:

  S3BucketName:
    Type: *String*
    Description: Unique name to assign to S3 bucket

Incorrect template:

Parameters:

  S3BucketName:
    Type: *InvalidType*
    Description: Unique name to assign to S3 bucket

再次提交并推送您的代码到 CodeCommit 存储库,等待管道在 CFN-Python-Lint 对照 CloudFormation 规范检查您的模板时失败,如下方屏幕截图所示:

 

管道失败的屏幕截图

如需管道失败的原因,在 CFN-Python-Lint 的 CodeBuild 操作中单击详情链接。您应该会看到与以下类似的屏幕。第 117 行显示“参数 S3BucketName 有无效类型 InvalidType”。

管道失败使用案例中的 cli 问题排查。

我们需要的是:CFN-Python-Lint 在管道部署我们的模板前帮助我们确保它们的有效性。

清理

为了避免您的 AWS 账户在未来产生费用,为此项目删除在您的 AWS 账户中创建的资源。您可以简单销毁之前创建的两个管道堆栈:cposs-codepipeline-stack 和 cposs-stacker-execution-role-stack。记住:您将必须清除由 cposs-codepipeline-stack 堆栈创建的 S3 存储桶,否则 CloudFormation 将无法删除对应的堆栈。

结论

在本文中,我们介绍了您可以如何利用热门的开放源工具和 AWS 代码服务(如 CodePipeline、CodeCommit 和 CodeBuild 等)来构建、验证和部署任意的基础设施堆栈。我们采用了 CFN-NAG 和 CFN-Lint 来验证模板,并通过 Stacker 执行 CloudFormation 堆栈的部署。我们还对被推送到 AWS CodeCommit 存储库的构件的详细信息进行了说明。

与开放源和 CI/CD 管道有关的更多信息

如需更多如何集成 AWS 服务和开放源工具以构建 CI/CD 管道的例子,请见 AWS 开源博客中其他一些文章,包括:使用 Spinnaker 在 Kubernetes 上构建部署管道通过 Git Push 在 EKS 上部署应用程序,或通过 AWS CodeCommit 集成 Phabricator 和 AWS CodePipeline