terraformpy是一个库和命令行工具,可以使用成熟的python环境来增强terraform配置!

terraformp的Python项目详细描述


地形

terraformpy是一个库和命令行工具,可以使用成熟的python环境来增强terraform配置!

terraform是一个很棒的工具。就像,真的很神奇。当使用管理第三方服务定义的代码,并通过调用api将更改实际应用于这些定义时,必须对更改过程有高度的信心,这就是terraform的优势所在。它所赋予的工作流程允许团队在多个供应商/地区/技术等领域的巨大(且不断增长)足迹中快速进行更改。

但是,随着定义的增长,hcl语法很快就留下了很多需要改进的地方,而且是不是太冗长了……那么多变量和输出的定义需要重复,一遍又一遍地重复,因为您组成了更多的模块,使用每个模块其他,

由于hcl是"完全兼容json的",python擅长生成json数据,因此我们构建terraformpy是为了提供一个更高效的环境来构建和维护复杂的terraform配置。自2016年以来,它每天都在Nerdwallet的 Nerdwallet 生产中使用,在加快我们整个工程组织对Terraform的采用方面证明非常有价值。

安装TerraFormPy

安装和使用terraformpy的推荐方法是通过pipenv

例如:

$ mkdir my-terraform-project
$ cd my-terraform-project
$ pipenv install --two terraformpy

然后可以使用pipenv run运行terraformpy

$ pipenv run terraformpy ...

或者可以使用pipenv shell激活virtualenv,这样就不需要使用pipenv run。本文档的其余部分假设您已经运行了pipenv shell,并且可以直接运行terraformpy。

使用cli工具

terraformpy 命令行工具用作底层 terraform 工具的填充程序。调用时,它将首先在当前目录中找到所有 *.tf.py 文件,使用 imp 模块加载它们,生成名为 main.tf.json 的文件,然后调用底层工具。

# just replace terraform in your regular workflow
terraformpy plan -out=tf.plan

# review changes...
# apply them!
# since we're going to operate on the generated plan here, we don't event need to use terraformpy anymore
terraform apply tf.plan

每个 *.tf.py 文件都使用声明性语法,使用从该库导入的对象。您不需要定义主函数,只需在模块的根目录中创建类的实例(匿名的或其他的)(您正在这里构建常规的python代码)。由于您处于一个成熟的python环境中,因此您可以做的事情没有限制—导入内容、连接到数据库等。

正在写入文件

terraformpy的名称空间提供了许多类,它们直接映射到您在normal .tf. 文件中声明的内容。要编写定义,只需导入这些类并开始创建它们的实例。下面是 terraform入门指南中的第一个示例

fromterraformpyimportProvider,ResourceProvider('aws',profile='default',region='us-east-1')Resource('aws_instance','example',ami='ami-2757f631'instance_type='t2.micro')

可以从terraformpy导入的内容

  • 提供商
  • 变量
  • 数据
  • 资源
  • 输出

有关完整的功能示例,请参见 示例/ 目录。

插值

到目前为止,我们只匿名使用了terraformpy,但是返回的 data resource 类实例提供了方便的插值属性。例如,一个常见的任务是使用 data 类来获取远程数据:

αααα5

在这里,我们只需在创建 aws\u实例时引用ami对象的id属性。在编译阶段,它将被转换为正确的语法: "${data.aws\u ami.ecs\u ami.id}"

这是通过在我们的 数据 资源 对象上有一个自定义的 \getattr 函数来实现的,该函数将把对不存在的属性名的任何属性访问转换为terraform插值语法。

模块

模块被明确地排除在这个实现之外,因为它们的目标是解决相同的问题——在TerraForm配置中构建可重用的块。

利用python的所有特性,不使用terraform中的本机模块就可以直接构建可重用单元,但是请参阅资源集合(下一页)中的一些帮助程序脚手架!

资源集合

在使用python构建configs时,一个常见的模式是希望在单个对象的伪装下抽象出许多不同的资源,这与本地terraform模块要解决的模式是相同的。在terraformpy中,我们为构建表示多个资源的对象提供了一个资源集合基类。

您可以使用 示意图来定义字段并执行验证。

例如,在配置rds集群时,您可能需要一组标准的选项,这些选项随集群一起提供。您可以通过资源集合来表达这一点:

