AIOps系列 | 基础设施即代码


!! 大家好,我是乔克,一个爱折腾的运维工程,一个睡觉都被自己丑醒的云原生爱好者。


作者:乔克

公众号:运维开发故事

博客:jokerbai.com


✍ 道路千万条,安全第一条。操作不规范,运维两行泪。
最近在学习《AIOps》相关的知识课程,为了让学习有一定的收获,所以将其进行了总结分享,如果你恰好也需要,很荣幸能帮到你。

概述

AIOps 的时候为什么要讲 基础设施即代码(Infrastructure as Code,简称IaC) 呢?

在企业中,不论是先进的技术也好,还是优秀的思想也罢,终究都是服务于业务,这些业务都是部署在各种基础设施之上,包括 AIOps 本身的应用,所以可以理解 IaCAIOps 实现自动化的基础平台。

AIOps 的加持下,IaC 可以变得更聪明,比如:

  • 自动识别资源的浪费或瓶颈
  • 根据负载预测推荐最优的实例类型
  • 在部署失败的时候提供根因分析和修复建议

那什么是 基础设施即代码(以下简称IaC) 呢?

顾名思义,基础设施即代码(Infrastructure as Code,简称 IaC) 就是一种通过 代码 来定义、管理和部署 IT 基础设施的技术方法。换句话说就是 把以前"手动点击配置服务器"的过程,变成像写程序一样用"代码"来描述和部署基础设施。

举个例子,过去你可能这样做:

  • 登录云平台控制台
  • 手动创建 VPC、子网、安全组
  • 创建 EC2 实例并安装软件
  • 配置负载均衡器和数据库

现在你可以这样写一段代码(比如用 Terraform):

ini 复制代码
resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
}

然后运行:

复制代码
terraform apply

系统就会自动帮你创建一个 AWS 实例。

通过 IaC 可以将重复简单的工作简单化,它主要有以下优势:

特性

描述

🔁 可重复

每次部署都是一样的结果,避免"在我机器上能跑"的问题

📦 可版本化

使用 Git 管理基础设施的变更历史

🚀 可自动化

能与 CI/CD 流程集成,实现一键部署

🔄 易于扩展

快速复制环境(开发、测试、生产)

🛠️ 可维护性强

修改配置只需改代码,无需手动操作

常见的一些 IaC 工具有:

类型

工具

说明

声明式(Declarative)

Terraform、Kubernetes(YAML)、AWS CloudFormation

描述目标状态,工具负责实现

命令式(Imperative)

Ansible、SaltStack、Chef、Puppet

编写具体指令一步步执行

容器编排

Docker Compose、Helm Charts

定义容器化应用的部署结构

云厂商专用

AWS CDK、Azure Bicep

结合云平台特性的 IaC 工具

我们知道了 IaC 的优势以及常用的工具集,那我们具体能用它做什么呢?

我们可以:

  1. 通过声明式方式定义和创建基础设施,使基础设施的管理类似于编写代码,实现创建和更新的自动化。
  2. 统一管理所有资源,无论这些资源最初是否由IC工具创建或管理,都可以导入进行统一的管理,提升整体的资源管控效率。
  3. 提供更安全的基础设施更改流程,通过预先列出影响范围并经由工程师确认后再执行变更,确保更改的安全性和准确性。
  4. 与CICD工具整合,形成基础设施管理的自动化工作流,例如在工作流中自动开通开发环境所需的云基础设施,实现环境快速搭建和标准化。
  5. 提供可复用的模块,编写的IC代码可以作为模块供其他团队复用,促进团队间协作和代码的标准化使用,实现基础设施管理流程的标准化和高效性。

在众多 IaC 工具中, Terraform 一直是优选工具,所以下面会主要介绍 Terraform

什么是Terraform

TerraformIaC 的一个开源工具,它由 HashiCorp 开发,用于安全高效地 预配、管理和销毁基础设施资源 。它就像是一把"万能钥匙",你可以用它来创建服务器、数据库、网络、容器、负载均衡器等资源,而无需手动点击云平台界面或写脚本去一个个配置。

它的核心优势有:

Terraform 采用 HCL(HashiCorp Configuration Language) 语言来定义这些文档,HCL 比较简单易学,它是一种DSL(即领域特定语言),用于简化基础设施参数配置的复杂性,它具有以下优势:

  • 保留YAML和JSON的可读性优势,同时引入动态编程特性,使其在编写时类似编程语言,但专注于配置
  • 使用HCL描述和编写JSON对象时,代码变得更清晰且简洁

