跳转到主要内容

简单的Terraform测试辅助工具

项目描述

Python Test Helper for Terraform

此简单辅助工具通过包装Terraform可执行文件并公开便利方法来设置固定装置、执行Terraform命令和解析它们的输出,从而便于从Python单元测试中测试Terraform模块。

它允许进行不同类型的测试:仅使用Terraform initplan 进行轻量级测试,以确保代码在语法上正确,应该创建正确数量和类型的资源,或者运行完整的 apply/output/destroy 循环的完整测试,然后可以用来测试实际创建的资源或状态文件。

作为额外的便利,该模块还提供了请求和访问计划输出(通过 terraform plan -outterraform show)和输出(通过 terraform output -json)的简单方法,并返回简单类中包装的它们,从而简化访问其属性。

此模块深受两个项目的启发:用于测试Terraform的轻量级方法的 Terratest 和将Terraform命令包装在Python中的 python-terraform

示例用法

test” 文件夹包含如何使用合成固件(计划输出的简单表示和输出文件)或最小根模块来为 planapply 编写测试的简单示例。更多示例可以在 Cloud Foundation Fabric 存储库中找到,该模块为此模块开发。

这是一个使用实际模块的计划输出进行的测试。

import pytest
import tftest


@pytest.fixture
def plan(fixtures_dir):
  tf = tftest.TerraformTest('plan', fixtures_dir)
  tf.setup(extra_files=['plan.auto.tfvars'])
  return tf.plan(output=True)


def test_variables(plan):
  assert 'prefix' in plan.variables
  assert plan.variables['names'] == ['one', 'two']


def test_outputs(plan):
  assert sorted(plan.outputs['gcs_buckets'].keys()) == plan.variables['names']


def test_root_resource(plan):
  res = plan.resources['google_project_iam_member.test_root_resource']
  assert res['values']['project'] == plan.variables['project_id']


def test_modules(plan):
  mod = plan.modules['module.gcs-buckets']
  res = mod.resources['google_storage_bucket.buckets[0]']
  assert res['values']['location'] == plan.variables['gcs_location']

Terragrunt 支持

Terragrunt 的支持实际上遵循了瘦 TerraformTest 包装器的相同原则。

请参阅以下示例了解如何使用它

import pytest
import tftest


@pytest.fixture
def run_all_apply_out(fixtures_dir):
  # notice for run-all, you need to specify when TerragruntTest is constructed
  tg = tftest.TerragruntTest('tg_apply_all', fixtures_dir, tg_run_all=True)
  # the rest is very similar to how you use TerraformTest
  tg.setup()
  # to use --terragrunt-<option>, pass in tg_<option in snake case>
  tg.apply(output=False, tg_non_interactive=True)
  yield tg.output()
  tg.destroy(auto_approve=True, tg_non_interactive=True)

  
def test_run_all_apply(run_all_apply_out):
    triggers = [o["triggers"] for o in run_all_apply_out]
    assert [{'name': 'foo', 'template': 'sample template foo'}] in triggers
    assert [{'name': 'bar', 'template': 'sample template bar'}] in triggers
    assert [{'name': 'one', 'template': 'sample template one'},
            {'name': 'two', 'template': 'sample template two'}] in triggers
    assert len(run_all_apply_out) == 3

缓存

TerraformTestsetupinitplanapplyoutputdestroy 方法可以将关联输出缓存到本地的 .tftest-cache 目录。对于后续方法调用,可以返回缓存值而不是调用实际的底层 terraform 命令。使用缓存值可以比再次运行 Terraform 命令快得多,特别是如果该命令时间消耗很大。

要确定是否应使用缓存,首先会使用当前 TerraformTest 实例的 __init__ 和调用方法参数、tfdir 的文件内容以及任何 tf_var_fileextra_files 方法参数的文件内容生成哈希值。将哈希值与缓存实例关联参数的哈希值进行比较。如果哈希值相同,则使用缓存,否则执行方法。

缓存功能的优点包括

  • 测试期间设置时间更快,因为这些 terraform 模块在测试会话之间没有变化
  • 编写测试时无需担心测试代码中的错误导致 Terraform 设置逻辑再次运行

请参阅以下示例了解如何使用它

import pytest
import tftest


@pytest.fixture
def output(fixtures_dir):
  tf = tftest.TerraformTest('apply', fixtures_dir, enable_cache=True)
  tf.setup(use_cache=True)
  tf.apply(use_cache=True)
  yield tf.output(use_cache=True)
  tf.destroy(use_cache=True, **{"auto_approve": True})


def test_apply(output):
  value = output['triggers']
  assert len(value) == 2
  assert list(value[0].keys()) == ['name', 'template']
  assert value[0]['name'] == 'one'

兼容性

从版本 1.0.0 开始,需要 Terraform 0.12,并且使用此模块的先前版本编写的测试不兼容。请参阅 CHANGELOG.md 文件以获取有关更改的详细信息。

测试

测试使用 pytest 框架,除了对 Terraform 二进制文件之外没有其他依赖项。开发期间使用的版本在 DEV-REQUIREMENTS.txt 文件中。

免责声明

这不是一个官方支持的 Google 产品。

项目详情


下载文件

下载适用于您的平台的文件。如果您不确定要选择哪个,请了解有关 安装包 的更多信息。

源分布

tftest-1.8.5.tar.gz (22.9 kB 查看散列值)

上传时间 源码

构建分发版

tftest-1.8.5-py3-none-any.whl (16.0 kB 查看散列值)

上传时间 Python 3

由以下支持