实战基于Gitlab+Jenkins+Terraform的基础设施自动化方案

举报
kaliarch 发表于 2024/08/06 22:58:50 2024/08/06
【摘要】 一 背景在当今快速发展的云计算时代,企业对基础设施的管理需求越来越复杂,传统的手工管理方式已经无法满足快速迭代、高效运维的需求。为了应对这一挑战,基础设施自动化应运而生,它利用自动化工具将基础设施的配置、部署和管理流程自动化,从而提高效率、降低成本、增强安全性。1. 传统基础设施管理的痛点效率低下: 手工配置和部署基础设施需要大量时间和人力,无法满足快速迭代的需求。错误率高: 手工操作容易出...

一 背景

在当今快速发展的云计算时代,企业对基础设施的管理需求越来越复杂,传统的手工管理方式已经无法满足快速迭代、高效运维的需求。为了应对这一挑战,基础设施自动化应运而生,它利用自动化工具将基础设施的配置、部署和管理流程自动化,从而提高效率、降低成本、增强安全性。

1. 传统基础设施管理的痛点

  • 效率低下: 手工配置和部署基础设施需要大量时间和人力,无法满足快速迭代的需求。
  • 错误率高: 手工操作容易出现错误,导致系统故障或安全漏洞。
  • 难以维护: 手工管理的配置难以追踪和维护,难以保证一致性。
  • 成本高昂: 人工成本、运维成本、故障修复成本等都比较高。

2. 基础设施自动化的优势

  • 提高效率: 自动化工具可以快速完成基础设施的配置和部署,大大提高效率。
  • 降低错误率: 自动化工具可以确保配置的准确性和一致性,降低错误率。
  • 增强可维护性: 自动化工具可以记录配置和操作日志,方便追踪和维护。
  • 降低成本: 减少人工成本、运维成本、故障修复成本。

3. Jenkins和Terraform的应用场景

  • 持续集成和持续交付 (CI/CD): 使用Jenkins构建自动化流程,并使用Terraform管理基础设施,实现快速、可靠的CI/CD流程。
  • 多云管理: 使用Terraform管理不同云平台上的基础设施,实现多云部署和管理。
  • 基础设施即代码 (IaC): 将基础设施配置以代码的形式进行管理,提高可重复性和可控性。
  • 云原生应用开发: 使用Terraform管理云原生应用所需的基础设施,例如容器、Kubernetes集群等。

二 相关概念

1. Jenkins

  • 持续集成与持续交付 (CI/CD) 平台: Jenkins是一个开源的自动化服务器,提供了一个平台用于构建、测试和部署软件。它可以自动执行构建、测试和部署流程,帮助开发者更快地将代码交付到生产环境。
  • 强大的插件生态系统: Jenkins拥有丰富的插件系统,支持各种语言、工具和云平台,可以满足不同的自动化需求。
  • 灵活的配置: Jenkins提供灵活的配置选项,可以根据不同的需求定制自动化流程。

2. Terraform

  • 基础设施即代码 (IaC) 工具: Terraform是一个开源的基础设施即代码工具,允许用户使用声明性配置语言定义和管理基础设施资源。
  • 支持多种云平台: Terraform支持多种云平台,包括AWS、Azure、GCP、阿里云等。
  • 强大的资源模型: Terraform提供丰富的资源模型,可以管理各种基础设施资源,例如虚拟机、网络、存储、数据库等

三 架构及详解

3.1 架构

3.2 工作流程

代码变更: 开发者将代码推送到代码仓库。

Jenkins 触发: Jenkins 自动检测到代码变更,并触发构建流程。

执行 Terraform: Jenkins 调用 Terraform,执行基础设施的创建或更新操作。

部署应用: Jenkins 部署应用程序到创建好的基础设施环境中。

四 实战

4.1 创建一个Jenkins Job

在Jenkins主页上,单击新建项目按钮。然后为管道命名并选择管道项目类型。

4.2 添加插件和安装软件

  • Jenkins中安装Terraform

系统工具配置