比如要在AWS上创建一台EC2,只需要使用 HCL 编写以下文档:

ini 复制代码
# main.tf

# 指定 AWS 提供商
provider "aws" {
  region = "us-west-2"
}

# 创建 EC2 实例
resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0" # Amazon Linux 2 AMI ID
  instance_type = "t2.micro"
}

运行 terraform initterraform apply 后,你的 AWS 控制台中就会出现这台新创建的 EC2 实例。

Terraform架构

Terraform 的执行过程中,主要包含以下几个组件配置:

  • Terraform Config:使用 HCL 编写的声明式配置,用于描述用户希望的状态
  • Terraform Core:它是Terraform的核心编排引擎,负责处理基础设施的变更,它会通过用户编写的HCL代码转换成期望的基础设施最终状态。
  • Terraform Provider:Provider是Terraform和云厂商通信的插件,负责将 HCL 配置映射为云平台的具体 API 请求。不同云厂商有不同的Provider,这些Provider一般由云厂商自己维护。
  • Terraform State:State文件用于记录当前基础设施的真实状态,由Terraform进行管理,用于保持配置和实际状态是一致的,当有变更操作的时候,Terraform就会对比期望状态和实际状态,然后生成对应的变更计划。

特别说明

  1. 注意 Provider 版本兼容性
  • 引入不同 Provider 时,需关注其版本,避免因上游更新导致代码异常或参数废弃。
  1. 推荐固定版本以确保稳定性
  • 建议使用固定版本号 ,防止因自动更新带来的不兼容问题。
  1. 使用"波浪号加大于号(~>)"进行版本约束
  • 这是一种悲观约束符 ,用于限制 Provider 的版本范围。
  • 它允许小版本更新(如 bug 修复、功能增强) ,但禁止大版本升级(可能带来破坏性变更)

比如,采用以下配置表示允许使用 5.0.05.999.999 之间的版本,但不会升级到 6.0

ini 复制代码
provider "aws" {
  version = "~> 5.0"
}

Terraform的核心命令

Terraform 的命令可以使用 terraform -help 来查看,这里介绍一个常用的命令。

基础命令

常用的基础命令有:

  • terraform init:初始化工作目录,下载provider插件等依赖
  • terraform plan:查看将要执行的操作,不会实际执行
  • terraform apply:执行配置,该命令执行后会实际执行
  • terraform destroy:销毁所有由terraform创建的资源

状态管理命令

常用的状态管理命令有:

  • terraform state list:列出当前状态中的所有资源
  • terraform state show <resource>:查看某资源的具体信息
  • terraform state rm <resource>:从状态中移除某个资源(不删除真实资源)
  • terraform state pull:从远端拉取状态到本地
  • terraform state push:更新本地的状态到远端
  • terraform refresh:从基础设施实际状态更新 state 状态
  • terraform import <resource> <id>:将已有资源导入到terraform中

查询与调试命令

常用的查询与调试命令有:

  • terraform show:显示当前状态文件的内容
  • terraform output:显示outputs中定义的输出值
  • terraform graph:生成资源配置的依赖图
  • terraform validate:检查配置语法是否正确

其他命令

还有一些比较实用的命令:

  • terraform fmt:格式化.tf文件,统一风格
  • terraform taint <resource>:标记某个资源为"污染",下次apply的时候重建
  • terraform workspace:管理多个环境(dev / staging / prod)

Terraform State

这里着重把 Terraform State 拿出来讲,是因为它是 Terraform 生命周期中必不可少的元素,它保存了真实基础设施的所有元数据。默认情况下,这些信息保存在一个名为 "terraform.tfstate" 的文件中。

Terraform 使用状态来创建执行计划并更改您的基础设施。当 Terraform 通过配置文件创建或者更改了远端对象时,它会将该远端对象的标识记录在与之对应的资源实例中,并保存在状态文件中,之后,Terraform 可能会根据未来的配置更改更新或删除该对象。

