亚马逊AWS官方博客
使用开源工具 Liquibase 和 Jenkins 部署、跟踪和回滚 RDS 数据库代码更改
各行各业的客户都需要处理关系数据库代码部署。在大多数情况下,开发人员依靠数据库管理员 (DBA) 执行数据库代码部署。当数据库数量和数据库代码更改量不大时,这非常适用。但是,如果是公司规模,那么他们需要处理不同的数据库引擎,包括 Oracle、SQL Server、PostgreSQL 和 MySQL,以及成百甚至上千个数据库。当开发人员需要部署、跟踪或是回滚数据库更改时,这会对 DBA 造成巨大的负担。而且,在敏捷的环境中等待 DBA 为开发人员进行更改会产生瓶颈。
在本博文中,我将会详细介绍一个在 AWS 中使用开源工具 Liquibase 和 Jenkins 构建具有成本效益、独立于数据库的解决方案示例,以解决这些数据库问题。我不会深入介绍 Liquibase 或 Jenkins 的工作原理;相反,我会重点介绍如何在 Amazon Elastic Compute Cloud (Amazon EC2)、AWS CodeCommit、AWS Secrets Manager 和 Amazon Simple Email Service (Amazon SES) 等 AWS 服务上部署这些开源工具,以实现所需目标。
概览
Liquibase 是一个独立于数据库的库,用于跟踪、管理和应用数据库架构更改,使用户能够更轻松地跟踪数据库更改。您可以轻松以 SQL、XML、JSON 或 YAML 格式定义更改。
Jenkins 是一个开源自动化服务器,支持开发人员可靠地构建、部署和回滚代码更改。Jenkins 可以安装在任何已安装 Java Runtime Environment (JRE) 的计算机上。
先决条件
出于本演练的目的,您需要具备以下条件:
- AWS 账户
- Amazon Aurora RDS 数据库 (PostgreSQL)
- 可连接到 Amazon Aurora RDS 数据库和创建/删除表的数据库用户
- 已在其中安装 Git 客户端并且已将该客户端配置为连接到 CodeCommit 存储库和发布数据库代码的本地计算机
架构
演练
让我们来详细介绍一个示例,在该示例中,我将使用在 Amazon Linux AMI 上运行的 Amazon EC2 实例构建此解决方案,在 Amazon Aurora PostgreSQL RDS 数据库上部署数据库架构更改。
步骤 1:将数据库凭证存储于 AWS Secrets Manager 中
在先决条件部分,我提到了需要数据库用户才能部署数据库更改。此数据库用户用于在数据库中来回部署和回滚架构更改。我将使用 Secrets Manager 来存储这些数据库用户凭证。需要时,使用 AWS 命令行界面 (AWS CLI) 配置 Jenkins 作业,以检索这些凭证。
在下面的示例中,我将存储名为 dbdevopsaurora 的 RDS Aurora 数据库的凭证。
1.在 AWS 控制台中,导航至 AWS Secrets Manager、存储新密钥。
2.选择 RDS 数据库凭证作为密钥类型,然后输入数据库用户名和密码。
3.选择下一步,然后填写密钥 名称和描述字段。
4.依次选择下一步和启用自动旋转(可选,但推荐选中)。
5.依次选择下一步和保存。
步骤 2:设置 CodeCommit 存储库
要创建 CodeCommit 存储库:
1.打开 CodeCommit 控制台。
2.在区域选择器中,选择想要在其中创建存储库的 AWS 区域:Us-east-1.
3.在存储库页面上,选择创建存储库。
4.在创建存储库页面上,输入存储库名称:DBDevopsDemoRepo.
5.在描述中,输入存储库描述:此存储库用于 DB 部署自动化演示。
6.可选步骤:选择添加标签向您的存储库添加一个或多个存储库标签(自定义属性标签,用于帮助您组织和管理您的 AWS 资源)。
7.创建。
步骤 3:启动 EC2 实例以托管 Jenkins 和 Liquibase
在此构建环境中,我将启用在 Amazon Linux AMI 上运行的 Amazon EC2 实例,以托管 Liquibase、Jenkins 以及此解决方案所需的其他程序包。
安装和配置 Jenkins、Java、Nginx、jq、Git
使用专用密钥连接到您的实例,然后切换至根用户。首先,让我们更新存储库并安装 Jenkins、Nginx、Git、Java 和 jq。
若要在 Amazon Linux 上安装 Jenkins,我们需要从以下位置添加 Jenkins 存储库和安装 Jenkins:
wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key
yum install -y jenkins
yum install -y java
yum install -y nginx1
yum install -y jq
yum install -y git-all
Jenkins 通常使用端口 TCP/8080,因此,我们将 Nginx 配置为代理。编辑 Nginx 配置文件 (/etc/nginx/nginx.conf) 并更改服务器配置,与以下类似:
Jenkins 通常使用端口 TCP/8080,并在安全组中将该端口向需要访问的计算机开放。
启动 Jenkins 和 Nginx 服务,并确保已将其配置为即便在重启后仍运行:
service jenkins start
service nginx start
chkconfig jenkins on
chkconfig nginx on
配置 EC2 实例上的 Git
确保您使用自己的电子邮件地址:
sudo -u jenkins git config --global credential.helper '!aws codecommit credential-helper $@‘
sudo -u jenkins git config --global credential.useHttpPath true
sudo -u jenkins git config --global user.email "email@domain.com"
sudo -u jenkins git config --global user.name (http://user.name/) "MyJenkinsServer"
解锁 Jenkins
将浏览器指向 EC2 实例的公开 DNS 名称(例如,http://ec2-54-221-39-132.compute-1.amazonaws.com/),此时您应该能够看到 Jenkins 主页和解锁说明:
在自定义 Jenkins 页面上,选择安装建议的插件。
等待一段时间,直到 Jenkins 安装所有建议的插件。此过程完成之后,已安装插件旁边将会显示复选标记。
在创建第一个管理员用户页面上,输入 Jenkins 用户的用户名、密码、全名和电子邮件地址。
选择保存并继续、保存并完成以及开始使用 Jenkins。
下载 Liquibase 并将其安装到 EC2 实例上
将 Liquibase Community 版本下载为 .zip 文件夹。使用 Putty 或任何其他 SSH 工具登录到 EC2 实例,然后移至 Jenkins 安装目录 cd /var/lib/Jenkins。
创建一个名为 liquibase 的文件夹,然后将 Liquibase .zip 文件夹的内容复制到此文件夹。目录应与以下所示类似:
下载 JDBC 驱动程序并将其安装到 EC2 实例上
安装 JDBC 驱动程序,以便 Liquibase 连接到 RDS 数据库。在本示例中,我们使用的是 Aurora PostgreSQL,因此,需要的是 PostgreSQL JDBC 驱动程序。
下载 JDBC JAR 文件并将其置于 Liquibase 文件夹中。目录应与以下所示类似:
创建用于部署和回滚的 Bash shell 脚本
Jenkins 将在后台调用这些脚本。这些 Bash shell 脚本将通过分配至 EC2 实例的 IAM 角色调用 Secrets Manager,以提取数据库凭证、运行 Liquibase 实用程序以及部署和回滚更改。
1.创建用于部署的脚本。请注意,此脚本为 PostgreSQL 专用。针对不同的数据库相应地更改驱动程序和 classpath。使用 vi 之类的编辑器创建此文件。
cd /var/lib/jenkins
vi callLiquibaseDemoDeployment.sh
export lquser=`aws secretsmanager get-secret-value --secret-id dbdevopsAuroraCreds --region us-east-1 | jq --raw-output .SecretString | jq -r ."username"`
export lqpassword=`aws secretsmanager get-secret-value --secret-id dbdevopsAuroraCreds --region us-east-1 | jq --raw-output .SecretString | jq -r ."password"`
export hostname=`aws secretsmanager get-secret-value --secret-id dbdevopsAuroraCreds --region us-east-1 | jq --raw-output .SecretString | jq -r ."host"`
export portnumber=`aws secretsmanager get-secret-value --secret-id dbdevopsAuroraCreds --region us-east-1 | jq --raw-output .SecretString | jq -r ."port"`
bash $JENKINS_HOME/liquibase/liquibase --changeLogFile=$1 --url=jdbc:postgresql://$hostname:$portnumber/devopsdb --username=$lquser --password=$lqpassword --driver=org.postgresql.Driver --classpath=$JENKINS_HOME/liquibase/postgresql-42.2.8.jar update
然后保存此脚本并退出编辑器。
2.创建使用 Count 进行回滚的脚本。请注意,此脚本为 PostgreSQL 专用。针对不同的数据库相应地更改驱动程序和 classpath。
cd /var/lib/jenkins
vi callLiquibaseDemoRollback.sh
export JENKINS_HOME=/var/lib/jenkins/
export lquser=`aws secretsmanager get-secret-value --secret-id dbdevopsAuroraCreds --region us-east-1 | jq --raw-output .SecretString | jq -r ."username"`
export lqpassword=`aws secretsmanager get-secret-value --secret-id dbdevopsAuroraCreds --region us-east-1 | jq --raw-output .SecretString | jq -r ."password"`
export hostname=`aws secretsmanager get-secret-value --secret-id dbdevopsAuroraCreds --region us-east-1 | jq --raw-output .SecretString | jq -r ."host"`
export portnumber=`aws secretsmanager get-secret-value --secret-id dbdevopsAuroraCreds --region us-east-1 | jq --raw-output .SecretString | jq -r ."port"`
bash $JENKINS_HOME/liquibase/liquibase --changeLogFile=$1 --url=jdbc:postgresql://$hostname:$portnumber/devopsdb --username=$lquser --password=$lqpassword --driver=org.postgresql.Driver --classpath=$JENKINS_HOME/liquibase/postgresql-42.2.8.jar rollbackCount $2
然后保存此脚本并退出编辑器。
步骤 3:为 EC2 实例创建 IAM 角色
为 EC2 实例创建一个 IAM 角色,以访问 CodeCommit 存储库和 Secrets Manager。
1.创建角色 JenkinsEC2DevopsRole。
2.将 AWS 策略 AWSCodeCommitPowerUser 附加到该角色。
3.创建自定义策略 SecretsManagerRead,以读取 Secrets Manager 中的密钥并将其附加到角色。此自定义策略的 JSON 与以下类似:
将角色 JenkinsEC2DevopsRole 附加到运行 Jenkins 的 EC2 实例。
步骤 4:使用 SES 为 Jenkins 设置 SMTP 服务器
1.登录到 SES 的 AWS 控制台,并将区域选择为 us-east-1。
2.导航至 SMTP 设置并单击创建我的 SMTP 凭证。此操作会将凭证下载到本地计算机;下一步骤需要使用此文件的内容。
3.通过浏览器登录到 Jenkins 并导航至管理 Jenkins、配置系统。
4.在系统管理员电子邮件地址中输入您选择的电子邮件地址,该地址用于发送 Jenkins 通知。此电子邮件地址应为经过 SES 验证的电子邮件地址。请参阅有关如何在 SES 中验证电子邮件地址的文档。
5.在电子邮件通知下输入 SMTP 服务器名称(例如,步骤 4.2 中的 email-smtp.us-east-1.amazonaws.com)。
6.单击高级按钮,然后再单击使用 SMTP 身份验证选项旁边的复选框。然后设置以下字段:
- 用户名:已下载的 SMTP 凭证中的用户名(步骤 4.2)
- 密码:已下载的 SMTP 凭证中的密码(步骤 4.2)
- 使用 SSL:取消选中此复选框
- SMTP 端口:587
6.单击通过向收件人发送测试电子邮件测试配置选项旁边的复选框,以检查电子邮件通知功能。输入有效的电子邮件 ID 并单击测试配置按钮,以查看是否会在配置的邮箱中收到一封测试邮件。请注意,收件人电子邮件地址应经过 SES 验证才会收到测试邮件。请参阅有关如何在 SES 中验证电子邮件地址的文档。
7.保存。
步骤 5:将数据库代码推送至 CodeCommit 存储库
在先决条件中,我提到了可通过 Git 客户端连接到 CodeCommit 存储库的本地计算机。在这里,我将不再详细介绍该主题,许多其他博文中均有介绍。请参阅 CodeCommit 文档,了解如何将文件推送至 CodeCommit 存储库。
对于 Liquibase,可以 SQL、XML 和 JSON 格式指定更改。在本示例中,我将演示 SQL 格式。以下屏幕截图所示为推送到存储库 DBDevopsDemoRepo 的主分支的 Liquibase 格式化 SQL 文件。文件名为 changeset.sql。此文件用于保留代码,以便部署到数据库。
如何针对 Liquibase 设置此文件的格式
Liquibase 格式化 SQL 文件使用注释为 Liquibase 提供元数据。每个 SQL 文件均必须以下面的注释开头:
格式化 SQL 文件中的每个更改集必须以下面的注释开头:
在 changeset.sql
中,您可以看到作者为公共并且使用任意 ID 3 来指定更改集编号。此 ID 是唯一的。这些值有助于跟踪数据库中的更改。
然后是要部署的 DDL:
create table test3 (
id int primary key,
name varchar(255)
);