在当今快节奏的软件开发领域,自动化至关重要。在本文中,我将向您展示如何构建一个全面的 DevOps 流水线,该流水线能够:
- 使用 Terraform 预置完整的 AWS 基础设施。
- 部署一个包含私有子网和公共子网、RDS PostgreSQL 以及完整配置的网络堆栈的 EKS 集群。
- 通过 Helm 安装关键的 Kubernetes 组件,包括 cert-manager(集成 Let’s Encrypt)、ingress-nginx、ArgoCD 和 SonarQube。
- 使用 GitLab CI/CD 流水线自动化基础设施和应用程序工作流。
让我们开始吧!
架构概览
我们的解决方案包含以下几个层级:
1. 基础设施配置:
我们将使用 Terraform 模块创建:
- 一个包含公有/私有子网、路由表、NAT 网关、IGW 和 EIP 的 VPC。
- 一个包含工作节点的 EKS 集群(使用成熟的 Terraform 模块)。
- 一个用于持久存储的 RDS PostgreSQL 实例。
- Route53 中的 DNS 管理,用于证书验证。
2. 通过 Helm 进行 Kubernetes 部署:
集群运行后,我们将部署:
- cert-manager(已为 Let’s Encrypt 配置 ClusterIssuer)用于管理 TLS 证书。
- ingress-nginx 作为我们的入口控制器。
- ArgoCD 用于基于 GitOps 的持续交付。
- SonarQube 用于静态代码分析。
3. 使用 GitLab 的 CI/CD 流水线:
我们设置了两个 GitLab 流水线:
- 一个用于管理 Terraform 代码(初始化、验证、规划和应用)。
- 另一个用于构建、测试(通过 SonarQube)和部署应用程序(从 new-app)。
1. 使用 Terraform 预配 AWS 基础设施
我们将首先创建一个模块化的 Terraform 项目。以下是简化的项目结构:
.
├── modules
│ ├── vpc
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── eks
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ └── rds
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
├── helm
│ ├── ingress-nginx-values.yaml
│ ├── argocd-values.yaml
│ ├── sonarqube-values.yaml
│ └── cert-manager-values.yaml
├── main.tf
├── variables.tf
├── outputs.tf
└── providers.tf
provider.tf
我们配置 AWS 以及 Kubernetes 和 Helm 提供程序。请注意,Kubernetes 提供程序使用来自我们 EKS 模块的输出:
// providers.tf
provider "aws" {region = var.aws_region
}
provider "kubernetes" {host = module.eks.cluster_endpointcluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)token = data.aws_eks_cluster_auth.cluster.token
}
provider "helm" {kubernetes {host = module.eks.cluster_endpointcluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)token = data.aws_eks_cluster_auth.cluster.token}
}
data "aws_eks_cluster_auth" "cluster" {name = module.eks.cluster_name
}
Variables.tf
定义 AWS、VPC、EKS 和 RDS 配置的变量:
// variables.tf
variable "aws_region" {description = "AWS region for resources"type = stringdefault = "us-west-2"
}
variable "vpc_cidr" {description = "CIDR block for the VPC"type = stringdefault = "10.0.0.0/16"
}
variable "public_subnet_cidrs" {description = "List of public subnet CIDRs"type = list(string)default = ["10.0.1.0/24", "10.0.2.0/24"]
}
variable "private_subnet_cidrs" {description = "List of private subnet CIDRs"type = list(string)default = ["10.0.101.0/24", "10.0.102.0/24"]
}
variable "availability_zones" {description = "List of availability zones to use"type = list(string)default = ["us-west-2a", "us-west-2b"]
}
variable "cluster_name" {description = "EKS Cluster name"type = stringdefault = "my-eks-cluster"
}
variable "db_username" {des