使用 Bitbucket Pipelines 和 AWS CodeDeploy 持续交付

在上一节中,我们为 PHP 应用程序准备了一个 AWS EC2 实例。现在,我们需要一种将解决方案代码从 Bitbucket 移植到 EC2 实例的方法。为此,我们需要配置 Bitbucket Pipelines 以使用 AWS CodeDeploy。有关将 Bitbucket Pipelines 部署到 AWS CodeDeploy 的更多信息,请访问 https://support.atlassian.com/bitbucketcloud/docs/deploy-to-aws-with-codedeploy/

Bitbucket 管道设置

我们需要在 Bitbucket 中添加一些 AWS 特有的信息,因为我们将使用这些信息连接到 AWS CodeDeploy 应用程序。要添加这些信息,请按照以下步骤操作:

  1. 在 Bitbucket 存储库仪表板中,单击存储库设置选项:

    image 2023 10 24 17 45 29 835
    Figure 1. Figure 10.32 – Repository settings
  2. 然后,从左侧菜单中选择存储库变量链接。您应该被重定向到存储库变量页面。 在名称和值字段中,添加以下名称和值:

    • AWS_ACCESS_KEY_ID:使用密钥对文件中的值

    • AWS_SECRET_ACCESS_KEY:使用密钥对文件中的值

    • AWS_DEFAULT_REGION:ap-southeast-2

    • S3_BUCKET:<您唯一的 S3 存储桶名称>

    • DEPLOYMENT_GROUP:codedeploy_group1

    • APPLICATION_NAME:mycodedeployapp:

    image 2023 10 24 17 47 02 704
    Figure 2. Figure 10.33 – Repository variables; AWS values

    接下来,我们需要告诉 Bitbucket Pipelines 我们想要压缩应用程序并将其上传到 AWS S3。然后,我们将使用 AWS CodeDeploy 将其部署到我们的 EC2 实例。

  3. 回到我们的代码库,在根目录下找到上一章创建的 bitbucket-pipelines.yml 文件。在文件中添加以下几行:

    /bitbucket-pipelines.yml
    image: docker:stable
    
    options:
      docker: true
    
    pipelines:
      default:
        - step:
            name: Run Automated Tests
            script:
              - set -eu
              - apk add --no-cache py-pip bash
              - apk add --no-cache gcc
              - apk add --update --no-cache --virtual .tmp-build-deps gcc libc-dev linux-headers postgresql-dev && apk add libffi-dev
              - apk update && apk add python3-dev gcc libc-dev
              - pip install --upgrade pip setuptools wheel
              - pip install --no-cache-dir docker-compose
              - docker-compose -v
              - ls -lap
              - pwd
              - cd docker
              - docker-compose build && docker-compose up -d
              - docker exec -i docker_server-web_1 /var/www/html/symfony/setup.sh
              - docker exec -i docker_server-web_1 /var/www/html/symfony/runCoverage.sh
              - docker exec -i docker_server-web_1 /var/www/html/behat/setup.sh
              - docker exec -i docker_server-web_1 /var/www/html/behat/runBehatTests.sh
            caches:
              - composer
        - step:
            name: Package and Upload
            script:
              - apk add zip
              - zip -r phptddapp.zip .
              - pipe: atlassian/aws-code-deploy:0.2.10
                variables:
                  AWS_DEFAULT_REGION: $AWS_DEFAULT_REGION
                  AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
                  AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
                  COMMAND: 'upload'
                  APPLICATION_NAME: 'mycodedeployapp'
                  ZIP_FILE: 'phptddapp.zip'
                  S3_BUCKET: $S3_BUCKET
                  VERSION_LABEL: 'phptdd-app-1.0.0'
        - step:
            name: Deploy to AWS
            script:
              - pipe: atlassian/aws-code-deploy:0.2.5
                variables:
                  AWS_DEFAULT_REGION: $AWS_DEFAULT_REGION
                  AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
                  AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
                  APPLICATION_NAME: $APPLICATION_NAME
                  DEPLOYMENT_GROUP: $DEPLOYMENT_GROUP
                  S3_BUCKET: $S3_BUCKET
                  COMMAND: 'deploy'
                  VERSION_LABEL: 'phptdd-app-1.0.0'
                  IGNORE_APPLICATION_STOP_FAILURES: 'true'
                  FILE_EXISTS_BEHAVIOR: 'OVERWRITE'
                  WAIT: 'true'

    在这里,我们将使用我们在上一节的存储库变量页面中输入的 AWS 值。

接下来,我们需要告诉 CodeDeploy 在部署应用程序时要运行哪些脚本。

创建 CodeDeploy 配置文件

CodeDeploy 需要一个名为 appspec.yml 的基础配置文件。在这里,我们可以让 CodeDeploy 为我们运行脚本,比如运行 docker-compose 和 Symfony 应用程序的 setup.sh 脚本。

创建 /appspec.yml 文件并添加以下内容:

version: 0.0
os: linux
files:
  - source: /
    destination: /home/ec2-user/phptdd
hooks:
  AfterInstall:
    - location: aws/codedeploy/containers_setup_php.sh
      timeout: 3600
      runas: ec2-user

在该文件中,我们要告诉 CodeDeploy,我们希望将代码复制到 /home/ec2-user/phptdd 目录中。安装完成后,我们要运行 containers_ setup_php.sh 文件,接下来将创建该文件。创建包含以下内容的文件:

aws/codedeploy/containers_setup_php.sh
#!/bin/bash

# Build and run containers (PHP, MySQL)
docker-compose -f ~/phptdd/docker/docker-compose-production.yml down
docker-compose -f ~/phptdd/docker/docker-compose-production.yml build
docker-compose -f ~/phptdd/docker/docker-compose-production.yml up -d