如果安装失败,可以使用agent或者在jenkins服务器配置terraform命令

sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo

# 查看制定版本
yum --showduplicates list |grep terraform
# 查看制定版本
repoquery --show-duplicates terraform

# 安装制定版本
terraform install -y terraform-0:1.5.0-1.x86_64
  • 添加pollscm插件。

4.3 开发代码并上传到Gitlab仓库

Jenkinsfile

pipeline {
    agent any
    parameters {
        choice(name: 'ACTION', choices: ['apply', 'plan','destroy'], description: 'What action should Terraform take?')
    }
    environment {
        TENCENTCLOUD_SECRET_ID = credentials('secret_id')
        TENCENTCLOUD_SECRET_KEY = credentials('secret_key')
    }
    stages {
        stage('apply/destory') {
            steps {
                script {
                        dir('cloud/tencent') {
                            sh 'terraform init'
                            sh 'terraform validate'
                            if (params.ACTION == 'plan') {
                                sh "terraform plan"
                            } else {
                               sh "terraform ${params.ACTION} -auto-approve"
                            }
                        }
                }
            }
        }
    }
}

tf文件核心

variable "region" {
  type    = string
  default = "ap-hongkong"
}

variable "instance_name" {
  type = string
  default = "iac"
}

variable "password" {
  type = string
  default = "Wxxxxxm"
}


variable "os_name" {
  type    = string
  default = "CentOS 7"
}

variable "username" {
  type    = string
  default = "root"
}

locals {
  cidr_block_vpc_name    = "10.0.0.0/16"
  cidr_block_subnet_name = "10.0.1.0/24"
  count                  = 1
  install_v2ray = "install.sh"
  v2ray_port  = 8080
  v2ray_id = "65xxxx076"
  # 密钥管理公钥
  # public_key_content = file("/Users/xuel/.ssh/id_rsa.pub")
  # 私钥
  # privile_key_file = "/Users/xuel/.ssh/id_rsa"
//  public_key_content = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDxxxx"
  tag = {
    name = "xuel"
  }
  username = can(regex("^(?i)ubuntu.*", lower(var.os_name))) ? "ubuntu" : var.username
}

data "template_file" "v2ray" {
  template = file(format("./scripts/%s", local.install_v2ray))
  vars = {
    V2RAY_PORT = local.v2ray_port
    V2RAY_ID = local.v2ray_id
  }
}

data "tencentcloud_images" "image" {
  image_type = ["PUBLIC_IMAGE"]
  os_name    = var.os_name
}

data "tencentcloud_instance_types" "instanceType" {
  cpu_core_count = 8
  memory_size    = 16

  filter {
    name   = "instance-charge-type"
    values = ["POSTPAID_BY_HOUR"]
  }
}

data "tencentcloud_availability_zones_by_product" "zone" {
    product = "cvm"
}


resource "tencentcloud_vpc" "vpc" {
  cidr_block = local.cidr_block_vpc_name
  name       = "xuel_tf_vpc"
  tags = local.tag
}

resource "tencentcloud_subnet" "subnet" {
  availability_zone = data.tencentcloud_availability_zones_by_product.zone.zones[0].name
  cidr_block        = local.cidr_block_subnet_name
  name              = "xuel_tf_subnet"
  vpc_id            = tencentcloud_vpc.vpc.id
  tags = local.tag
}

resource "random_string" "random" {
  length  = 4
  special = false
  numeric = true
}
 
# resource "tencentcloud_key_pair" "xuel-tf-key" {
#    key_name   = "xuel_tf_publickey_${random_string.random.result}"
#    public_key = local.public_key_content
# }



