Terraform 和Terraformer on AWS 动手实践

2023-03-24 09:56

1 文档目的

Terraform 是一个安全和高效的用来构建、更改和合并基础架构的工具。采用 Go 语言开发。Terraform 可管理已有的流行的服务,并提供自定义解决方案。

Terraform 的基本原则是,它允许编写人类可读的配置代码来定义 IaC。借助配置代码,可以把可重复的、短暂的、一致的环境部署到公有云、私有云和混合云上。

本文主要介绍在AWS上使用Terraformer 收集已经部署的基础架构资源和使用Terraform 来部署基础资源。

2   安装

2.1 基础环境

测试使用redhat 7.9

2.2 安装aws cli

# curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"

# yum -y install unzip

# unzip awscliv2.zip

# ./aws/install

2.3 安装terraform

# yum install -y yum-utils

# yum-config-manager /

--add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo

# yum -y install terraform

# terraform --version

Terraform v1.3.4

on linux_amd64

2.4 安装terraformer

# export PROVIDER=aws

# curl -LO   /

https://github.com/GoogleCloudPlatform/terraformer/releases/download/$(curl -s   /

https://api.github.com/repos/GoogleCloudPlatform/terraformer/releases/latest |   /

grep tag_name | cut -d '"' -f 4)/terraformer-${PROVIDER}-linux-amd64

# chmod +x terraformer-${PROVIDER}-linux-amd64

# mv terraformer-${PROVIDER}-linux-amd64 /usr/local/bin/terraformer

# terraformer --version

version v0.8.22

3   Terraformer 获取现有资源

3.1 初始化provider

# mkdir tfer && cd tfer

# vi provider.tf

provider "aws" {

region = "cn-northwest-1"

}

# terraform init

3.2   获取现有资源

1) 获取VPC

# terraformer import aws --resources=vpc





2) 获取子网:

# terraformer import aws --resources=subnet



3) 获取igwnat

# terraformer import aws --resources=igw,nat


4) 获取安全组

# terraformer import aws --resources=sg


5) 获取实例

# terraformer import aws --resources=ec2_instance


更多资源名称,可访问:

https://github.com/GoogleCloudPlatform/terraformer/blob/master/docs/aws.md

4   Terraform 创建资源

Provider 资源参数可访问官网:

https://registry.terraform.io/providers/hashicorp/aws/latest/docs

4.1 配置provider

# vi provider.tf

terraform {

  required_providers {

    aws = {

      source   = "hashicorp/aws"

      version = "~> 4.0"

    }

  }

}

provider "aws" {

  region = "cn-northwest-1"

}

# terraform init



4.2 创建vpc

# vi vpc.tf

resource "aws_vpc" "tf_vpc" {

  cidr_block = "10.200.0.0/16"

enable_dns_hostnames = "true"

  enable_dns_support = "true"

  tags = {

Name = "tf-vpc"

  }

}

# terraform plan

# terraform apply -auto-approve




4.3   创建子网

# vi subnet.tf

resource "aws_subnet" "tf_public_subnet1" {

  vpc_id     = aws_vpc.tf_vpc.id

  cidr_block = "10.200.1.0/24"

  map_public_ip_on_launch = "true"

  availability_zone = "cn-northwest-1a"

  tags = {

    Name = "tf_public_subnet1_1a"

  }

}

resource "aws_subnet" "tf_public_subnet2" {

  vpc_id     = aws_vpc.tf_vpc.id

  cidr_block = "10.200.2.0/24"

  map_public_ip_on_launch = "true"

  availability_zone = "cn-northwest-1b"

  tags = {

    Name = "tf_public_subnet2_1b"

  }

}

resource "aws_subnet" "tf_private_subnet1" {

  vpc_id     = aws_vpc.tf_vpc.id

  cidr_block = "10.200.100.0/24"

  availability_zone = "cn-northwest-1a"

  tags = {

    Name = "tf_private_subnet1_1a"

  }

}

resource "aws_subnet" "tf_private_subnet2" {

  vpc_id     = aws_vpc.tf_vpc.id

  cidr_block = "10.200.110.0/24"

  availability_zone = "cn-northwest-1b"

  tags = {

    Name = "tf_private_subnet1_1b"

  }

}

# terraform plan


# terraform apply -auto-approve


4.4 创建IGW

# vi igw.tf

resource "aws_internet_gateway" "tf_igw" {

  vpc_id = aws_vpc.tf_vpc.id

  tags = {

    Name = "tf_igw"

  }

}

# terraform plan


# terraform apply -auto-approve


4.5 创建路由表

# vi rtb.tf

# terraform plan

# terraform apply -auto-approve


4.6 创建安全组

# vi sg.tf

