How to automatically import infrastructure into Terraform?

What is Terraform?

Terraform CLI is a tool that generates based on the existing infrastructure (reverse Terraform) tf/jsonand tfstatefiles.

Terraformer uses Terraform providers and is designed to easily support newly added resources. To upgrade resources with new fields, you only need to upgrade the related Terraform provider.

I will review the exact same scenario I have experienced so that you can see exactly how easy it is to import using Terraform.

Why import existing infrastructure?

Before the text begins, we need to talk about this topic first. Like other things in life, sometimes it is impossible to plan for the future. Without adequate planning for infrastructure creation, it may lead to time pressure, emergency release, or manual infrastructure creation, and Terraform has never been used in the first place.

Example: A resource has been defined and I want to inform the status that the resource already exists.

Imagine that if there is a problem in production, changes must be made quickly to prevent downtime. Manually add changes in route53 to add DNS records.

Once things are stable, the same record will be defined as a Terraform resource, but when the application is running, a message will be returned stating that the resource already exists, which will cause the application phase to fail.

In this case, all you need to do is to import the state of the existing resources so that the next time you run the Terraform application, the Terraform software will consider the resources in their state. In the future, this means that any changes made will be treated as modifications rather than additions.

In this hypothetical situation, let us assume that the following resources were created from the AWS console:

Route53 Record Set Name: www.mywebsite.com.
Route53 Record Set Type: CNAME
Route53 Record Set Value: mywebsite.com

Now, since these three resources are very simple and you know what was created, you can add them to the Terraform project:

resource aws_route53_record www {
name = "www.mywebsite.com"
type = "CNAME"
zone_id = aws_route53_zone.zone.id
records = ["mywebsite.com"]
ttl = 300
}
resource aws_route53_zone zone {
name         = "mywebsite.com"
}

The error message when applying Terraform is as follows:

* aws_route53_record.www: 1 error(s) occurred:
* aws_route53_record.www: [ERR]: Error building changeset: InvalidChangeBatch: RRSet of type CNAME with DNS name www.mywebsite.com. is not permitted as it conflicts with other records with the same DNS name in zone mywebsite.com.
status code: 400

Due to the conflict, Terraform will exit at this time.

To import state, or even import an existing resource file (if you no longer own it), you can run the Terraformer CLI command:

AWS_PROFILE=craig terraformer import aws --resources=route53 --filter=aws_route53_record=mywebsite.com --regions=eu-west-2

Terraformer 的美妙之处在于使用了过滤器,而不是 Terraform 使用的命名约定。

你基本上可以根据给定的名称来猜测资源名称,而使用 Terraform 时,它必须采用特定的格式。

导入过程耗费几秒钟的时间,但窗口中的输出非常有用:

2020/06/28 21:50:14 aws importing default region
2020/06/28 21:50:14 aws importing... route53
2020/06/28 21:50:17 Refreshing state... aws_route53_zone.tfer--Z06212801O0AQL6BP58RC_mywebsite-002E-com
2020/06/28 21:50:19 aws Connecting....
2020/06/28 21:50:19 aws save route53
2020/06/28 21:50:19 aws save tfstate for route53

将创建一个目录结构,你可以从中获取所需的所有信息。

route53_zone 包含于我的资源类似的定义,terraform.tfstate 文件包含状态信息。

但你必须记住,terrform.tfstate 只包含已过滤资源的状态信息。如果使用它来代替现有的 Terraform 状态,那么你可能会删除已具有状态的资源。

这个状态文件的重点技术是现在可以从状态文件中获取所需的部分,并将其粘贴到现有文件中。

以下是可供参考的文件:

代码文件

resource "aws_route53_zone" "tfer--Z06212801O0AQL6BP58RC_mywebsite-002E-com" {
comment       = "Managed by Terraform"
force_destroy = "false"
name          = "mywebsite.com."
}

状态文件

{
"version": 3,
"terraform_version": "0.12.18",
"serial": 1,
"lineage": "17034a7a-eadd-b496-c4e3-0ca3639e33ee",
"modules": [
{
"path": ["root"],
"outputs": {
"aws_route53_zone_tfer--Z06212801O0AQL6BP58RC_mywebsite-002E-com_id": {
"sensitive": false,
"type": "string",
"value": "Z06212801O0AQL6BP58RC"
}
},
"resources": {
"aws_route53_zone.tfer--Z06212801O0AQL6BP58RC_mywebsite-002E-com": {
"type": "aws_route53_zone",
"depends_on": [],
"primary": {
"id": "Z06212801O0AQL6BP58RC",
"attributes": {
"comment": "Managed by Terraform",
"delegation_set_id": "",
"force_destroy": "false",
"id": "Z06212801O0AQL6BP58RC",
"name": "mywebsite.com.",
"name_servers.#": "4",
"name_servers.0": "ns-1428.awsdns-50.org",
"name_servers.1": "ns-1616.awsdns-10.co.uk",
"name_servers.2": "ns-307.awsdns-38.com",
"name_servers.3": "ns-944.awsdns-54.net",
"tags.%": "0",
"vpc.#": "0",
"zone_id": "Z06212801O0AQL6BP58RC"
},
"meta": {
"schema_version": 0
},
"tainted": false
},
"deposed": [],
"provider": "provider.aws"
}
},
"depends_on": []
}
]
}

结论

Terraform 肯定有它的用途,尽管对于日常单一资源的导入,替代方法使用起来可能会更快。但我认为,它的主要目的是为了导入更多的基础设施。我很有兴趣在更大的范围来验证这一点,下次若有机会需要导入多个资源时,我肯定会尝试一下的。


Guess you like

Origin blog.51cto.com/15060462/2674769