resource "tencentcloud_instance" "xuel_tf_ansible" {
  availability_zone = data.tencentcloud_availability_zones_by_product.zone.zones[0].name
  image_id          = data.tencentcloud_images.image.images[0].image_id
  # image_id = "img-mbw2jx7s"
  instance_type     = data.tencentcloud_instance_types.instanceType.instance_types[0].instance_type
  vpc_id            = tencentcloud_vpc.vpc.id
  subnet_id         = tencentcloud_subnet.subnet.id
  //  allocate_public_ip = true
  system_disk_size = 50
  # system_disk_type = "CLOUD_PREMIUM"
  system_disk_type = "CLOUD_BSSD"
  #system_disk_type = "CLOUD_SSD"  
  # key_name         = tencentcloud_key_pair.tf-key.id
  password = var.password
  allocate_public_ip = true
  internet_max_bandwidth_out = 40

  # data_disks {
  #   data_disk_size = 50
  #   data_disk_type = "CLOUD_SSD"
  # }
  hostname             = format("xuel-tf-v2ray-%d", count.index)
  instance_charge_type = "POSTPAID_BY_HOUR"
  count                = local.count
  instance_name        = var.instance_name

  tags = {
    tagkey = "xtf_20240110"
  }
}

resource "null_resource" "shell" {
  count = local.count

  triggers = {
    instance_ids = element(tencentcloud_instance.xuel_tf_ansible.*.id, count.index)
  }
  provisioner "remote-exec" {
    connection {
      host        = element(tencentcloud_instance._tf_ansible.*.public_ip, count.index)
      type        = "ssh"
      user        = local.username
      password = var.password
      timeout = 100000
    }

    inline = [
      // 安装脚本
      data.template_file.v2ray.rendered
    ]
  }
}


output "summary" {
  sensitive = true
  value = {

    //    image = {for k,v in data.tencentcloud_images.image:k=>v}
    //    instanceType = {for k,v in data.tencentcloud_instance_types
    //    .instanceType:k=>v}
    //    zone = {for k,v in data.tencentcloud_availability_zones.zone: k=>v}
    instance = { for k, v in tencentcloud_instance.xuel_tf_ansible : k => v }
  }
}

output "public_ip" {
  value = tencentcloud_instance.xuel_tf_ansible[0].public_ip  
}


output "username" {
  value = local.username
}

# output "instance_type" {
#   value = data.tencentcloud_images.image
# }

output "image_list" {
  value = {for k, v in data.tencentcloud_images.image: k => v}
}

provider "tencentcloud" {
  region = var.region
  # secret_id = var.secret_id
  # secret_key = var.secret_key

}

terraform {
  required_providers {
    tencentcloud = {
      source = "tencentcloudstack/tencentcloud"
      version = "1.79.3"
    }
  }
}

脚本文件

yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
                  
yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2
yum-config-manager \
    --add-repo \
    https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install docker-ce docker-ce-cli containerd.io -y
sudo systemctl start docker
sudo systemctl enable docker

目录结构

上传到git仓库

4.3 配置作业信息

现在,为这个管道作业填写一些细节。您可以添加Poll SCM来配置Jenkins定期轮询GitHub。该计划遵循cron的语法。例如,如果我们想每两分钟轮询一次,我们将在“管道”下使用:H/2****,从SCM、Git for SCM、我们的存储库URL和主分支中选择管道脚本。

  • 添加gitlab凭据,用于jenkins登录gitlab

  • 配置任务

注意gitlab触发的分支,以及Jenkinsfile在项目中的存放路径。

  • 创建腾讯秘钥认证信息

针对敏感信息需要加密存储。

配置:Dashboard > ⚙ Manage Jenkins > Credentials

  • 测试构建

由于Jenkinsfile中编写有参数化构建

部署选择apply

已成功安装软件和编排腾讯云

销毁选择destory

由于同一个流水线使用的为Jenkins本地的磁盘, /var/lib/jenkins/workspace/terraform-qcloud/cloud/tencent

同一个流水线不需要其他外部存储或者terraform的backend,存储在本地

五 注意事项

权限管理: 确保 Jenkins 用户具有足够的权限来执行 Terraform 命令。

安全配置: 使用合适的密码和密钥管理策略来保护敏感信息。

版本控制: 将 Terraform 配置文件保存在代码仓库中,并使用版本控制工具进行管理。

测试和验证: 在正式部署之前,要进行充分的测试和验证。

六 参考链接

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。