# Setup the PHP Applications inside the containers (install composer packages, setup db, etc).
docker-compose -f ~/phptdd/docker/docker-compose-production.yml exec server-web php --version
docker-compose -f ~/phptdd/docker/docker-compose-production.yml exec server-web /var/www/html/symfony/setup.sh
docker-compose -f ~/phptdd/docker/docker-compose-production.yml exec server-web /var/www/html/behat/setup.sh

你会发现我们正在运行 docker-compose。之后,我们将运行为 Symfony 和 Behat 应用程序创建的自定义 setup.sh 文件。

接下来,我们需要使用 Bitbucket Pipelines 运行整个 CI/CD 流程。

运行 Bitbucket 管道

现在我们已经拥有了所需的一切,只需提交文件并将其推送到存储库即可触发 Bitbucket 管道运行,或者只是手动运行管道。

我们的管道现在分为三个步骤:

  • 运行自动测试(Run automated tests):这将运行我们的 Symfony 和 Behat 测试

  • 打包和上传(Package and upload):将代码压缩并上传到 AWS S3

  • 部署到 AWS(Deploy to AWS):这将使用 CodeDeploy 在我们配置的 EC2 实例中部署我们的解决方案

运行所有内容需要几分钟,但想象一下替换手动测试数十、数百或数千个功能和服务器部署的手动过程:

image 2023 10 24 17 59 18 196
Figure 3. Figure 10.34 – CI/CD result

18 分钟后,我们完成了整个过程!这个设置和流程还可以调整和优化,但在短短几分钟内,我们就能自动运行所有测试场景,并自动将它们部署到远程服务器上!

部署成功了吗?让我们一探究竟。

回到 AWS 控制台,再次连接 EC2 实例:

image 2023 10 24 18 00 22 703
Figure 4. Figure 10.35 – New phptdd directory

如果代码部署有效,您会注意到的第一件事是应该有一个新的 /phptdd 目录。我们看看里面有没有东西:

image 2023 10 24 18 01 29 134
Figure 5. Figure 10.36 – /phptdd content

如您所见,我们拥有推送到 Bitbucket 存储库中的所有文件!但是我们的 Docker 容器呢?让我们看看他们是否正在运行。

运行以下命令:

docker ps

如果 CodeDeploy 正确安装了所有内容,我们应该会看到容器正在运行:

image 2023 10 24 18 02 34 919
Figure 6. Figure 10.37 – Docker containers running

我们所有的容器都在运行!现在,如果我们运行自动化测试会怎样?让我们看看进展如何。运行以下命令:

docker-compose -f -/phptdd/docker/docker-compose-production.yml

您应该看到以下内容:

image 2023 10 24 18 03 40 289
Figure 7. Figure 10.38 – Running a Symfony coverage test in EC2

我们所有的 Symfony PHP 测试都通过了!但实际的 Web 应用程序又如何呢? 自动化测试对我们的访客来说没有意义。

返回 EC2 仪表板并单击我们创建的 EC2 实例。然后,单击弹性 IP 地址链接:

image 2023 10 24 18 04 57 018
Figure 8. Figure 10.39 – Elastic IP addresses link

将加载弹性 IP 地址详细信息。然后,复制公共 DNS 值:

image 2023 10 24 18 05 34 168
Figure 9. Figure 10.40 – Elastic IP – Public DNS

复制公共 DNS 后,只需将其粘贴到您的网络浏览器中并查看它是否加载:

image 2023 10 24 18 06 01 680
Figure 10. Figure 10.41 – HomeController

如您所见,我们现在可以通过网络浏览器访问我们的网络应用程序。您可以尝试注册账户、登录和添加新的玩具车条目。

让我们先试试注册功能:

  1. 点击注册链接,输入电子邮件地址和密码:

    image 2023 10 24 18 06 59 561
    Figure 11. Figure 10.42 – Register
  2. 点击注册。然后点击登录按钮:

    image 2023 10 24 18 07 48 815
    Figure 12. Figure 10.40 – Login

    如果运行正常,就会跳转到 "添加玩具车" 页面。

  3. 在 "添加玩具车" 页面,在字段中添加一些值:

    image 2023 10 24 18 08 46 921
    Figure 13. Figure 10.41 – Add Toy Car
  4. 点击 "添加玩具车" 按钮。如果成功,就会跳转到表格控制器:

    image 2023 10 24 18 09 28 475
    Figure 14. Figure 10.42 – Table controller

    在表格控制器中,我们创建的玩具车条目将全部显示出来。如果我们想为应用程序添加更多功能,只需从 Jira 票据开始,创建一个新分支,编写一些代码,提交并推送代码,仅此而已。CI/CD 流程会处理剩下的工作!

总结

在本章中,我们介绍了设置 AWS EC2 实例、AWS CodeDeploy 以及托管 PHP 应用程序所需的所有其他 AWS 资源的过程。我们将 Bitbucket Pipelines 与 AWS CodeDeploy 应用程序集成,并使用自定义脚本在每次运行 CodeDeploy 时自动配置 AWS EC2 实例内的 Docker 容器。

我们介绍了从开发人员向应用程序推送新代码变更、运行所有自动测试到通过 AWS 将整个解决方案部署到 Linux 服务器的整个过程。我们还可以使用网络浏览器手动测试网络应用程序,以确保消费者可以使用应用程序。

在下一章中,我们将研究一些帮助我们监控应用程序的工具。在开发大型应用程序时,这将非常有帮助,因为作为开发人员,这将帮助我们分析应用程序的性能和健康状况。