每个在资源块中创建的基础设施资源都是通过其resource_name在 Terraform 状态中进行标识的,其对资源的管理流程大致如下:

  • 当第一次通过 terraform apply 应用 Terraform 配置时,会创建基础设施资源,同时自动生成一个状态文件,该文件引用资源块中声明的名称
  • 如果一个资源已经在 Terraform 状态文件中有标识,那么 Terraform 会将配置文件与状态文件和当前的资源远端的实际状态进行比较,并根据比较结果,会生成一个执行计划
  • 当执行该计划时,它会更新资源的状态以匹配配置文件中的定义,如果由于远端 API 限制无法实现就地更新参数,那么该执行计划将会先销毁资源,然后再重新创建新的资源;如果是一个资源销毁的计划,将发起资源的销毁操作
  • 计划执行成功后,Terraform 状态文件会更新以反映当前的基础设施状态
  • 如果某资源已从当前 Terraform 配置中移除但在状态文件中仍然存在,Terraform 则会比较配置文件并销毁不再存在的资源

Terraform 默认将本地状态文件保存在当前工作目录中,扩展名为 .tfstate,因此它们不需要额外的维护。本地状态文件适用于只有一个开发人员工作的项目,当多个开发人员同时运行 Terraform 并且每台机器都有对当前基础设施的理解和配置时,默认的本地状态文件的配置方式就会变得棘手。

在团队协作开发场景中使用本地状态时主要存在以下几个问题:

  1. 本地状态没有共享访问权限:当使用 Terraform 更新你的基础设施,团队中的每个成员都需要访问相同的状态文件,这意味着这些文件必须存储在一个共享的位置,比如 ECS 实例特定的位置,而这无形增加了管理成本。
  2. 不能锁定本地状态文件:如果两个团队成员同时运行 Terraform,他们可能会遇到竞争条件,因为多个 Terraform 进程可能同时在更新状态文件。在这种情况下,可能带来导致冲突、数据丢失和状态文件损坏等风险。
  3. 本地状态文件不保密:当信息以明文形式存储在状态文件中时,敏感数据将存在被暴露的风险,例如数据库凭证,SSH 登录密码等。

因此,在团队协作开发的场景中,推荐使用远程替代本地存储,这种存储模式下会:

  • 远端状态文件会自动更新:每次使用 plan 或者 apply 命令的时候会自动从远端加载状态文件,每次执行apply之后也会把状态文件自动同步到远端存储中。
  • 远端状态文件支持状态锁定:当执行 terraform 的时候,可以对远端状态文件进行加锁,这样在多个开发人员同时运行 terraform apply 的时候不会因同时更新而损坏。
  • 远端状态文件存储比本地存储更安全:比如像 OSS 这类远端存储不仅支持精细化控制访问权限,还支持传输和远端加密功能。

比如采用 阿里云OSS 作为后端存储,其配置如下:

ini 复制代码
terraform {
  backend "oss" {
    bucket = "bucket-for-terraform-state"
    prefix   = "path/mystate"
    key   = "version-1.tfstate"
    region = "cn-beijing"
    tablestore_endpoint = "https://terraform-remote.cn-hangzhou.ots.aliyuncs.com"
    tablestore_table = "statelock"
  }
}

其中:

  • bucket:为阿里云OSS Bucket的名称
  • prefix:在Bucket中存放状态文件的路径前缀
  • key:状态文件的名称
  • region:Bucket所在区域
  • tablestore_endpoint:tablestore的访问地址,用于状态锁
  • tablestore_table:用于状态锁的tablestore表名

说明:当你运行 terraform applydestroy 时,Terraform 会尝试对状态文件加锁。如果已有其他人在操作,就会提示"lock failed",防止并发修改导致错误。

Terraform项目布局

任何项目的开发都需要比较好的项目布局,Terraform 也不例外,在简单的项目中推荐使用 Terraform Layout 的项目布局方式,将文件拆分成四个文件:

其中, main.tf 是业务的主逻辑,比如这里要创建一个EC2,定义如下:

ini 复制代码
resource "aws_instance" "my-example" {
   ami = "ami-xxxxxxx"
   instance_type = var.instance_type
}

这里的 var.instance_type 是定义的变量,所以我们还要创建一个 variables.tf,内容如下:

ini 复制代码
variable "instance_type" {
  description = "EC2 实例类型"
  default     = "t2.micro"
}

然后,我们喜欢得到创建后的EC2实例的IP,所以我们还要定义 outputs.tf,如下:

ini 复制代码
output "public_ip" {
  value = aws_instance.my-example.public_ip
}

另外,还有一个 version.tf,这个文件主要是用来固定版本的,避免上游版本变化导致脚本出现不可预知的BUG。其定义大概如下:

ini 复制代码
# versions.tf

