AWS标记最佳实践第2部分:TerraForm和CloudForm

2020-08-27 02:38:41

一旦您采用了AWS标记策略,您将需要确保您现有的所有AWS资源以及您创建的任何新资源都遵守该策略。一致性是关键-如果您不主动执行您的AWS标记策略,您将总是在追赶和追赶团队成员,以确保他们向其资源添加正确的标记。

虽然您可以使用AWS CLI或AWS Tag Editor手动将AWS标记应用于您的资源,但您可能会发现这在规模上很麻烦且容易出错。更好的方法是自动将AWS标签应用于您的资源,并使用规则强制其一致使用。

根据您用来在AWS上维护基础设施的工具,您在新资源上主动实施AWS标签的方法可能会有所不同。在本指南中,我将重点介绍两个工具:TerraForm和AWS CloudForment。您将了解如何使用每个标签来创建和更新资源上的AWS成本分配标签,然后强制正确使用新资源的特定标签。通过主动实施您的AWS标记策略,您将最大限度地减少审核和更正不正确的AWS标记所花费的时间,并迫使开发人员了解适合您环境的最佳AWS标记最佳实践。

我将介绍的第一个基础设施管理工具是Terraform。TerraForm可与各种云托管提供商协作,帮助您调配和维护您的AWS资源。使用Terraform,您可以用代码定义您的服务器、数据库和网络,并以编程方式将您的更改应用到您的AWS帐户。

如果您是Terraform的新手,他们在GitHub上有一个文档齐全的入门指南和几个AWS模板示例。在本节中,我将向您展示GitHub上提供的演示Terraform项目和模块的一些片段。您将在此Terraform AWS标签中了解以下内容:

如果要使用Terraform部署具有AWS标签的EC2实例,则您的配置可能包括以下内容:

