一、基础设施即代码(IaC)到底在折腾什么?

咱们搞DevOps的兄弟都知道,传统的基础设施管理方式简直就是在玩火。想象一下,每次部署新环境都要手动配置服务器、安装软件、调整网络,这跟用算盘算账有什么区别?IaC的出现就是为了解决这个痛点。

举个真实的例子,我们团队去年接手了一个电商项目,需要同时管理开发、测试、预发布和生产四套环境。刚开始还傻乎乎地手动操作,结果有次生产环境配置漏了一个参数,直接导致双十一当天支付系统瘫痪了2小时。老板的脸黑得跟锅底似的,从那以后我们就铁了心要上IaC。

二、Terraform实战中的那些坑

我们选择Terraform作为主要技术栈,毕竟它是多云支持的扛把子。但真正用起来才发现,理想很丰满,现实很骨感。

2.1 状态文件管理的噩梦

刚开始我们天真地把terraform.tfstate文件放在本地,结果团队里新来的小哥不小心覆盖了状态文件,整个环境直接崩了。后来我们改用S3后端存储,才算解决了这个问题。

# 使用S3作为Terraform后端存储的配置示例
terraform {
  backend "s3" {
    bucket = "my-terraform-state-bucket"
    key    = "path/to/my/key"  # 建议按项目/环境分级存储
    region = "us-west-1"
    
    # 启用状态锁防止并发修改
    dynamodb_table = "terraform-locks"
    encrypt        = true  # 加密存储敏感信息
  }
}

2.2 模块化的纠结

项目大了之后,资源配置文件越来越臃肿。我们尝试模块化拆分,但又遇到了版本控制的难题。最后采用了类似下面这种结构:

modules/
├── network/           # 网络相关资源
│   ├── main.tf
│   ├── variables.tf
│   └── outputs.tf
├── database/          # 数据库相关
└── compute/           # 计算资源
environments/
├── dev/               # 开发环境
├── staging/           # 预发布
└── production/        # 生产环境

三、Ansible带来的救赎

光有Terraform还不够,配置管理这块我们选了Ansible。这玩意学习曲线平缓,YAML写起来也比Terraform的HCL舒服多了。

3.1 动态Inventory的妙用

当服务器数量多了之后,静态Inventory文件就是个灾难。我们搞了个动态Inventory脚本,直接从AWS API拉取实例信息:

# ansible.cfg配置示例
[defaults]
inventory = ./inventory/aws_ec2.py
host_key_checking = False
private_key_file = ~/.ssh/aws_key.pem

# 动态Inventory脚本使用示例
ansible -i aws_ec2.py -m ping tag_Environment_Dev

3.2 角色(Role)的组织艺术

Ansible的Role功能让配置管理变得井井有条。比如部署一个Nginx服务:

roles/nginx/
├── tasks/
│   ├── main.yml       # 主任务
│   └── configure.yml  # 配置任务
├── templates/
│   └── nginx.conf.j2  # 模板文件
└── vars/
    └── main.yml       # 变量定义

四、多云环境下的生存法则

现在的项目动不动就要跨云部署,我们在AWS和阿里云之间反复横跳,总结出一些血泪经验。

4.1 Provider的抽象层

为了兼容不同云平台,我们抽象了一个Provider层:

# 抽象Provider配置
variable "cloud_provider" {
  description = "Target cloud platform"
  type        = string
  default     = "aws"
}

locals {
  provider_config = {
    aws = {
      instance_type = "t3.medium"
      region        = "us-east-1"
    }
    aliyun = {
      instance_type = "ecs.c6.large"
      region        = "cn-hangzhou"
    }
  }
}

resource "aws_instance" "example" {
  count         = var.cloud_provider == "aws" ? 1 : 0
  instance_type = local.provider_config.aws.instance_type
  # 其他AWS特有配置...
}

4.2 网络互联的坑

跨云网络互联是个大坑,我们最后采用了VPN+专线的方案。在Terraform中这样配置:

# 跨云网络连接配置
resource "aws_vpn_connection" "to_aliyun" {
  vpn_gateway_id      = aws_vpn_gateway.main.id
  customer_gateway_id = aws_customer_gateway.aliyun.id
  type                = "ipsec.1"
  
  # 路由配置
  static_routes_only = true
}

resource "aws_vpn_connection_route" "aliyun" {
  destination_cidr_block = "10.0.0.0/16"  # 阿里云VPC网段
  vpn_connection_id     = aws_vpn_connection.to_aliyun.id
}

五、安全与合规的平衡术

安全团队天天追着我们屁股后面要审计报告,IaC在这方面反而成了救星。

5.1 策略即代码

用Terraform的Sentinel或者Open Policy Agent(OPA)实现合规检查:

# OPA策略示例:禁止公开的S3存储桶
deny[msg] {
    input.resource_type == "aws_s3_bucket"
    input.change.after.acl == "public-read"
    msg = "S3 buckets cannot be set to public-read"
}

5.2 秘密管理

刚开始我们把密码直接写在Terraform变量里,被安全团队骂得狗血淋头。后来改用Vault:

# 集成HashiCorp Vault获取数据库密码
data "vault_generic_secret" "db_creds" {
  path = "secret/data/prod/database"
}

resource "aws_db_instance" "default" {
  # ...
  password = data.vault_generic_secret.db_creds.data["password"]
}

六、CI/CD管道的完美闭环

IaC不和CI/CD结合就是耍流氓。我们在GitLab CI中实现了这样的流程:

# .gitlab-ci.yml示例
stages:
  - validate
  - plan
  - apply

terraform:validate:
  stage: validate
  script:
    - terraform init -backend=false
    - terraform validate

terraform:plan:
  stage: plan
  script:
    - terraform plan -out=planfile
  artifacts:
    paths:
      - planfile

terraform:apply:
  stage: apply
  script:
    - terraform apply -input=false planfile
  when: manual  # 生产环境需要手动确认
  only:
    - master

七、监控与漂移检测

基础设施建好了不是就完事了,我们吃过配置漂移的大亏。现在用这样的方案:

# 漂移检测脚本示例
#!/bin/bash
terraform plan -detailed-exitcode
case $? in
    0)
        echo "No changes"
        ;;
    1)
        echo "Error"
        exit 1
        ;;
    2)
        echo "Drift detected!"
        # 触发告警
        ;;
esac

八、团队协作的那些事儿

IaC改变了我们整个团队的工作方式,也带来了一些新问题。

8.1 代码评审文化

现在每个基础设施变更都要走PR流程,比如这样的评审要点:

  1. 变量是否有合理的默认值?
  2. 敏感信息是否妥善处理?
  3. 资源命名是否符合规范?
  4. 是否有适当的销毁策略?

8.2 知识共享机制

我们建立了这样的知识库结构:

knowledge-base/
├── terraform-best-practices.md
├── ansible-patterns/
│   ├── zero-downtime-deployment.md
│   └── rolling-updates.md
└── incident-reports/  # 事故复盘
    ├── 2021-03-s3-outage.md
    └── 2021-08-dns-failure.md

九、未来展望:IaC的进化方向

虽然我们已经趟过了很多坑,但IaC领域还在快速发展。我们正在关注这些新趋势:

  1. 多云服务目录(Service Catalog)的IaC管理
  2. 基于机器学习的基础设施优化建议
  3. 更智能的变更影响分析
  4. 与Service Mesh的深度集成

十、给后来者的忠告

最后给准备上IaC的团队几点建议:

  1. 从小处着手,先拿非关键环境试水
  2. 状态管理方案要优先考虑
  3. 建立完善的备份机制
  4. 文档比代码更重要
  5. 定期进行销毁重建测试

记住,IaC不是银弹,但它确实能让你的基础设施管理从石器时代进入工业时代。关键是找到适合你团队的节奏和工具链组合。