terraform {
  required_version = ">= 1.6.0"

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

    random = {
      source  = "hashicorp/random"
      version = "~> 3.0"
    }

    # 示例:阿里云 Provider
    alicloud = {
      source  = "aliyun/alicloud"
      version = "~> 1.2.0"
    }
  }
}

如果项目比较复杂,可以将 main.tf 再进行拆分,比如我们要使用 terraform 部署 vpc、rds,则可以将其按模块进行拆分,如下:

css 复制代码
main.tf
variables.tf
outputs.tf
modules/
  └── vpc/
      ├── main.tf
      ├── variables.tf
      └── outputs.tf
  └── rds/
      ├── main.tf
      ├── variables.tf
      └── outputs.tf

然后在 main.tf 中去引用即可,如下:

ini 复制代码
module "vpc" {
  source = "./modules/vpc"

  cidr_block = "10.0.0.0/16"
  tags       = { Name = "my-vpc" }
}

如果你的项目涉及多个环境(dev/staging/prod),且要提高代码的复用,我们可以将目录结构定义如下:

r 复制代码
project-root/
├── environments/
│   ├── dev/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── outputs.tf
│   ├── staging/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── outputs.tf
│   └── prod/
│       ├── main.tf
│       ├── variables.tf
│       └── outputs.tf
├── modules/              # 可选:用于复用的模块
│   ├── vpc/
│   └── rds/
├── versions.tf           # 固定版本号(推荐)
└── backend.tf            # 远程后端配置(可选)

在具体使用的时候我们应该先创建 workspace ,然后再执行。比如要在 dev 环境执行命令,则用:

ruby 复制代码
$ terraform workspace new dev    # 创建 dev 的workspace
$ cd environments/dev            # 切换到dev的主入口
$ terrafotm apply --auto-approve # 在dev workspace 中创建资源
# 如果不清楚目前有哪些 workspace,可以使用 terraform workspace list 查看
$ terraform workspace list
# 如果想切换到某个 workspace,可以使用 terraform workspace select <workspace> 进行切换
$ terraform workspace select dev
# 如果要删除某个 workspace 中的资源,可以使用 terraform destroy --auto-approve 命令
$ terraform destroy --auto-approve

Terraform实战

下面我们将以 模块化 + 多环境支持 的方式设计这个 Terraform 项目,并以 阿里云(Alibaba Cloud) 平台为例进行说明。

Tips:代码未经调试,原因是没钱

整体的项目需求是:

  • 创建VPC
  • 创建ECS
  • 在ECS中部署K8S,版本是1.32.1
  • 在K8S中部署Nginx,版本是latest

整体的项目目录结构规划如下:

css 复制代码
terraform-k8s-on-ecs/
├── environments/
│   └── dev/
│       ├── main.tf
│       ├── variables.tf
│       └── outputs.tf
├── modules/
│   ├── vpc/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── outputs.tf
│   ├── ecs/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── outputs.tf
│   ├── k8s-install/
│   │   ├── main.tf
│   │   ├── install-k8s.sh
│   │   └── variables.tf
│   └── k8s-deploy-nginx/
│       ├── main.tf
│       └── nginx-deployment.yaml
├── versions.tf
└── providers.tf

1、固定版本号

ini 复制代码
# versions.tf

terraform {
  required_version = ">= 1.6.0"

  required_providers {
    alicloud = {
      source  = "aliyun/alicloud"
      version = "~> 1.2.0"
    }

    null = {
      source  = "hashicorp/null"
      version = "~> 3.0"
    }

    template = {
      source  = "hashicorp/template"
      version = "~> 2.0"
    }
  }
}

2、创建VPC模块

(1)定义变量
ini 复制代码
# modules/vpc/variables.tf

variable "vpc_name" {
  description = "VPC 名称"
  type        = string
}

variable "cidr_block" {
  description = "VPC CIDR"
  type        = string
  default     = "10.0.0.0/16"
}

variable "subnet_cidr" {
  description = "子网 CIDR"
  type        = string
  default     = "10.0.1.0/24"
}

variable "zone_id" {
  description = "可用区 ID"
  type        = string
}
(2)定义主入口
ini 复制代码
# modules/vpc/main.tf

resource "alicloud_vpc" "main" {
  vpc_name   = var.vpc_name
  cidr_block = var.cidr_block
}

resource "alicloud_vswitch" "main" {
  vswitch_name = "${var.vpc_name}-vsw"
  cidr_block   = var.subnet_cidr
  vpc_id       = alicloud_vpc.main.id
  zone_id      = var.zone_id
}

