作者:禅与计算机程序设计艺术
1.简介
TerraForm是一个基础设施自动化工具,它可以自动创建、更新、删除IT基础设施(例如服务器、网络设备、存储系统等)上的云资源配置。Terraform 的主要优点包括:
- 声明式语法: TerraForm 使用描述性语言而不是编程语言来描述期望的资源状态,这是它与其他自动化工具的一个重要区别。
- 滚动发布: Terraform 可以轻松管理复杂的基础设施,并支持滚动部署,即逐步部署新功能或更新。
- 可重用性: 高度模块化的代码结构使得 Terraform 模板可重用,你可以通过公共模块库来扩展 Terraform 的功能。
- 提供可观察性: Terraform 为每个执行过的命令提供详细的日志记录和可视化输出,这对跟踪和排查问题至关重要。
本文将详细介绍TerraForm的一些特性、限制和用例,希望能够帮助读者更好地理解TerraForm这个强大的工具。
在正式开始之前,本文假定读者已经熟悉云计算相关知识,了解计算机网络和服务器硬件体系结构的基本知识。同时,本文不会涉及到TerraForm的安装和配置过程,只会介绍其常用的命令和参数。
2.基本概念与术语
2.1 Terraform Basics
Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. It works with popular cloud providers such as Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform, and more. TerraForm uses a declarative language to describe the desired state of your infrastructure, compared to imperative languages like Python or bash scripting. This means that rather than specifying individual commands to create or destroy resources, you declare what you want, and TerraForm will ensure that real physical resources match your configuration. You can even version control this file using Git or other version control systems.
2.2 Terraform Terminology and Concepts
Resources
A resource represents an infrastructure object, such as a virtual machine instance in AWS EC2 or a container cluster in GCP Kubernetes Engine. Each resource has certain attributes that define its configuration, and some may have additional nested objects within them. For example, a VM instance might have a network interface attached to it which itself contains an IP address, security group rules, and so on.
Modules
Modules are reusable code blocks that encapsulate common functionality and can be used across multiple configurations. For example, you could write one module to create an EC2 instance running Apache web server, another to set up NGINX load balancers, and then combine these modules into larger deployments that span multiple regions and VPCs.
Providers
Providers are plugins that interact with a particular cloud provider’s API to manage resources. For example, there is a separate provider plugin for each major cloud provider, allowing Terraform to work with different APIs depending on where your infrastructure is hosted.
State
The state file is essentially a database that Terraform keeps track of the current physical and logical states of all of your resources. When you run a command like terraform plan
, Terraform compares the state file against your configuration files and generates an execution plan before making any changes to the actual infrastructure. If everything looks good, Terraform applies the planned changes to your live infrastructure. If not, Terraform provides detailed error messages explaining why the changes failed and how to correct them.
Backend
Backends are responsible for persisting the Terraform state data between runs and managing remote state files. By default, Terraform stores the state locally on disk, but backends allow you to store it remotely, such as in S3 or Consul.
3. Core Algorithm and Operations
3.1 Plan
The plan command generates an execution plan based on the current state of your resources and the proposed updates to those resources specified in your configuration files. Execution plans show you what Terraform will change when you apply your changes.
$ terraform planRefreshing Terraform state in-memory prior to plan...The refreshed state will be used to calculate this plan, but will not bepersisted to local or remote state storage.------------------------------------------------------------------------An execution plan has been generated and is shown below.Resource actions are indicated with the following symbols:+ create<= read (data resources)Terraform will perform the following actions:# aws_instance.web[0] will be created+ resource "aws_instance" "web" {+ ami = "ami-0c55b159cbfafe1f0"+ arn = (known after apply)+ associate_public_ip_address = true+ availability_zone = "us-west-2a"+ cpu_core_count = 2+ cpu_threads_per_core = 1+ disable_api_termination = false+ ebs_block_device { + delete_on_termination = true + device_name = (known after apply) + encrypted = false + iops = (known after apply) + kms_key_id = (known after apply) + snapshot_id = (known after apply) + volume_size = 16 + volume_type = "gp2"}+ get_password_data = false+ host_id = (known after apply)+ iam_instance_profile = ""+ id = (known after apply)+ instance_state = (known after apply)+ instance_type = "t2.micro"+ ipv6_address_count = (known after apply)+ ipv6_addresses = (known after apply)+ key_name = "my-key-pair"+ monitoring = true+ outpost_arn = (known after apply)+ password_data = (known after apply)+ placement_group = (known after apply)+ primary_network_interface_id = (known after apply)+ private_dns = (known after apply)+ private_ip = (known after apply)+ public_dns = (known after apply)+ public_ip = (known after apply)+ root_block_device { + delete_on_termination = true + device_name = (known after apply) + encrypted = false + iops = (known after apply) + kms_key_id = (known after apply) + tags = {} + volume_id = (known after apply) + volume_size = 8 + volume_type = "gp2"}+ secondary_private_ips = (known after apply)+ security_groups = [ + "default",]+ source_dest_check = true+ subnet_id = "subnet-0e9e72c578d4a1fb0"+ tenancy = (known after apply)+ user_data = (known after apply)+ vpc_security_group_ids = []+ capacity_reservation_specification { + capacity_reservation_preference = (known after apply)}+ credit_specification { + cpu_credits = "standard"}+ metadata_options { + http_endpoint = "enabled" + http_put_response_hop_limit = 1 + http_tokens = "optional"}}Plan: 1 to add, 0 to change, 0 to destroy.
3.2 Apply
Once you’re satisfied with the execution plan, you can use the apply command to deploy the changes to your live infrastructure. The first time you apply new resources, Terraform creates them; subsequently, it only makes the necessary changes.
$ terraform applyaws_instance.web[0]: Creating...aws_instance.web[0]: Still creating... [10s elapsed]aws_instance.web[0]: Still creating... [20s elapsed]aws_instance.web[0]: Creation complete after 29s [id=i-0d8d1d5605ddaa14d]Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
3.3 Destroy
If at any point you need to revert back to the previous state, you can use the destroy command to remove all the resources managed by Terraform from your account.
$ terraform destroyaws_instance.web[0]: Destroying... [id=i-0d8d1d5605ddaa14d]aws_instance.web[0]: Destruction complete after 3sDestroy complete! Resources: 1 destroyed.
4. Code Examples
Here are two simple examples that demonstrate basic usage of TerraForm.
Example 1: Create a Virtual Machine Instance Using an Existing Image
To create a single EC2 virtual machine instance using an existing image we’ll follow these steps:
- Open a text editor and create a new directory called
example
. - Navigate inside the
example
folder and initialize a new TerraForm project by typing$ terrform init
. - Inside the
example
folder create a new file namedmain.tf
and paste the following contents:
resource "aws_instance" "web" {ami = var.amiinstance_type = "t2.micro"root_block_device {volume_type = "gp2"volume_size = 8}key_name = "my-key-pair"security_groups = ["sg-abc123"]subnet_id = "subnet-xyz789"user_data = <<-EOF#!/bin/bashecho "Hello, World!" > index.htmlnohup python -m SimpleHTTPServer 80 &EOF}variable "ami" {description = "The ID of the AMI to use for the instance."}output "public_dns" {value = "${aws_instance.web.public_dns}"}
- Now open the terminal and navigate to the
example
directory using the cd command. - Run the following command to download an Ubuntu Server AMI and provide it as input to our Terraform template:
export TF_VAR_ami=$(aws ec2 describe-images --filters 'Name=name,Values="ubuntu/images/*"' | jq '.Images[] |.ImageId' -r | head -n 1)
This command exports the value of TF_VAR_ami
environment variable which contains the ID of the latest Ubuntu Server AMI available in the us-east-1 region.
6. Next, run the following command to check if everything is configured correctly:
$ terraform validateSuccess! The configuration is valid.
- Finally, run the following command to create a new EC2 instance:
$ terraform apply...Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
- After applying the changes, retrieve the DNS name of the newly created EC2 instance by running:
$ terraform output public_dnsXXXXXXXXXXXXXXXXXXXX.us-west-2.compute.amazonaws.com
This should display the Public DNS Name of the newly created EC2 instance.
9. SSH into the instance using the ssh command and test the deployment by navigating to the domain name provided in step 8.
Example 2: Deploy Multiple Instances in Different Regions
In this example, we’ll deploy three instances in three different regions and update their security groups using variables. We assume that we already have the required keys and security groups defined in our account.
- Open a text editor and create a new directory called
multiregion
. - Navigate inside the
multiregion
folder and initialize a new TerraForm project by typing$ terrform init
. - Inside the
multiregion
folder create a new file namedmain.tf
and paste the following contents:
provider "aws" {access_key = ""secret_key = ""region = "us-east-1"}variable "regions" {type = list(string)default = ["us-east-1","us-west-2","ap-southeast-1"]}resource "aws_instance" "app" {count = length(var.regions)ami = "ami-0c55b159cbfafe1f0"instance_type = "t2.micro"key_name = "my-key-pair"vpc_security_group_ids = [aws_security_group.allow_all.id]subnet_id = element(aws_subnet.subnet.*.id, count.index)depends_on = [aws_internet_gateway.igw]connection {user = "root"private_key = file("path/to/private_key")}}resource "aws_security_group" "allow_all" {ingress {protocol = "-1"self = true}egress {cidr_blocks = ["0.0.0.0/0"]from_port = 0to_port = 0protocol = "-1"}}resource "aws_vpc" "vpc" {cidr_block = "10.0.0.0/16"enable_dns_support = trueenable_dns_hostnames = truetags = {Name = "my-vpc"}}resource "aws_subnet" "subnet" {count = length(var.regions)vpc_id = aws_vpc.vpc.idcidr_block = "10.0.1.${count.index}.0/24"map_public_ip_on_launch = trueavailability_zone = var.regions[count.index]tags = {Name = "subnet-${count.index}"}}resource "aws_internet_gateway" "igw" {vpc_id = aws_vpc.vpc.idtags = {Name = "my-igw"}}output "public_dns" {value = flatten([for x in aws_instance.app : [x.public_dns]])}
- Modify the provider block with your own credentials and save the file.
- Now let’s move on to defining our variable values.
First, replace
and
with your AWS Access Key and Secret Key respectively.
Second, uncomment the line# default = ["us-east-1","us-west-2","ap-southeast-1"]
under thevariable "regions"
block. - Save the file.
- Let’s now modify our main.tf script to include a dynamic block that selects the right subnet IDs for each region:
[...]resource "aws_instance" "app" {count = length(var.regions)ami = "ami-0c55b159cbfafe1f0"instance_type = "t2.micro"key_name = "my-key-pair"vpc_security_group_ids = [aws_security_group.allow_all.id]subnet_id = element(aws_subnet.subnet.*.id, count.index)depends_on = [aws_internet_gateway.igw]connection {user = "root"private_key = file("path/to/private_key")}}[...]resource "aws_subnet" "subnet" {count = length(var.regions)vpc_id = aws_vpc.vpc.idcidr_block = "10.0.1.${count.index}.0/24"map_public_ip_on_launch = trueavailability_zone = var.regions[count.index]tags = {Name = "subnet-${count.index}"}}
- Add an output block to display the DNS names of the deployed instances:
[...]output "public_dns" {value = flatten([for x in aws_instance.app : [x.public_dns]])}
- Now save the file and exit the text editor.
- Start by updating your AWS CLI installation by running:
pip install awscli --upgrade --user
- Configure your profile using:
aws configure
- Export your AWS Access Key and Secret Key as follows:
export TF_VAR_access_key=""export TF_VAR_secret_key=""
- Change the directory to
multiregion
:
cd multiregion
- Initialize the TerraForm workspace:
terraform init
- Validate the Terraform configuration:
terraform validate
- Review the execution plan:
terraform plan
- Apply the changes to your account:
terraform apply
- Verify that the instances were created successfully:
terraform output
- Delete all the resources when you are done:
terraform destroy
- Check your AWS Console to confirm that all resources have been deleted successfully.
来源地址:https://blog.csdn.net/universsky2015/article/details/132126853