fromschematicsimporttypesfromschematics.typesimportcompoundfromterraformpyimportResource,ResourceCollectionclassRDSCluster(ResourceCollection):# Defining attributes of your resource collection is like defining a Schematics Model, in fact the# ResourceCollection class is just a specialized subclass of the Schematics Model class.## Each attribute becomes a field on the collection, and can be provided as a keyword when constructing# an instance of your collection.## Validation works the same as in Schematics.  You can attach validators to the fields themselves and# also define "validate_field" functions.name=types.StringType(required=True)azs=compound.ListType(types.StringType,required=True)instance_class=types.StringType(required=True,choices=('db.r3.large',...))# The create_resources function is invoked once the instance has been created and the kwargs provided have been# processed against the inputs.  All of the instance attributes have been converted to the values provided, so# if you access self.name in create_resources you're accessing whatever value was provided to the instancedefcreate_resources(self):self.param_group=Resource('aws_rds_cluster_parameter_group','{0}_pg'.format(self.name),family='aurora5.6',parameter=[{'name':'character_set_server','value':'utf8'},{'name':'character_set_client','value':'utf8'}])self.cluster=Resource('aws_rds_cluster',self.name,cluster_identifier=self.name,availability_zones=self.azs,database_name=self.name,master_username='root',master_password='password',db_cluster_parameter_group_name=self.param_group.id)self.instances=Resource('aws_rds_cluster_instance','{0}_instances'.format(self.name),count=2,identifier='{0}-${{count.index}}'.format(self.name),cluster_identifier=self.cluster.id,instance_class=self.instance_class)

然后可以导入该定义并在terraformpy配置中使用。

frommodules.rdsimportRDSClustercluster1=RDSCluster(name='cluster1',azs=['us-west-2a','us-west-2b','us-west-2c'],instance_class='db.r3.large')# you can then refer to the resources themselves, for interpolation, through the attrs# i.e. cluster1.cluster.id

变型

存在于许多不同环境中的资源定义通常在每个环境之间仅略有不同。为了便于对这些差异进行定义,您可以使用变体分组。

首先创建文件夹: configs/stage/ configs/prod/ configs/shared/ 。在每一个包里放一个初始化包。

接下来创建文件configs/shared/instances.py

fromterraformpyimportResourceResource('aws_instance','example',ami=ami.id,prod_variant=dict(instance_type='m4.xlarge'),stage_variant=dict(instance_type='t2.medium'))

然后创建configs/stage/main.tf.py

fromterraformpyimportVariantwithVariant('stage'):importconfigs.shared.instances

由于实例文件的导入是在variant上下文中进行的,因此资源将被创建,就好像它被定义为:

$ mkdir my-terraform-project
$ cd my-terraform-project
$ pipenv install --two terraformpy
0

多个提供商

根据您对terraform的使用情况,您可能最终需要在某个时间点使用多个提供者。要使用terraform中的多个提供者,请使用别名定义它们,然后在资源定义中引用这些别名。

为了简化此模式,您可以将terraformpy provider 对象用作上下文管理器,然后在上下文中创建的任何资源都将自动引用该提供程序别名:

$ mkdir my-terraform-project
$ cd my-terraform-project
$ pipenv install --two terraformpy
1

使用文件内容

通常情况下,您会希望包含位于python代码旁边的文件的内容,但是当运行terraform和插值函数路径时,将与编译后的主文件所在的位置而不是python代码所在的位置相关。

为了帮助解决这种情况,在terraformpy.helpers中提供了一个名为 relative_file 的函数。

$ mkdir my-terraform-project
$ cd my-terraform-project
$ pipenv install --two terraformpy
2

这将产生一个定义,该定义利用 ${file(…)} 插值函数和一个从定义角色的python代码所在的同一目录读取 role\u policy.json 文件的路径。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
Maven中的java,为什么要运行“mvn clean”?   java会降低图像质量。OutOfMemory异常Android   在Java8中将函数传递到流的过滤方法   jboss6。x java。lang.NoClassDefFoundError,当我将<listenerclass>包含到web时。xml java   java读取图像像素时,像素Alpha始终为255   java在迭代后跳过一行   java如何创建我自己的单链表   意图上的java空指针异常。getStringExtra.:安卓   具有连接实体的java Hibernate onetoone映射   java需要帮助在自制的仓鼠模拟器上实现启动/恢复/暂停/停止线程操作   如何测试非主方法?[Java,IntelliJ]   java jdbc自动提交(false)不起作用   java在JADE中的同一容器中创建多个代理   java OkHttp获取失败的响应正文   java Webdriver flash按钮