3、创建ECS模块

(1)定义变量
ini 复制代码
# modules/ecs/variables.tf

variable "instance_name" {
  description = "ECS 实例名称"
  type        = string
}

variable "image_id" {
  description = "镜像 ID(如 centos_7_9_x64_20G_alibase_20220310.vhd)"
  type        = string
}

variable "instance_type" {
  description = "实例类型(如 ecs.n4.small)"
  type        = string
}

variable "vpc_id" {
  description = "VPC ID"
  type        = string
}

variable "vswitch_id" {
  description = "VSwitch ID"
  type        = string
}

variable "zone_id" {
  description = "可用区 ID"
  type        = string
}

variable "root_password" {
  description = "ECS root 密码"
  type        = string
}
(2)定义主入口
ini 复制代码
# modules/ecs/main.tf

resource "alicloud_security_group" "k8s-node" {
  name   = "k8s-node-sg"
  vpc_id = var.vpc_id
}

resource "alicloud_instance" "k8s-master" {
  instance_name        = var.instance_name
  image_id             = var.image_id
  instance_type        = var.instance_type
  availability_zone    = var.zone_id
  system_disk_category = "cloud_efficiency"
  system_disk_size     = 40
  vswitch_id           = var.vswitch_id
  security_groups      = [alicloud_security_group.k8s-node.id]
  internet_max_bandwidth_out = 100
  password             = var.root_password
}

4、创建Kubernetes集群(采用kubeadm)

(1)创建安装K8S脚本
bash 复制代码
# modules/k8s-install/install-k8s.sh

#!/bin/bash

# 安装 Docker
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 
yum install -y docker-ce docker-ce-cli containerd.io
systemctl start docker
systemctl enable docker

# 安装 kubelet kubeadm kubectl
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64 
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg  https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg 
exclude=kube*
EOF

yum install -y kubelet-1.32.1 kubeadm-1.32.1 kubectl-1.32.1
systemctl enable kubelet
systemctl start kubelet

# 初始化集群
kubeadm init --pod-network-cidr=10.244.0.0/16

# 配置 kubectl
mkdir -p $HOME/.kube
cp /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config

# 安装 CNI(Flannel)
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml 
(1)定义变量
ini 复制代码
# modules/k8s-install/variables.tf

variable "ecs_public_ip" {
  description = "ECS 公网 IP"
  type        = string
}

variable "root_password" {
  description = "ECS root 密码"
  type        = string
}
(2)定义主入口
ini 复制代码
# modules/k8s-install/main.tf

resource "null_resource" "install_k8s" {
  connection {
    type     = "ssh"
    user     = "root"
    password = var.root_password
    host     = var.ecs_public_ip
  }

  provisioner "file" {
    source      = "${path.module}/install-k8s.sh"
    destination = "/root/install-k8s.sh"
  }

  provisioner "remote-exec" {
    inline = [
      "chmod +x /root/install-k8s.sh",
      "/root/install-k8s.sh"
    ]
  }
}

5、在K8S中部署Nginx

(1)、创建NG的Deployment
yaml 复制代码
# modules/k8s-deploy-nginx/nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: NodePort
(2)、定义变量
ini 复制代码
# modules/k8s-deploy-nginx/variables.tf

variable "ecs_public_ip" {
  description = "ECS 公网 IP"
  type        = string
}

variable "root_password" {
  description = "ECS root 密码"
  type        = string
}
(3)、定义主入口
ini 复制代码
# modules/k8s-deploy-nginx/main.tf

resource "null_resource" "deploy_nginx" {
  depends_on = [module.k8s-install]

  connection {
    type     = "ssh"
    user     = "root"
    password = var.root_password
    host     = var.ecs_public_ip
  }

  provisioner "file" {
    source      = "${path.module}/nginx-deployment.yaml"
    destination = "/root/nginx-deployment.yaml"
  }

  provisioner "remote-exec" {
    inline = [
      "kubectl apply -f /root/nginx-deployment.yaml"
    ]
  }
}

6、配置开发环境的主业务逻辑

ini 复制代码
# environments/dev/main.tf

# 创建 VPC
module "vpc" {
  source = "../../modules/vpc"

  vpc_name    = "dev-vpc"
  cidr_block  = "10.0.0.0/16"
  subnet_cidr = "10.0.1.0/24"
  zone_id     = "cn-beijing-a"
}

# 创建 ECS,依赖 VPC
module "ecs" {
  source = "../../modules/ecs"

