从Jenkins执行Cloudformation、Ansible的作业的流程
Jenkins执行作业的流程
* 这只是对流程的简单说明,省略了创建各种文件、安装方法等。
* 假设预先准备了用于应用程序的cloudformation堆栈和Ansible。
作为大致的流程,
1. 创建Jenkins服务器(EC2A)
↓
2. 启动Jenkins
↓
3. 执行各种任务(创建环境到EC2B)
– 克隆cloudformation堆栈的存储库任务
– 执行克隆的cloudformation堆栈任务
– 克隆Ansible的存储库任务
– 执行克隆的Ansible任务
如果有时间的话,我会在另一篇文章中提供链接。(待创建后附上链接)
补充:我已经创建了关于Jenkins和Github的集成文章。
使用Webhook来实现Jenkins和Github的协作。
设置当有内容推送到Github时,自动触发Jenkins启动。
・主要人物
詹金斯叔叔
构成图

## 环境
macOS Big Sur 版本11.2.2
在EC2上部署Jenkins服务器。
有几种方法可以选择:
1、手动创建。
2、使用CloudFormation。
3、使用Ansible。
无论哪种方法都可以(这里省略具体方法)。
补充:我创建了一个使用CloudFormation创建的文章。
*请打开SG端口22(用于SSH)和8080(用于Jenkins)。
*请使用IamUser创建Jenkins用户。
*如果不满足t2small或更高规格,服务器将会宕机。
*定义弹性IP将更加方便。
安装Jenkins(java版本)、Ansible和Git。
↓代码如下
$ sudo yum update -y
$ sudo amazon-linux-extras install -y ansible2
$ sudo yum install -y java-1.8.0-openjdk-devel.x86_64
$ sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat/jenkins.repo
$ sudo rpm --import https://pkg.jenkins.io/redhat/jenkins.io.key
$ sudo yum install -y jenkins git
$ sudo systemctl start jenkins
如果在云堆栈中使用CloudFormation来启动Jenkins服务器,如果CloudFormation的用户数据代码没有正常工作,则可以使用以下代码查看EC2实例启动时的日志:(sudo cat /var/log/cloud-init-output.log)
使用公共IP地址和端口8080登录Jenkins,然后进行设置(具体操作略)。
#各种任务执行
##●克隆云形成堆栈的存储库的任务
– 预先构建好的云形成堆栈(适用于应用程序的)从Github克隆回来的任务设置
使用t2micro实例可以。同时也要定义ElasticIP。根据需要也可能需要定义RDS和SG。还要为EC2安全组添加一个用于Rails的3000号端口。
・首先创建新的任务。
・输入任务名称⇨选择自由风格项目构建,并点击确定。
・在源代码管理中,从Github拉取Cloudformation的yaml文件(整个文件夹也可以)。
・将构建分支设置为*/main(或者master)(根据默认分支)。
・点击应用并保存。
・执行构建。
・这样,在/var/lib/jenkins/workspace目录下会有创建任务时的任务名称文件夹,其中包含从Github克隆过来的文件。
需要通过AWS CLI让Jenkins先生帮我们创建克隆的cloudformation堆栈,并执行相关任务。
首先,Jenkins用户需要将信息注册到EC2,以便可以使用CLI。
1, 现在检查是否已添加Jenkins用户
(在Linux系统上搜索用户确认)
使用sudo命令查看/etc/passwd文件
2、点击AWS控制台中IAM菜单下使用CloudFormation创建的IAM用户的名称。
3、从凭证中创建并复制访问密钥。
4、登录到EC2A并输入命令(sudo -u jenkins aws configure)。
5、输入之前复制的访问密钥和秘密密钥。
6、选择东京区域(ap-northeast-1),输出可以留空(或选择JSON格式)。
至此,jenkins用户通过aws configure创建完成。
在Shell的执行窗口中输入CLI命令来设置启动CloudFormation堆栈的配置。
需要两种类型的命令。
其中一个选项的中文释义是:执行堆栈命令(可以是aws cloudformation create-stack或aws cloudformation deploy)。同时,辅助命令的写法也各有不同。
2、请让Jenkins先生执行等待堆栈完全创建的命令(轮询处理),直到构建完成。(AWS CloudFormation等待堆栈创建完成)
在刚才克隆的云层模板(git clone)任务中重新打开配置,并在shell执行框中进行描述。
(从构建->添加构建步骤->调用shell执行框)
・書き方
aws cloudformation create-stack \
--stack-name (スタックの名前) \
--template-body file://$WORKSPACE/(アプリをデプロイするEC2環境を作る)cloudformationのyamlファイル
aws cloudformation wait stack-create-complete \
--stack-name (スタックの名前)
例1)
aws cloudformation create-stack \
--stack-name foo \
--template-body file://$WORKSPACE/new.yaml
aws cloudformation wait stack-create-complete \
--stack-name foo
例2)
aws cloudformation deploy \
--stack-name jenkins \
--template-file new.yml \
--parameter-overrides $(cat new_dev.cfg) \
--capabilities CAPABILITY_NAMED_IAM
aws cloudformation wait stack-create-complete \
--stack-name jenkins
* `$工作区=/var/lib/jenkins/建筑名称/`
请注意,如上所述,由于命令不同,附带命令的书写方式也不同。
请查询各个命令的含义。必须提供栈名称和模板名称。
在将堆栈命名反映在S3存储桶时,需要注意命名规则,如不能使用大写字母,并且必须保证唯一性。
如果能够输入,就保存并执行构建。
克隆Ansible存储库的操作。
Cloudformation的流程与以前相同
– 首先创建新的作业
– 输入作业名称,选择自由风格的项目构建,然后点击确定
– 从Github拉取Ansible文件(可以是整个文件夹)进行源代码管理
– 将要构建的分支设置为/main(或者master)(根据默认分支设置)
– 点击应用并保存
– 执行构建
– 这样,在/var/lib/jenkins/workspace中会有一个与作业名称相对应的文件夹,其中包含从Github克隆的文件。
・确认是否存储在/var/lib/jenkins/workspace
・确认jenkins用户是否能够使用Ansible
在shell命令栏中输入$ ansible –version,并执行作业
⇨如果能够执行,则可以确认已安装Ansible。
执行从克隆而来的Ansible作业。
将在本地定义的 Ansible 私钥传输到 Jenkins 服务器。
使用EC2A(Jenkins服务器)登录EC2B(目标节点)需要使用私钥和公钥
(前提是需要在EC2A和EC2B上创建相同的密钥)。
因为EC2A目前没有秘钥,所以无法从EC2A ssh到EC2B。
所以需要从本地复制秘钥到EC2A上。
尝试使用scp命令将文件发送到/var/lib/jenkins/.ssh,但是出现了权限被拒绝的错误。(因为jenkins仓库的权限属于jenkins用户)
首先将其复制到/home/ec2-user/.ssh
書き方
$ scp -i <EC2Bへのssh接続で使用する秘密鍵> <ローカルの秘密鍵ファイルPATH> <ユーザー名>@<接続先IPv4アドレス>:<秘密鍵の配置先PATH>
例
$ scp -i ~/.ssh/udemysample1.pem ~/.ssh/udemysample1.pem ec2-user@54.95.40.69:/home/ec2-user/.ssh/
请确认文件是否在.ls .ssh文件中传输
将位于/home/ec2-user/.ssh中的密钥复制到jenkins目录中
$ sudo cp ~/.ssh/udemysample1.pem /var/lib/jenkins/.ssh/
用ls -la命令确认Jenkins目录中的内容,应该具有.root权限的.ssh文件夹。
补充说明:此时.ssh文件夹存在,但是不知道为什么没有复制过去。难道不是蓝色的吗?
无论如何,如果尝试用cd命令进入.ssh文件夹,会显示”Not a directory”。此情况请参考下方的内容。
在/var/lib/jenkins目录下,使用sudo rm .ssh命令进行一次删除,
然后使用sudo mkdir -p .ssh命令进行创建。
接着再次使用sudo cp ~/.ssh/udemysample1.pem .ssh命令进行复制。
当我通过ls -la检查时,发现.ssh以蓝色字体存在。由于权限是root,需要将其更改为jenkins用户。
sudo chown -R jenkins:jenkins .ssh
将密钥复制到EC2A(jenkins服务器)下完成。
在Ansible任务的设置中,将命令写入到Shell执行字段中。
例
ansible-playbook -i inventory site.yml
由于Ansible文件夹的创建方式有很多种,所以请根据大家创建的文件夹结构来执行命令。
如果忘记更改 inventory 的公共 IP,请注意,如果是弹性 IP,则可以。
此外,通过添加 –check 标志可以进行虚拟执行(即实际上不会构建,而是用于测试)。
仮実行例
ansible-playbook -i inventory site.yml --check
保存并执行构建
到目前为止,已经从Jenkins成功执行了Cloudformation和Ansible的作业。
追加说明:
如果要通过Webhook进一步将Jenkins和Github进行连接,请参考以下文章。
续篇文章:
使用Webhook将Jenkins与Github进行连接。
当Github收到推送时,自动启动Jenkins。
## Jenkins 错误集合
错误1
– 在执行git clone任务时
“无法找到任何需要构建的版本。请验证此任务的存储库和分支配置。”
似乎是由于Github的默认分支引起的问题,比如主要的主分支或者是master分支。虽然具体原因不明,但问题已被解决。
更改了默认分支从main到master,然后又从master切换回main。
然后,在默认的main分支上合并了remotes/origin/master等分支。
(结果显示已是最新,即Everything up-to-date)
再次执行Jenkins任务成功了。
可能的中文翻译:
*解决方案(或许)
将构建分支的字段设置为*/main(或者master)(根据GitHub的默认分支而定)
然后从main(或master)仓库中拉取代码,如果与默认分支链接,我认为就可以同步。
错误2
·您必须指定一个地区。您也可以通过运行“aws configure”来配置您的地区。
创建一个与LINUX用户名称(使用“sudo cat /etc/passwd”命令显示的用户名称)相同的IAM用户名称来解决问题。在此情况下,需要创建jenkins用户,并使用aws configure命令在CLI中注册密钥。
错误3
– 无效的模板路径 file:///var/lib/jenkins/workspace~
原因是在使用CLI命令来描述CloudFormation堆栈时,file和body参数的编写方式不同。
「错误的示例)
– 模板文件 file://$WORKSPACE/new.yml」
正解例:
使用 AWS 云形成工具部署
— 模板文件 new.yml
或者
使用AWS CloudFormation创建堆栈
—-template-body file://$WORKSPACE/new.yml
错误4
– 在执行scp命令时
权限被拒绝(publickey,gssapi-keyex,gssapi-with-mic)
原因→只是命令输入错误
scp和-i的顺序
无论sudo放在哪里都可以
错误命令:
sudo -i scp ~/.ssh/udemysample1.pem ~/.ssh/udemysample1.pem ec2-user@54.95.40.69:/home/ec2-user/.ssh/
正确的命令:
scp -i ~/.ssh/udemysample1.pem ~/.ssh/udemysample1.pem ec2-user@54.95.40.69:/home/ec2-user/.ssh/
在Jenkins执行Ansible作业时出错:fatal:[54.95.40.69]:无法访问! => {“changed”: false, “msg”: “通过ssh连接主机失败:无法将主机添加到已知主机列表(/var/lib/jenkins/.ssh/known_hosts)。\r\n没有此身份:/var/lib/jenkins/.ssh/udemysample1.pem:不是一个目录\r\n权限被拒绝(publickey,gssapi-keyex,gssapi-with-mic)。”, “unreachable”: true}
某些原因下,Jenkins未能正确地复制密钥。
・其他还有无法访问的错误
Ansible配置文件中的设置内容
请先确认目标节点的地址(EC2B的地址,通过cloudformation创建)。
2、儲存鑰匙的位置
~/.ssh/udemysample1.pem
3、SSH连接目标的用户信息
ec2-user
在其他方面也有一些无关紧要的错误。
我不小心在s3stack名称中使用了大写字母。
在yml文件中,我将s3堆栈名称设置为了cfn模板文件的名称。
由于将Cfn模板文件名称包含大写字母,所以出现了错误。
Jenkins运行时,如何将在cloudformation创建的堆栈中设定的值应用到Ansible中呢,例如RDS的端点等。
如果以下三个点不改变,重新创建RDS实例的话,端点似乎不会改变。
-
- RDSのインスタンス識別子
-
- AWSアカウントID
- RDSインスタンスを配置するリージョン
⇨先试着恢复之前创建的RDS数据库
⇨确认成功。