resource "aws_security_group" "tf_general_sg" {

  name        = "tf_general_sg"

  description = "General inbound traffic configuration of tf testing "

  vpc_id      = aws_vpc.tf_vpc.id

  ingress {

    description      = "https"

    from_port        = 443

    to_port          = 443

    protocol         = "tcp"

    cidr_blocks      = ["0.0.0.0/0"]

  }

  ingress {

    description      = "http"

    from_port        = 80

    to_port          = 80

    protocol         = "tcp"

    cidr_blocks      = ["0.0.0.0/0"]

  }

  ingress {

    description      = "ssh"

    from_port        = 22

    to_port          = 22

    protocol         = "tcp"

    cidr_blocks      = ["0.0.0.0/0"]

  }

  ingress {

    description      = "icmp"

    from_port        = "-1"

    to_port          = "-1"

    protocol         = "icmp"

    cidr_blocks      = ["0.0.0.0/0"]

  }

  ingress {

    description      = "8088"

    from_port        = 8088

    to_port          = 8088

    protocol         = "tcp"

    cidr_blocks      = ["0.0.0.0/0"]

  }

 

  egress {

    from_port        = 0

    to_port          = 0

    protocol         = "-1"

    cidr_blocks      = ["0.0.0.0/0"]

  }

  tags = {

    Name = "tf_general_sg"

  }

}

# terraform plan

# terraform apply -auto-approve


4.7 创建实例

4.7.1 设置ami

# vi datasource.tf

data "aws_ami" "Amazon_Linux_2" {

  most_recent      = true

  owners           = ["141808717104"]

  filter {

    name   = "name"

    values = ["amzn2-ami-kernel-5.10-hvm-2.0.20221103.3-x86_64-gp2"]

  }

}

# terraform apply -auto-approve




4.7.2 创建密钥对

# ssh-keygen


# vi keypair.tf

resource "aws_key_pair" "tfkey" {

  key_name   = "tfkey"

  public_key = file("/root/.ssh/tfkey.pub")

}

# terraform plan


# terraform apply -auto-approve




4.7.3 编辑userdata

# vi userdata.tpl

#!/bin/bash

sudo amazon-linux-extras install nginx1 -y

sudo systemctl enable nginx

sudo systemctl start ngnix

4.7.4 创建实例

# vi instance.tf

resource "aws_instance" "web-1a" {

  ami             = data.aws_ami.Amazo_Linux_2.id

  instance_type   = "t3.micro"

  subnet_id       = aws_subnet.tf_public_subnet1.id

  vpc_security_group_ids = [aws_security_group.tf_general_sg.id]

  key_name        = aws_key_pair.tfkey.id

  user_data       = file("./userdata.tpl")

 

  root_block_device {

    volume_size = 30

    volume_type = "gp3"

  }

 

  tags = {

    Name = "Web-1a"

  }

}

resource "aws_instance" "web-1b" {

  ami             = data.aws_ami.Amazo_Linux_2.id

  instance_type   = "t3.micro"

  subnet_id       = aws_subnet.tf_public_subnet2.id

  vpc_security_group_ids = [aws_security_group.tf_general_sg.id]

  key_name        = aws_key_pair.tfkey.id

  user_data       = file("./userdata.tpl")

 

  root_block_device {

    volume_size = 30

    volume_type = "gp3"

  }

 

  tags = {

    Name = "Web-1b"

  }

}

# terraform plan

# terraform apply -auto-approve


4.8 创建ELB

4.8.1 创建目标群组

# vi targetgroup.tf

resource "aws_lb_target_group" "tf_target_group" {

  name        = "tf-alb-tg"

  target_type = "instance"

  port        = 80

  protocol    = "HTTP"

  vpc_id      = aws_vpc.tf_vpc.id

}

resource "aws_lb_target_group_attachment" "ints_att_1a" {

  target_group_arn = aws_lb_target_group.tf_target_group.arn

  target_id        = aws_instance.web-1a.id

  port             = 80

}

resource "aws_lb_target_group_attachment" "ints_att_1b" {

  target_group_arn = aws_lb_target_group.tf_target_group.arn

  target_id        = aws_instance.web-1b.id

  port             = 80

}

# terraform plan



# terraform apply -auto-approve



4.8.2 创建elb

# vi elb.tf

resource "aws_lb" "tf_lb" {

  name               = "tf-lb"

  internal           = false

  load_balancer_type = "application"

  security_groups    = [aws_security_group.tf_general_sg.id]

  subnets            = [aws_subnet.tf_public_subnet1.id,aws_subnet.tf_public_subnet2.id]

  enable_deletion_protection = true

  tags = {

    Name = "tf-lb"

  }

}

resource "aws_lb_listener" "tf_lb_port" {

  load_balancer_arn = aws_lb.tf_lb.arn

  port              = "8088"

  protocol          = "HTTP"

 

  default_action {

    type             = "forward"

    target_group_arn = aws_lb_target_group.tf_target_group.arn

  }

}

# terraform plan

# terraform apply -auto-approve



5 Terraform 删除资源

1 删除单个资源

# terraform state list

# terraform destroy -target=aws_instance.web-1b -auto-approve

# terraform state list


2   删除全部资源

# terraform destroy -auto-approve

# terraform state list


6   结束语

l 本文档适合在AWS平台上学习和动手练习;

l Terraform使用provider来定义所使用的平台,因此不可一套代码在多个平台部署,需要在相应的平台下重新编写相应的代码。








昵称:
内容:
验证码:
提交评论
评论一下