  instance_name = "k8s-master"
  image_id      = "centos_7_9_x64_20G_alibase_20220310.vhd"
  instance_type = "ecs.n4.small"
  vpc_id        = module.vpc.vpc_id
  vswitch_id    = module.vpc.vswitch_id
  zone_id       = "cn-beijing-a"
  root_password = "your-root-password-123"
}

# 安装 Kubernetes,依赖 ECS
module "k8s-install" {
  source = "../../modules/k8s-install"

  ecs_public_ip = module.ecs.ecs_public_ip
  root_password = "your-root-password-123"

  depends_on = [module.ecs]  # 等 ECS 创建完成后再安装 K8s
}

# 部署 Nginx,依赖 Kubernetes 安装完成
module "deploy-nginx" {
  source = "../../modules/k8s-deploy-nginx"

  ecs_public_ip = module.ecs.ecs_public_ip
  root_password = "your-root-password-123"

  depends_on = [module.k8s-install]  # 等 K8s 安装完成后再部署应用
}

配置输出:

lua 复制代码
# environments/dev/outputs.tf

output "vpc_id" {
  value = module.vpc.vpc_id
}

output "ecs_public_ip" {
  value = module.ecs.ecs_public_ip
}

output "k8s_config" {
  value = "/root/.kube/config"
}

7、部署

当所有脚本开发完成后,为了保证后续的可扩展,整体的命令执行流程是:

shell 复制代码
# 切换到 dev 目录下
$ cd environments/dev
# 创建 dev workspace
$ terraform workspace new dev
# 初始化下载依赖
$ terraform init
# 预执行
$ terraform plan
# 执行部署
$ terraform apply

总结

综上所述,文章系统阐述了基础设施即代码(IaC)的核心概念、与AIOps的关联及显著优势,并聚焦IaC工具Terraform,深入解析其定义、架构、核心命令、状态管理、项目布局等关键内容,最后通过在阿里云平台部署VPC、ECS、K8S及Nginx的实战案例,完整呈现了Terraform在模块化和多环境支持下的应用流程。这不仅展现了IaC通过代码化管理基础设施的高效性与规范性,也为实际运维中利用Terraform实现自动化部署提供了清晰的思路与参考。

引用

1\] [developer.hashicorp.com/terraform/d...](https://link.juejin.cn?target=https%3A%2F%2Fdeveloper.hashicorp.com%2Fterraform%2Fdocs "https://developer.hashicorp.com/terraform/docs") \[2\] [help.aliyun.com/zh/terrafor...](https://link.juejin.cn?target=https%3A%2F%2Fhelp.aliyun.com%2Fzh%2Fterraform%2Fwhat-is-terraform%3Fspm%3Da2c4g.help-menu-95817.d_0_1.dee2c092b7ORVO "https://help.aliyun.com/zh/terraform/what-is-terraform?spm=a2c4g.help-menu-95817.d_0_1.dee2c092b7ORVO") 最后,求关注。如果你还想看更多优质原创文章,欢迎关注我们的公众号「**运维开发故事**」。 *** ** * ** *** 我是 乔克,《运维开发故事》公众号团队中的一员,一线运维农民工,云原生实践者,这里不仅有硬核的技术干货,还有我们对技术的思考和感悟,欢迎关注我们的公众号,期待和你一起成长!

相关推荐
架构师沉默7 分钟前
程序员如何避免猝死?
java·后端·架构
椰奶燕麦24 分钟前
Windows PackageManager (winget) 核心故障排错与通用修复指南
后端
zjjsctcdl1 小时前
springBoot发布https服务及调用
spring boot·后端·https
zdl6861 小时前
Spring Boot文件上传
java·spring boot·后端
世界哪有真情2 小时前
哇!绝了!原来这么简单!我的 Java 项目代码终于被 “拯救” 了!
java·后端
RMB Player2 小时前
Spring Boot 集成飞书推送超详细教程:文本消息、签名校验、封装工具类一篇搞定
java·网络·spring boot·后端·spring·飞书
重庆小透明2 小时前
【搞定面试之mysql】第三篇 mysql的锁
java·后端·mysql·面试·职场和发展
武超杰2 小时前
Spring Boot入门教程
java·spring boot·后端
IT 行者2 小时前
Spring Boot 集成 JavaMail 163邮箱配置详解
java·spring boot·后端
gelald3 小时前
JVM - 运行时内存模型
java·jvm·后端