“功能分支的优势在于,每个开发人员都可以使用自己的功能,并且不受其他地方进行的更改的影响。” ( FeatureBranch )
Feature分支已经存在很长时间了,并且是开发团队中的常见做法。 没有他们,我无法想象一个团队的发展。 如果有人要我与正在使用其他功能的同事共享分支机构,这似乎很荒谬。 只是这个想法让我不舒服。 很容易看出,功能分支提供的隔离也是测试应用程序所需要的。 更具体地说-测试其集成。
保持运行代码隔离非常容易,您可以在本地运行所有代码。 我已经在几乎所有使用过的计算机上安装了MySQL和Redis。 但是,随着我们的应用程序逐渐依赖于托管服务(例如Cognito和BigQuery),在本地运行100%成为一个问题。 可以模拟或模仿这些服务,但它们的行为绝不会像原始服务那样。 此外,应经常且早地测试这些集成,因为应用程序的边界往往是我们感到惊讶的地方,也是事情破裂的地方 。
营救环境
因此,如果我们要针对真实的云服务测试应用程序,为什么我们不能共享?
实际上这在小范围内有效。 例如,每个开发人员都在本地运行其代码,每个人都使用专用的S3存储桶,该存储桶具有不同的文件夹以隔离使用情况。 但是您不必费神就可以打破这种局面。 如果我们正在使用SQS队列怎么办? 我的本地应用程序会将消息推送到该队列中,而只是让同事的本地应用程序提取该消息。 这正是我们要避免的中断类型。 我们每个人都应该使用自己的队列,并从那里推断我们自己的环境 。
首先,为每个功能分支或每个拉取请求运行环境都取决于您如何感知CD管道。 不要把它想成“ 这个部署 环境 ”,但“ 本次部署 的 环境 ”。 您只需要给它起一个名字即可。 这可能是“ 生产 ”或“ 登台 ”,但也可能是“ 功能蓝色按钮 ”的“ pr1017 ”。 您的CD流程需要适用于现有环境以及新环境。 这就是Terraform真正的光芒所在。
因为Terraform使用声明性方法,所以它负责确定环境是新环境还是需要创建,或者环境是否存在并且需要更新。 Terraform的另一个关键功能是工作区 ,它可以隔离不同环境之间的状态(在以前的版本中甚至称为“环境”)。 您的Terraform代码将需要使用变量$ {terraform.workspace},以确保您的资源专用于您所处的环境。
一个有效的例子。
我们将使用一个非常简单的设置进行工作,以说明此流程。 我们将从一个S3存储桶开始,该存储桶作为网站公开,其中包含一个简单的HTML文件:
locals {environment_name = terraform.workspace
}
resource “aws_s3_bucket” “website_bucket” {bucket = “ ${local.environment_name} .feature.environment.blog.com”acl = “public-read”force_destroy = truewebsite {index_document = “index.html”}
}
请注意,我们如何从Terraform工作空间名称创建本地变量,并使用该变量为存储桶赋予每个环境唯一的名称。
我们的“ CD进程”将是一个简单的bash文件,它接受环境名称作为参数:
echo “Deploying environment $ENVIRONMENT ”
echo “Injecting env vars”
sed ‘s/!!!ENVIRONMENT!!!/’” $ENVIRONMENT ”’/g’ index.template.html > $ENVIRONMENT .index.html
echo “Applying Terraform”
terraform init
echo “Selecting/creating workspace”
terraform workspace select $ENVIRONMENT || terraform workspace new $ENVIRONMENT
terraform apply
在这里,我们 -
- 将环境名称注入到html文件中,该文件将用作我们的静态站点。
- 选择/创建一个以我们的环境命名的Terraform工作空间。
- 应用环境。
(您可以在 https://github.com/env0/feature-environments-blog-code中 找到完整的示例 )
让我们运行它!
运行./apply.sh env1
将部署一个名为env1的环境。 Terraform将初始化,向我们展示将要执行的操作(Terraform计划),并且在部署所有内容之后,将输出网站的端点。 如果我们进入该网站-我们会看到类似的内容-
让我们尝试再次运行该命令,这次是针对另一个环境。 我们将运行./apply.sh my-other-env
,我们将获得一个指向如下所示网站的链接:
更新中
为了更新我们的环境,我们要做的就是再次使用相同的环境名称运行apply.sh。 我们的代码和Terraform将认识到我们正在现有的环境中工作,并将相应地对其进行更新。
毁灭
当分支被合并和删除时,就不需要这种环境了,我们绝对不想继续为此付费。 为了破坏该特定环境,我们只需要运行-
> terraform workspace select $ENVIRONMENT
> terraform destroy
Terraform将请求批准,然后从那里获得批准。 不过要小心,因为这些猫的照片不容易找到;)
自动化
拥有要素环境的下一步也是最后一步,就是使它们自动化。 这是非常有益的自动化操作,您的工程师将感谢您为他们打开的每个分支/ PR都获得专用的隔离环境。 您可以获取上面显示的apply.sh文件的某个版本,并将其放入管道中(GH操作,Circle,Jenkins等)。 只要确保您还记得分支/ PR关闭时的销毁部分即可。
功能环境的乐趣
从env0开始 ,我们从第一天开始就使用功能环境。 我们打开的每个PR都运行自己的环境。 这确实有助于我们尽早且不间断地测试我们的整个应用程序。 我们通常也使用它来展示开发中的功能,这确实有助于早日获得反馈。 这也是在开发过程的早期开放PR的另一个诱因,这是分享我们正在从事的工作的好方法。 每个开发人员每个月运行大约20个环境,平均环境寿命约为1.5天。
从博客文章到现实世界
我想请您对上述所有内容一视同仁-此代码实际上是一个过于简化的示例,旨在说明工作流程。 随着软件的发展,使它“在野外”运行通常要复杂得多。 使Terraform自动化和管理云环境并不是一件容易的事,并且大多数CI / CD工具都可以运行一次任务,而不是管理生命周期更长的“环境”。
这就是为什么我们创建了env0 (一个完整的环境即服务解决方案)的原因,该解决方案旨在为您的开发人员提供他们所需的动态基础架构,而不会损害组织控制和管理云资源使用方式的需求。 请访问www.env0.com 。
下一步 -
正如我上面所写的那样,功能完善的环境很少像上面的示例那样简单。 所以在这一点上,您可能会问各种各样的问题-
- 听起来很贵! 有什么方法可以使其更便宜?
- 让每个人都可以访问部署基础架构可能会变得混乱—如何控制我的云使用量?
- 我已经有Terraform代码-但它运行静态环境。 使它动态化的步骤是什么?
如果您想进一步了解上述内容,请在评论中让我知道,我将尝试写一篇后续文章。
谢谢阅读!
先前发布在https://medium.com/env0/from-feature-branches-to-feature-environments-with-terraform-652c0fdf0e78
From: https://hackernoon.com/from-feature-branches-to-feature-environments-with-terraform-10973ycb