skluck / terraform-plan-parser
HashiCorp Terraform计划的PHP解析器
Requires
- php: >=7.3
Requires (Dev)
- overtrue/phplint: ~1.1
- phpunit/phpunit: ~9.0
- squizlabs/php_codesniffer: ~3.4
README
Terraform Plan Parser
这是一个用于解析terraform plan输出的PHP库。
它将尝试解析出从terraform plan中修改的资源的变化属性以及从terraform init中使用的模块。
它支持Terraform 0.11和Terraform 0.12
Terraform 0.12支持计划文件的本地JSON输出,但这并不像stdout那样完整,因此我们仍需继续解析。
目录
用例
这个库将这个
Copying configuration from "git::https://git.example.com/terraform/module.git?ref=2.3.1"... Initializing modules... - module.fargate Getting source "./modules/fargate" Initializing provider plugins... - Checking for available provider plugins on https://releases.hashicorp.com... - Downloading plugin for provider "aws" (2.2.0)... An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: ~ update in-place -/+ destroy and then create replacement <= read (data resources) Terraform will perform the following actions: -/+ null_resource.promote_images (new resource required) id: "1236159896537553123" => <computed> (forces new resource) triggers.%: "1" => "1" triggers.deploy_job_hash: "6c37ac7175bdf35e" => "1a0bd86fc5831ee6" (forces new resource)
转换为这个
{
"changedResources": [
{
"action": "replace",
"name": "promote_images",
"fully_qualified_name": "null_resource.promote_images",
"module_path": "",
"is_new": true,
"is_tainted": false,
"attributes": {
"id": {
"name": "id",
"force_new_resource": true,
"old": {
"type": "string",
"value": "1236159896537553123"
},
"new": {
"type": "computed",
"value": null
}
},
"triggers.%": {
"name": "triggers.%",
"force_new_resource": false,
"old": {
"type": "string",
"value": "1"
},
"new": {
"type": "string",
"value": "1"
}
},
"triggers.deploy_job_hash": {
"name": "triggers.deploy_job_hash",
"force_new_resource": true,
"old": {
"type": "string",
"value": "6c37ac7175bdf35e"
},
"new": {
"type": "string",
"value": "1a0bd86fc5831ee6"
}
}
}
}
],
"modules": [
{
"name": "module.fargate",
"source": "./modules/fargate",
"version": null
},
{
"name": "root",
"source": "git::https://git.example.com/terraform/module.git",
"version": "2.3.1"
}
]
}
这个库受到了其他语言中类似库的启发和基于。如果您不使用PHP,可以查看它们
- lifeomic/terraform-plan-parser (typescript - cli)
- chrislewisdev/prettyplan (typescript - 基于浏览器的)
安装
此包需要PHP 7.1或更高版本。CI工作流程测试了PHP 7.1、7.2和7.3。它没有运行时依赖。
使用composer下载此包
composer require skluck/terraform-plan-parser ~1.1
用法
<?php use SK\TerraformParser\TerraformOutputParser; use SK\TerraformParser\Terraform11OutputParser; use SK\TerraformParser\Terraform12OutputParser; $filename = '/path/to/terrraform/output'; $parser = new TerraformOutputParser; // It is also possible to use the desired version of Terraform directly: // $parser = new Terraform11OutputParser; // $parser = new Terraform12OutputParser; $output = $parser->parseFile($filename); var_export($output); // [ // 'errors' => [ // 'Failed to parse resource name (line 63)', // 'Failed to parse attribute name (line 102)', // 'Failed to parse attribute name (line 103)', // ], // 'changedResources' => [ // ResourceChange, // ResourceChange, // ResourceChange, // ], // "modules": [ // { // "name": "module.mymodule", // "source": "./path/to/submodule", // "version": null // }, // { // "name": "root", // "source": "git::https://git.example.com/terraform/mymodule2.git", // "version": "2.3.1" // } // ] // ];
此解析器的输出还实现了jsonSerialize,因此可以安全地编码并使用JSON输出。
<?php use SK\TerraformParser\TerraformOutputParser; $filename = '/path/to/terrraform/output'; $contents = file_get_contents($filename); $parser = new TerraformOutputParser; $output = $parser->parse($contents); echo json_encode($output, JSON_PRETTY_PRINT); // { // "errors": [ // "Failed to parse resource name (line 63)", // "Failed to parse attribute name (line 102)", // "Failed to parse attribute name (line 103)" // ], // "changedResources": [ // ResourceChange, // ResourceChange, // { // "action": "create", // "name": "test2", // "fully_qualified_name": "module.test1.module.test2.null_resource.test2", // "module_path": "test1.test2", // "is_new": true, // "is_tainted": false, // "attributes": { // "triggers.deploy_job_hash": { // "name": "triggers.deploy_job_hash", // "force_new_resource": true, // "old": { // "type": "string", // "value": "6c37ac7175bdf35e" // }, // "new": { // "type": "computed", // "value": null // } // } // } // } // ], // "modules": [ // { // "name": "module.mymodule", // "source": "./path/to/submodule", // "version": null // }, // { // "name": "root", // "source": "git::https://git.example.com/terraform/mymodule2.git", // "version": "2.3.1" // } // ] // }
数据结构
解析terraform plan的响应将始终是以下结构的数组
{
"errors": array<string>
"changedResources": array<ResourceChange>
"modules": array<[name: string, source: string: version: ?string]>
}
解析器可能成功地解析了一些资源,但仍包含其他资源的错误。因此,您应该检查errors和changedResources以确定您的失败状态。通常,我会建议仅在errors非空时失败,并且changedResources为空,或者如果errors包含大量消息时。
关于模块的特别说明
此解析器将尝试从Terragrunt输出中找到“根”模块。如果主要模块来自远程源(例如git或Terraform注册表)或本地目录,这可能很重要。
ResourceChange
这代表了Terraform中的单个资源,其结构如下
-
$resourceChange->action(): string正在对资源执行的操作,例如
创建、销毁、替换、更新或读取。 -
$resourceChange->name(): string在Terraform代码中为资源指定的名称。
-
$resourceChange->type(): stringterraform资源的类型,例如
aws_s3_bucket。 -
$resourceChange->fullyQualifiedName(): string资源的完整正确Terraform路径,它将与Terraform状态中的路径相匹配。
-
$resourceChange->modulePath(): string仅包括模块的路径,不包括资源类型或名称。
- 示例完整路径:
module.mymodule1.module.mymodule2.aws_s3_bucket.mybucket - 模块路径:
mymodule1.mymodule2
- 示例完整路径:
-
$resourceChange->isTainted(): string如果资源被污染,导致它被重新创建。
-
$resourceChange->isNew(): string如果资源是新的(对于Terraform 0.12始终为false)。
-
$resourceChange->attributes(): array该资源的属性列表(见下文)。
AttributeChange
这代表资源上的单个属性。解析器将确定属性的类型,并在可能的情况下确定该属性的旧值和新值。
-
$attrChange->name(): string由Terraform资源确定的属性名称(请参阅您的Terraform提供者文档)。
-
$attrChange->forceNewResource(): bool此属性是否是资源重新创建的原因。
-
$attrChange->oldValue(): ?array可能为null,或包含
type和value的数组。
对于多行块、映射、列表和字符串,value始终为null。type的可能值未知已计算null数字布尔值字符串列表映射块
-
$attrChange->oldValue(): ?newValue见上文。