Resource";aws_instance";";cart";{connection{type=";ssh";user=";ubuntu";host=self.public_IP private_key=file(var.private_key_path)}instance_type=";t2.micro";AMI=var.aws_amis[var.aws_region]key_name=aws_key_pair.auth.key_name vpc_security_group_ids=[aws_security_group.default.id]子网id=aws_subnet.default.id Provisioner";remote-exec";{inline=[";sudo apt-get-y update";,";sudo apt。,]}标签={Contact=";j-mark";env=";dev";service=";cart";}}。

上面的示例包括三个AWS成本分配标记:Contact、env和service,值描述为字符串。应用此配置时,Terraform将连接到AWS并部署具有您指定的AWS标签的EC2实例。

TerraForm使得使用AWS标签以可逆且一致的方式更新现有资源变得容易。如果您使用AWS标记来跟踪资源的联系人(例如,上例中的J-mark),则可能需要在团队成员离职或更换角色时更新AWS标记。

要更新资源上的AWS标记,只需在您的Terraform配置中更新相应的标记即可。新标记将覆盖以前分配给资源的任何标记,包括添加到Terraform外部的标记。

例如,要更改上面EC2实例上的联系成本分配标记,您可以使用以下内容更新上面的标记块:

当您应用此配置时,AWS标签将在AWS控制台中自动更新:

如果您将您的Terraform配置文件保存在版本控制中(这可能是一个好主意),您将能够看到标签是如何随着时间的推移而改变的。您还可以使用与应用程序代码相同的代码审查过程来审查更改,以帮助您捕获标记策略执行过程中的错误。

随着基础设施的发展,代码审查过程可能不足以防止不正确的AWS标记。幸运的是,您可以在Terraform中使用变量和自定义验证规则强制执行AWS标记名和值。

在上面的示例中,标记列表被硬编码到EC2实例定义中。更具伸缩性的模式是将EC2实例模板拆分成自己的模块,并使用标记变量。然后,您可以编写自定义验证规则来检查标记是否符合您的策略。

变量";标签";{description=";此资源的标签。";验证{Condition=Length(var.tag)>;0&;&;包含([";j-mark";,";l-duke";],var.tags.Contact)&;&;var.tags.env!=null&;&;包含([";cart";,&#。,";Cart:Search";],var.tags.service)ERROR_MESSAGE=";应用的资源标签无效。";}}

现在,当您运行带有缺失或无效标签的Terraform Plan时,会出现错误:

您的规则可以在Terraform的配置语言允许的范围内尽可能复杂,因此regex()、substr()和DISTINCT()等函数都是可用的。这就是说,对这种方法有一些警告。

首先,自定义变量验证是Terraform中的一个实验性特性。实验要素可能会发生变化,这意味着您可能需要密切关注Terraform更新规则。要启用VARIABLE_VALIDATION,请将以下内容添加到您的Terraform块中:

其次,Terraform的变量验证仅在基础设施生命周期的Terraform规划阶段进行。它不能防止用户直接在AWS控制台中意外更改您的标签,而且效果取决于您编写的验证规则。如果您开始使用新资源,但忘记添加验证规则,最终可能会得到许多不符合您的标记策略的资源。

付费Terraform Cloud客户的另一个选择是Sentinel,它允许您为您的资源创建自定义策略。我不会在这里介绍此方法,但是Terraform已经创建了一个示例策略来向您展示如何强制执行强制AWS标签。

与Terraform类似,AWS CloudFortification允许您根据配置文件调配AWS资源。与Terraform不同,CloudForment是亚马逊产品的一部分,因此如果您想使用其他基础设施提供商,它不一定会对您有所帮助。在CloudFortification中标记资源的方法类似于Terraform使用的方法,但是正如您将看到的,配置格式是不同的。

如果您不熟悉AWS CloudFortification,亚马逊的官方演练将帮助您开始部署一些基本模板。在本节中,我将向您展示演示AWS CloudFortification模板中的一些片段,该模板也可以在GitHub上获得。您将在此Terraform AWS标记部分了解以下内容:

AWS CloudForment旨在使用单个模板文件轻松创建AWS资源。使用CloudFortification模板,可以使用AWS标签部署的每个资源。

例如,要使用上面的Terraform示例中使用的三个相同的AWS标记创建新的EC2实例,请将标记数组添加到资源的属性块中:

";资源";:{";WebServerInstance";:{";类型";:";AWS::EC2::实例";,";元数据";:{...},";属性";:{";标记";:[{";键";:";联系人";,";值";:";j-mark";},{";key";:";env";,";value";:";dev";},{";key";:";service";,";value";:";cart";}],...}},...},

使用AWS CLI,您可以将此CloudFortification模板部署为新堆栈。这将确保您的模板有效,并使用其在AWS上的标签创建指定的资源:

如果您的模板中有很多类似的资源,您可以使用带有create-stack或update-stack命令的--tag标志一次将AWS标记部署到堆栈中的所有资源:

#使用标记锯创建堆栈-堆栈--模板正文file://path/to/your/template.json--堆栈名称=<;您的堆栈名称&>--Tags=";Key=env,Value=dev;#使用标记锯云表单更新-堆栈-模板-正文file://path/to/your/template.json--堆栈名称=<;您的堆栈名称&--Tags=";Key=env,Value=dev;更新堆栈。

如果您想要更改上面创建的EC2实例上的联系人,只需更改模板文件的标记部分,然后使用[update-stack](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/cloudformation/update-stack.html)命令部署您的更改。

当您更新模板文件外部的标签时,AWS CloudForment的行为与Terraform的行为相同。手动设置的任何标记都将被update-stack命令覆盖,因此请确保团队中的每个人都通过CloudFortification部署标记。

AWS提供组织标记策略和配置管理规则来帮助您查找标记不正确的资源,但这两种工具都无法阻止您创建缺少标记或无效标记的资源。主动实施标记策略的一种方法是使用CloudForformationLinter。

Cfn-lint是一个命令行工具,可确保您的AWS CloudFortification模板格式正确。它检查JSON或YAML文件的格式、输入的正确类型以及数百个其他最佳实践。虽然默认情况下不检查特定标记的存在,但您可以在Python中编写自定义规则来执行此操作。

例如,如果要确保您的CloudForformationWeb服务器遵循与上面的Terraform示例相同的规则,并且具有:

From cfnlint.ules从cfnlint.ules导入CloudFormationLintRulefrom cfnlint.ules导入RuleMatchclass TagsRequired(CloudFormationLintRule):id=';E9000';Shordesc=';标记已正确设置;description=';检查WebServerInsta';def Match(Self,CFN)的所有标记规则:Matches=[]Approved_Contacts=[&。]WEB_SERVERS=[x for x in cfn.search_deep_keys(';WebServerInstance';)if x[0]==';Resources';]对于WEB_SERVERS中的WEB_SERVER:Tags=web_server[-1][';Properties';][';Tags';]If Not Tags:Message=";所有资源必须至少有一个标记";Matches.append(RuleMatch(web_server,message.format()If Not Next((x表示x in tag if x.get(';key';)==';env';),None):message=";所有资源在标签中必须有';env';tag";matches.append(RuleMatch(web_server,message.format()。如果tag.get(';key';)==';service';和tag.get(';value';)不在VALID_SERVICES:message=";中,则联系人必须是批准的联系人";matches.append(RuleMatch(web_server,message.format()如果tag.get(';key';)==';service';和tag.get(';value';)不在VALID_SERVICES:MESSAGE=";服务必须是。Matches.append(RuleMatch(web_server,message.format()返回匹配。

使用LINTING验证您的AWS CloudFortification规则是主动实施您的AWS标签的好方法。如果您将CloudFortification模板存储在版本控制中,则可以使用预提交钩子或将其作为持续集成工作流的一部分来运行cfn-lint。

因为这些规则是用Python编写的,所以您可以根据需要将其复杂化,但它们也有缺点。与Terraform的自定义变量验证一样,linting规则不会告诉您不受CloudFortification管理的资源中存在的问题,因此当它们与反应式标签审计和调整策略结合使用时效果最好。

正确标记的资源将帮助您预测和控制您的成本,但是您的标记策略不能仅仅是被动的。拥有主动实施的模式将需要前期投资,但从长远来看将为您节省时间和金钱。

一旦你采用了标记策略和主动实施方法,当你落后的时候,最后一块拼图就是迎头赶上。在本指南的最后部分,您将了解如何审核和查找标记错误的资源,以确保您的标记策略在未来继续取得成功。

如果您有兴趣获得标记方面的帮助,请联系我们的CTO:[email protected],接收免费的标记合规性报告。