目录
一、实验
1.环境
2.aws 亚马逊云创建用户
3.Windows使用Terraform 初始化 aws provider
4.Windows使用Terraform 创建S3存储资源 (对象存储)
5.Windows使用Terraform 创建Dynamo DB资源 (表格存储)
6.Windows给Terraform项目添加Backend配置
7.Windows使用Terraform 创建VPC和Subnet资源
8.Windows使用Terraform 创建SecurityGroup资源
9.Windows使用Terraform 创建Route和Gateway资源
10.Windows使用Terraform 创建EC2资源
11.Windows使用Terraform 创建ELB资源
12.销毁资源
二、问题
1.Terraform初始化报错
2.Terram验证资源报错
3.Terraform初始化失败
4.Terraform删除资源失败 (负载均衡器)
5.Terraform删除资源失败 (S3)
6.AWS 有哪些区域和可用区
一、实验
1.环境
(1)主机
表1-1 主机
主机 | 系统 | 软件 | 工具 | 备注 |
jia | Windows | Terraform 1.6.6 | VS Code、 PowerShell、 Chocolatey | |
pipepoint | Linux | Terraform 1.6.6 |
2.aws 亚马逊云创建用户
(1)登录
用户 | IAM | Global (amazon.com)
(2)查看
IAM
(3)创建用户
(4)创建完成
(5)访问密钥
(6)完成
(7)创建组和权限
(8)关联用户
(9)查看用户权限
(10)查看aws provider 示例
Terraform Registry
USE PROVIDER 示例
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "5.32.1"
}
}
}
provider "aws" {
# Configuration options
}
Example Usage 示例
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
# Configure the AWS Provider
provider "aws" {
region = "us-east-1"
}
# Create a VPC
resource "aws_vpc" "example" {
cidr_block = "10.0.0.0/16"
}
3.Windows使用Terraform 初始化 aws provider
(1)创建项目terraform-aws
查看目录
(2)格式化代码
terraform fmt
(3) 初始化
terraform init
(4) 验证代码
terraform validate
(5)查看版本及provider
terraform -v 或 terraform --version
4.Windows使用Terraform 创建S3存储资源 (对象存储)
(1)查看目录
(2)创建主配置文件
main.tf
# Configuration options
provider "aws" {
region = var.region
access_key = var.access_key
secret_key = var.secret_key
}
resource "aws_s3_bucket" "terraform-bucket" {
bucket = "terraform-state-devmaojing"
acl = "private"
versioning {
enabled = true
}
}
(3)创建默认变量配置文件(存储IAM密钥)
terraform.tfvars
(4)创建版本配置文件
variables.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "5.32.1"
}
}
}
(5) 创建变量配置文件
variables.tf
variable "access_key" {
type = string
}
variable "secret_key" {
type = string
}
variable "region" {
type = string
default = "us-east-1"
}
(5) 格式化代码
terraform fmt
(6)验证代码
terraform validate
(7)计划与预览
terraform plan
(8)申请资源
terraform apply
(9)登录AWS查看
查看S3存储桶
5.Windows使用Terraform 创建Dynamo DB资源 (表格存储)
(1)修改主配置文件
main.tf 添加如下代码
resource "aws_dynamodb_table" "tf-state-table" {
name = "tf-state-tablemaojing"
billing_mode = "PROVISIONED"
read_capacity = 20
write_capacity = 20
hash_key = "LockID"
attribute {
name = "LockID"
type = "S"
}
}
(2) 格式化代码
terraform fmt
(3)验证代码
terraform validate
(4)计划与预览
terraform plan
(5)申请资源
terraform apply
(6)登录AWS查看
查看Dynamo DB
6.Windows给Terraform项目添加Backend配置
(1)添加输出配置文件
outputs.tf
output "bucket_name" {
value = aws_s3_bucket.terraform-bucket.bucket
}
(2) 申请资源
terraform apply
成功输出bucket名称
(3)添加后端存储配置文件
backend.tf
(4)格式化代码
terraform fmt
(3)验证代码
terraform validate
(4) 初始化
terraform init
yes,系统上传配置文件到AWS 的S3
(6)登录AWS查看
查看配置文件已上传S3
(7)删除配置文件
(8)IAM添加VPC权限
7.Windows使用Terraform 创建VPC和Subnet资源
(1)查看目录
(2)配置network网络实例资源
main.tf
# Configuration options
provider "aws" {
region = var.region
access_key = var.access_key
secret_key = var.secret_key
}
backend.tf
terraform.tfvars、variables.tf 、versions.tf 配置文件与 global/backend下的配置文件相同。
(3) 格式化代码
terraform fmt
(4) 初始化
terraform init
(5)AWS查看S3已更新配置文件
(6)添加VPC配置文件
vpc.tf
resource "aws_vpc" "main" {
cidr_block = "172.16.0.0/16"
enable_dns_hostnames = true
}
(7)申请资源
terraform apply
(8)AWS查看VPC
无Name
(9)修改VPC配置文件
vpc.tf ,添加标签
tags = {
"Name" = "tf-demo-vpc"
}
(10)申请资源
terraform apply
(11)AWS 再次查看VPC
出现了Name
详细信息
(12)修改VPC配置文件
vpc.tf,添加子网subnet信息
locals {
azs = ["us-east-1a", "us-east-1b"]
cidr_blocks = ["172.16.10.0/24", "172.16.50.0/24"]
}
resource "aws_subnet" "subnet" {
count = length(local.azs)
vpc_id = aws_vpc.main.id
cidr_block = local.cidr_blocks[count.index]
availability_zone = local.azs[count.index]
map_public_ip_on_launch = true
tags = {
Name = "subnet-${count.index}"
}
}
map_public_ip_on_launch = true 功能为开启自动分配公有 IPv4 地址
(13)格式化代码
terraform fmt
(14)申请资源
terraform apply
(14)AWS查看子网
8.Windows使用Terraform 创建SecurityGroup资源
(1)修改主配置文件
将vpc,tf 的locals 字段 移动到main.tf,并添加端口信息
# Configuration options
provider "aws" {
region = var.region
access_key = var.access_key
secret_key = var.secret_key
}
locals {
azs = ["us-east-1a", "us-east-1b"]
cidr_blocks = ["172.16.10.0/24", "172.16.50.0/24"]
ports = ["80", "443", "22"]
}
(2)创建安全组资源配置文件
security_group.tf
resource "aws_security_group" "allow" {
name = "allow"
description = "Allow inbound traffic"
vpc_id = aws_vpc.main.id
dynamic "ingress" {
for_each = local.ports
content {
description = "${ingress.value} from VPC"
from_port = ingress.value
to_port = ingress.value
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Name = "allow"
}
}
(3)格式化代码
terraform fmt
(4)申请资源
terraform apply
yes
(5)AWS 查看安全组
入站规则
出站规则
(6)添加输出配置文件
outputs.tf
output "vpc_id" {
value = aws_vpc.main.id
}
output "subnet_id" {
value = aws_subnet.subnet.*.id
}
output "security_group_id" {
value = aws_security_group.allow.id
}
(7) 申请资源
terraform apply
输出3个网络信息
9.Windows使用Terraform 创建Route和Gateway资源
(1)修改VPC配置文件
vpc.tf ,新增获取路由表信息
data "aws_route_table" "table" {
vpc_id = aws_vpc.main.id
}
(2)修改输出配置文件
outputs.tf ,新增输出路由表id
output "route_table_id" {
value = data.aws_route_table.table.id
}
(3) 申请资源
terraform apply
新增输出路由表信息
(4) 创建Gateway资源
修改vpc.tf ,新增网关代码
resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.main.id
tags = {
Name = "tf-demo-ec2-gw"
}
}
(5)申请资源
terraform apply
(6) AWS 查看网关
(7)创建路由表资源
修改vpc.tf ,添加如下代码:
resource "aws_route" "r" {
route_table_id = data.aws_route_table.table.id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.gw.id
}
(8)格式化代码
terraform fmt
(9) 申请资源
terraform apply
(10)AWS查看路由表
10.Windows使用Terraform 创建EC2资源
(1)查看目录
(2)修改主配置文件
main.tf
# Configuration options
provider "aws" {
region = var.region
access_key = var.access_key
secret_key = var.secret_key
}
(3) 修改后端存储配置文件
(4)初始化
terraform init
(5) 申请资源
terraform apply
(6)AWS查看S3
已新增service 配置文件
(7)AWS查询镜像ID
AMI ID
ami-023c11a32b0207432
(8)添加SSH密钥对
ssh-keygen -t rsa -m PEM
私钥名称改为myecs_private_key.pem,公钥名称改为myecs_public_key.pub
(9)添加ECS配置文件
ec2.tf
resource "aws_key_pair" "deployer" {
key_name = "myecs_private_key"
public_key = file("${path.module}/config/myecs_public_key.pub")
}
resource "aws_instance" "web" {
for_each = toset(local.instance)
ami = local.ami_id
key_name = aws_key_pair.deployer.key_name
instance_type = local.instance_type
associate_public_ip_address = true
subnet_id = local.instance_config[each.value].subnet_id
availability_zone = local.instance_config[each.value].availability_zone
private_ip = local.instance_config[each.value].ipv4_address
vpc_security_group_ids = [local.security_group_id]
user_data = file("${path.module}/config/install-nginx.sh")
tags = {
Name = each.value
}
}
(10) 修改主配置文件
main.tf
(11)添加输出配置文件
terraform validate
outputs.tf
output "ecs_ids" {
value = aws_instance.web
}
(12) 格式化代码
terraform fmt
(13)验证代码
terraform validate
(14)计划与预览
terraform plan
(15)申请资源
terraform apply
yes
输出
(16) AWS查看EC2
(17)点击连接server1
(18)SSH命令
(19)点击连接server1
(19)SSH命令
(20)远程操作server1
远程连接
ssh -i "myecs_private_key.pem" ec2-user@ec2-18-232-100-200.compute-1.amazonaws.com
sudo -s
注意切换目录config
查看nginx进程
ps aux | grep nginx
测试
curl localhost
退出
exit
(20)远程操作server2
远程连接
ssh -i "myecs_private_key.pem" ec2-user@ec2-3-215-176-187.compute-1.amazonaws.com
sudo -s
查看nginx进程
ps aux | grep nginx
测试
curl localhost
退出
exit
(21)公网访问
http://ec2-18-232-100-200.compute-1.amazonaws.com/
http://ec2-3-215-176-187.compute-1.amazonaws.com/
(22)修改输出配置文件
outputs.tf
output "ecs_ids" {
value = [for k, v in aws_instance.web : v.id]
}
(23) 申请资源
terraform apply
成功拿到2个ECS实例的id值
11.Windows使用Terraform 创建ELB资源
(1)添加elb配置文件
elb.tf
resource "aws_lb" "test_lb" {
name = "test-lb-tf"
internal = false
load_balancer_type = "application"
security_groups = [local.security_group_id]
subnets = local.subnet_id
enable_deletion_protection = true
tags = {
Environment = "production"
}
}
resource "aws_lb_target_group" "test_group" {
name = "tf-example-lb-tg"
port = 80
protocol = "HTTP"
vpc_id = local.vpc_id
}
resource "aws_lb_target_group_attachment" "test" {
count = length(local.ecs_ids)
target_group_arn = aws_lb_target_group.test_group.arn
target_id = local.ecs_ids[count.index]
port = 80
}
resource "aws_lb_listener" "front_end" {
load_balancer_arn = aws_lb.test_lb.arn
port = "80"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.test_group.arn
}
}
(2) 修改主配置文件
main.tf ,添加如下代码
ecs_ids = [for k, v in aws_instance.web : v.id]
(3)格式化代码
terraform fmt
(4)验证代码
terraform validate
(5)计划与预览
terraform plan
(6)申请资源
terraform apply
yes, 大概需要3分钟
(7)AWS查看
负载均衡器
侦听器
目标组(状态均为健康)
(8)访问DNS
test-lb-tf-978979139.us-east-1.elb.amazonaws.com
访问成功
刷新会变化
12.销毁资源
(1)查看当前目录
(2)销毁服务资源
terraform destroy
关闭负载均衡器的删除保护,然后删除成功
(3)销毁网络资源
terraform destroy
yes
(4)销毁后端存储资源
terraform destroy
清空存储桶内容,再销毁资源
(5)登录AWS查看
ECS已终止
负载均衡器已删除
DynamoDB已删除
二、问题
1.Terraform初始化报错
(1)报错
╷
│ Error: Failed to query available provider packages
│
│ Could not retrieve the list of available versions for provider hashicorp/aws: could not connect to registry.terraform.io: failed to request
│ discovery document: Get "https://registry.terraform.io/.well-known/terraform.json": read tcp
│ [240e:3ae:b80:8240:8013:f872:f878:2e7b]:61445->[2600:9000:2646:6e00:16:1aa3:1440:93a1]:443: wsarecv: An existing connection was forcibly
│ closed by the remote host.
╵
(2)原因分析
国内没有terraform provider源,因此可能会下载超时。
(3)解决方法
查询官网
Terraform-Provider-Aws Versions | HashiCorp Releases
找到指定版本
下载对应系统支持的版本
成功:
2.Terram验证资源报错
(1)报错
╷
│ Error: Reference to undeclared input variable
│
│ on main.tf line 4, in provider "aws":
│ 4: access_key = var.access_key
│
│ An input variable with the name "access_key" has not been declared. This variable can be declared with a variable "access_key" {} block.
╵
╷
│ Error: Reference to undeclared input variable
│
│ on main.tf line 5, in provider "aws":
│ 5: secret_key = var.secret_key
│
│ An input variable with the name "secret_key" has not been declared. This variable can be declared with a variable "secret_key" {} block.
(2)原因分析
变量未申明
(3)解决方法
申明变量。
成功:
3.Terraform初始化失败
(1)报错
╷
│ Error: Variables not allowed
│
│ on backend.tf line 5, in terraform:
│ 5: region = var.region
│
│ Variables may not be used here.
╵
PS C:\Gocode\src\terraform-aws\global\backend> terraform init
Initializing the backend...
╷
│ Error: No valid credential sources found
│
│ Please see https://www.terraform.io/docs/language/settings/backends/s3.html
│ for more information about providing credentials.
│
│ Error: failed to refresh cached credentials, no EC2 IMDS role found, operation error ec2imds: GetMetadata, request canceled, context deadline exceeded
(2)原因分析
backend 模块里 不允许出现变量,未添加IAM密钥验证信息。
(3)解决方法
修改配置文件。
成功:
4.Terraform删除资源失败 (负载均衡器)
(1)报错
╷
│ Error: deleting ELBv2 Load Balancer (arn:aws:elasticloadbalancing:us-east-1:754381516519:loadbalancer/app/test-lb-tf/acc75028b14a17a1): OperationNotPermitted: Load balancer 'arn:aws:elasticloadbalancing:us-east-1:754381516519:loadbalancer/app/test-lb-tf/acc75028b14a17a1' cannot be deleted because deletion protection is enabled
│ status code: 400, request id: 46687c4f-1016-496c-af63-f2b5840796c2
(2)原因分析
负载均衡器开启了删除保护。
(3)解决方法
查看属性
关闭保护
成功
5.Terraform删除资源失败 (S3)
(1)报错
╷
│ Error: deleting S3 Bucket (terraform-state-devmaojing): operation error S3: DeleteBucket, https response error StatusCode: 409, RequestID: MHHWXPQC0K43P5R4, HostID: 6CaQATqB7FfLhMwfaYhbTwMR+g1SVHho5FFrycVXtRXXo5P5b3+43oEJMlXY1+MopR5hcXD34zEW0/p2lWUUXYL3MRiWnKj6, api error BucketNotEmpty: The bucket you tried to delete is not empty. You must delete all versions in the bucket.
│
(2)原因分析
存储桶未清空。
(3)解决方法
先清空后删除
6.AWS 有哪些区域和可用区
(1)查询
区域和可用区 - Amazon Elastic Compute Cloud