Terraform: Up & Running 代码示例教程

Terraform: Up & Running 代码示例教程

【免费下载链接】terraform-up-and-running-code Code samples for the book "Terraform: Up & Running" by Yevgeniy Brikman 【免费下载链接】terraform-up-and-running-code 项目地址: https://gitcode.com/gh_mirrors/te/terraform-up-and-running-code

概述

《Terraform: Up & Running》是学习基础设施即代码(Infrastructure as Code, IaC)的权威指南,本书通过实践案例深入讲解Terraform的核心概念和最佳实践。本教程将基于官方代码仓库,带你系统学习Terraform从入门到精通的完整知识体系。

环境准备

安装Terraform

# 在Linux系统上安装Terraform
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt-get update && sudo apt-get install terraform

# 验证安装
terraform version

配置AWS凭证

# 配置AWS访问密钥
aws configure
# 或者设置环境变量
export AWS_ACCESS_KEY_ID="your_access_key"
export AWS_SECRET_ACCESS_KEY="your_secret_key"
export AWS_DEFAULT_REGION="us-east-2"

基础语法入门

第一个Terraform配置

让我们从最简单的示例开始,创建单个EC2实例:

# code/terraform/01-why-terraform/web-server/main.tf
terraform {
  required_version = ">= 1.0.0, < 2.0.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}

provider "aws" {
  region = "us-east-2"
}

resource "aws_instance" "app" {
  instance_type     = "t2.micro"
  availability_zone = "us-east-2a"
  ami               = "ami-0fb653ca2d3203ac1"

  user_data = <<-EOF
              #!/bin/bash
              sudo service apache2 start
              EOF
}

执行流程

mermaid

变量和输出

定义变量

# code/terraform/02-intro-to-terraform-syntax/webserver-cluster/variables.tf
variable "server_port" {
  description = "The port the server will use for HTTP requests"
  type        = number
  default     = 8080
}

variable "alb_name" {
  description = "The name of the ALB"
  type        = string
  default     = "terraform-asg-example"
}

使用变量

resource "aws_security_group" "instance" {
  name = var.instance_security_group_name

  ingress {
    from_port   = var.server_port
    to_port     = var.server_port
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

定义输出

# code/terraform/02-intro-to-terraform-syntax/webserver-cluster/outputs.tf
output "alb_dns_name" {
  value       = aws_lb.example.dns_name
  description = "The domain name of the load balancer"
}

output "asg_name" {
  value       = aws_autoscaling_group.example.name
  description = "The name of the Auto Scaling Group"
}

模块化设计

模块结构

mermaid

模块调用示例

# code/terraform/04-terraform-module/module-example/stage/services/webserver-cluster/main.tf
module "webserver_cluster" {
  source = "../../../../modules/services/webserver-cluster"

  cluster_name           = "webservers-stage"
  db_remote_state_bucket = "(YOUR_BUCKET_NAME)"
  db_remote_state_key    = "stage/data-stores/mysql/terraform.tfstate"

  instance_type = "t2.micro"
  min_size      = 2
  max_size      = 2
}

状态管理

远程状态配置

terraform {
  backend "s3" {
    bucket         = "(YOUR_BUCKET_NAME)"
    key            = "global/s3/terraform.tfstate"
    region         = "us-east-2"
    dynamodb_table = "(YOUR_TABLE_NAME)"
    encrypt        = true
  }
}

状态文件结构

组件描述示例路径
全局资源跨环境共享的资源global/s3/terraform.tfstate
环境资源特定环境的资源stage/services/webserver-cluster/terraform.tfstate
数据存储数据库等数据资源stage/data-stores/mysql/terraform.tfstate

循环和条件语句

count 参数循环

# 创建多个IAM用户
resource "aws_iam_user" "example" {
  count = 3
  name  = "neo.${count.index}"
}

for_each 循环

# 使用for_each创建唯一名称的用户
resource "aws_iam_user" "example" {
  for_each = toset(["neo", "trinity", "morpheus"])
  name     = each.value
}

条件表达式

# 根据环境变量决定是否创建资源
resource "aws_instance" "example" {
  count = var.create_instance ? 1 : 0
  
  instance_type = "t2.micro"
  ami           = "ami-0fb653ca2d3203ac1"
}

测试策略

单元测试示例

// code/terraform/09-testing-terraform-code/test/alb_example_test.go
func TestAlbExample(t *testing.T) {
    t.Parallel()

    opts := &terraform.Options{
        TerraformDir: "../examples/alb",
        Vars: map[string]interface{}{
            "alb_name": fmt.Sprintf("test-%s", random.UniqueId()),
        },
    }

    defer terraform.Destroy(t, opts)
    terraform.InitAndApply(t, opts)

    albDnsName := terraform.OutputRequired(t, opts, "alb_dns_name")
    url := fmt.Sprintf("http://%s", albDnsName)

    // 测试ALB默认动作返回404
    expectedStatus := 404
    expectedBody := "404: page not found"
    
    http_helper.HttpGetWithRetry(
        t,
        url,
        nil,
        expectedStatus,
        expectedBody,
        10,
        10*time.Second,
    )
}

测试类型对比

测试类型描述适用场景工具
语法检查验证Terraform配置语法开发阶段terraform validate
计划测试检查执行计划是否符合预期代码审查terraform plan
单元测试测试单个模块的功能模块开发terratest
集成测试测试多个模块的协作系统测试terratest
合规测试检查安全性和合规性安全审计OPA

生产级最佳实践

目录结构设计

infrastructure/
├── modules/
│   ├── networking/
│   │   └── alb/
│   ├── data-stores/
│   │   └── mysql/
│   └── services/
│       └── webserver-cluster/
├── live/
│   ├── prod/
│   │   ├── data-stores/
│   │   └── services/
│   └── stage/
│       ├── data-stores/
│       └── services/
└── examples/
    ├── alb/
    ├── asg/
    └── mysql/

安全最佳实践

  1. 密钥管理

    # 使用AWS Secrets Manager管理数据库密码
    data "aws_secretsmanager_secret_version" "db_password" {
      secret_id = "mysql-master-password-stage"
    }
    
  2. 最小权限原则

    # 为EC2实例分配最小必要权限的IAM角色
    resource "aws_iam_role" "example" {
      name = "example"
      assume_role_policy = jsonencode({
        Version = "2012-10-17"
        Statement = [
          {
            Action = "sts:AssumeRole"
            Effect = "Allow"
            Principal = {
              Service = "ec2.amazonaws.com"
            }
          }
        ]
      })
    }
    

团队协作

工作空间管理

# 使用工作空间管理多环境
locals {
  environment = terraform.workspace
}

resource "aws_instance" "example" {
  instance_type = local.environment == "prod" ? "m5.large" : "t2.micro"
  ami           = "ami-0fb653ca2d3203ac1"
  
  tags = {
    Environment = local.environment
  }
}

CI/CD集成

# GitHub Actions工作流示例
name: Terraform CI/CD

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  terraform:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    
    - name: Setup Terraform
      uses: hashicorp/setup-terraform@v1
      
    - name: Terraform Format
      run: terraform fmt -check
      
    - name: Terraform Validate
      run: terraform validate
      
    - name: Terraform Plan
      run: terraform plan
      env:
        AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
        AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

故障排除和调试

常见问题解决

问题类型症状解决方案
状态文件冲突Error acquiring state lock检查并释放状态锁
资源依赖问题Circular dependency detected使用depends_on显式声明依赖
权限不足AccessDeniedException检查IAM策略和权限
网络问题Timeout waiting for LB检查安全组和网络ACL

调试技巧

# 启用详细日志
export TF_LOG=DEBUG
export TF_LOG_PATH=terraform.log

# 检查执行计划详情
terraform plan -detailed-exitcode

# 导入现有资源
terraform import aws_instance.example i-1234567890abcdef0

总结

通过《Terraform: Up & Running》的代码示例,我们系统学习了:

  1. 基础语法 - 资源、变量、输出的定义和使用
  2. 模块化设计 - 如何创建和调用可重用模块
  3. 状态管理 - 本地和远程状态的最佳实践
  4. 测试策略 - 单元测试和集成测试的实施
  5. 生产部署 - 多环境管理和CI/CD集成
  6. 团队协作 - 工作空间和版本控制策略

Terraform作为基础设施即代码的标准工具,通过声明式配置和强大的生态系统,为现代云原生应用提供了可靠的基础设施管理方案。掌握这些核心概念和实践,将帮助你在实际项目中构建可维护、可扩展的基础设施代码库。

记住,良好的Terraform实践不仅仅是编写配置,更重要的是建立可重复、可测试、可协作的工作流程。从简单的单实例部署开始,逐步扩展到复杂的多模块架构,让基础设施代码成为你技术栈中的强大资产。

【免费下载链接】terraform-up-and-running-code Code samples for the book "Terraform: Up & Running" by Yevgeniy Brikman 【免费下载链接】terraform-up-and-running-code 项目地址: https://gitcode.com/gh_mirrors/te/terraform-up-and-running-code

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值