【问题标题】:integrate jenkins on terraform with bitbucket将 terraform 上的 jenkins 与 bitbucket 集成
【发布时间】:2019-05-13 03:23:34
【问题描述】:

我为 aws 架构创建了 terraform 脚本,其中包括 ec2 实例和 ec2 上的 jenkins。我是 jenkins 的新手,并试图弄清楚如何使用现有的 terraform 脚本将它与 bitbucket 集成。 任何帮助将不胜感激。

【问题讨论】:

  • 您尝试结合 terraform、Jenkins 和 bitbucket 来实现什么?

标签: amazon-web-services jenkins bitbucket terraform terraform-provider-aws


【解决方案1】:

使用 terraform 将更改应用到基础架构的 CI/CD 管道工作流程:

  1. 开发人员或运维工程师在其本地计算机中更改 terraform 配置文件并将代码提交到 BitBucket。
  2. Gitbucket webhook 触发 jenkins 的持续集成作业。
  3. Jenkins 将从包含 terraform 文件的已配置存储库中提取最新代码到其工作区。
  4. 它读取 terraform 配置,然后初始化远程 consul 后端。
  5. Terraform 生成有关必须应用于基础架构的更改的计划
  6. Jenkins 将有关更改的通知发送到松弛通道以供手动批准。
  7. 在这里,用户可以批准或不批准 terraform 计划。
  8. 用户输入被发送到 jenkins 服务器以继续执行进一步操作。
  9. 一旦操作员批准更改,jenkins 将执行 terraform apply 命令以将更改反映到基础架构。
  10. Terraform 将创建一份关于执行计划时创建的资源及其依赖关系的报告。
  11. Terraform 将在提供程序环境中配置资源。
  12. Jenkins 将在应用更改后再次向松弛通道发送有关基础架构状态的通知。作业执行后,将配置 Jenkins 管道作业以清理作业创建的工作空间。

如何搭建部署环境?

  1. 在 gitlab 或 bitbucket 等 scm 工具中创建一个 repo,并将 terraform 配置及其依赖模块提交到 repo。如果您使用任何第三方远程模块作为依赖项,它将在执行时自动下载。
  2. 如果您没有 Jenkins 服务器,则只需拉取一个 jenkins docker 映像并在您的本地计算机上运行它。如果您在云环境中设置它,请检查市场上的 jenkins 虚拟机映像以设置环境并配置所需的插件。
  3. 在您的 bitbucket 存储库设置中创建一个 webhook,以调用对 jenkins 回调 url 的 http 调用,以触发持续集成作业。
  4. 如果您有现有的 jenkins 服务器,请确保在 jenkins 服务器中安装了管道插件。否则转到“管理插件”并安装管道插件。
  5. 在这个项目中,我们使用 consul 作为远程后端进行状态存储和状态锁定。对于多人参与项目和生产部署的情况,不建议使用本地状态。最好使用远程后端,它提供具有状态锁定功能的高可用性存储,以避免多个用户一次写入状态。
  6. 如果您的环境中没有 consul 键值存储,只需拉取 consul docker 映像并设置单节点集群。如果是生产部署,请设置分布式键值存储。
  7. 在 slack 中创建一个应用程序并记下用于在 Jenkinsfile 中配置它的 slack 集成详细信息。
  8. 在主要 terraform 配置文件中配置您的提供者详细信息和后端详细信息,可以通过环境变量或持久存储在存储库中。就我而言,我将在 AWS 中预置一个资源,并且我的 CI 服务器托管在 AWS 中。因此,我正在为我的服务器分配一个具有足够权限的 IAM 角色。
  9. 使用管道插件在 Jenkins 中创建一个新项目。
  10. 添加定义管道阶段的 Jenkinsfile。保存作业并手动触发它以进行测试。然后将更改应用到配置并将更改提交到 bitbucket 并确保自动触发作业。查看 Jenkins 日志以了解有关该作业的更多详细信息。

###Jenkinsfile###
import groovy.json.JsonOutput

//git env vars
env.git_url = 'https://user@bitbucket.org/user/terraform-ci.git'
env.git_branch = 'master'
env.credentials_id = '1'

//slack env vars
env.slack_url = 'https://hooks.slack.com/services/SDKJSDKS/SDSDJSDK/SDKJSDKDS23434SDSDLCMLC'
env.notification_channel = 'my-slack-channel'

//jenkins env vars
env.jenkins_server_url = 'https://52.79.46.98'
env.jenkins_node_custom_workspace_path = "/opt/bitnami/apps/jenkins/jenkins_home/${JOB_NAME}/workspace"
env.jenkins_node_label = 'master'
env.terraform_version = '0.11.10'

def notifySlack(text, channel, attachments) {
    def payload = JsonOutput.toJson([text: text,
        channel: channel,
        username: "Jenkins",
        attachments: attachments
    ])
    sh "export PATH=/opt/bitnami/common/bin:$PATH && curl -X POST --data-urlencode \'payload=${payload}\' ${slack_url}"
}

pipeline {
	agent {
		node {
			customWorkspace "$jenkins_node_custom_workspace_path"
			label "$jenkins_node_label"
		} 
	}
	
	stages {
		stage('fetch_latest_code') {
			steps {
				git branch: "$git_branch" ,
				credentialsId: "$credentials_id" ,
				url: "$git_url"
			}
		}

		stage('install_deps') {
			steps {
				sh "sudo apt install wget zip python-pip -y"
				sh "cd /tmp"
				sh "curl -o terraform.zip https://releases.hashicorp.com/terraform/'$terraform_version'/terraform_'$terraform_version'_linux_amd64.zip"
				sh "unzip terraform.zip"
				sh "sudo mv terraform /usr/bin"
				sh "rm -rf terraform.zip"
			}
		}

		stage('init_and_plan') {
			steps {
				sh "sudo terraform init $jenkins_node_custom_workspace_path/workspace"
				sh "sudo terraform plan $jenkins_node_custom_workspace_path/workspace"
				notifySlack("Build completed! Build logs from jenkins server $jenkins_server_url/jenkins/job/$JOB_NAME/$BUILD_NUMBER/console", notification_channel, [])
			}
		}

		stage('approve') {
			steps {
			  notifySlack("Do you approve deployment? $jenkins_server_url/jenkins/job/$JOB_NAME", notification_channel, [])
				input 'Do you approve deployment?'
			}
		}

		stage('apply_changes') {
			steps {
				sh "echo 'yes' | sudo terraform apply $jenkins_node_custom_workspace_path/workspace"
				notifySlack("Deployment logs from jenkins server $jenkins_server_url/jenkins/job/$JOB_NAME/$BUILD_NUMBER/console", notification_channel, [])
			}
		}
	}
	
	post { 
  	always { 
    	cleanWs()
   }
  }
}
###Code Completed###

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-07
    • 2019-05-30
    • 2015-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-12
    • 1970-01-01
    相关资源
    最近更新 更多