【ChatOps】通过golang + slack + ansible,从配置到部署
首先
这是关于使用Ansible Playbook作为部署工具,从Slack进行部署的故事。
背景:Background
-
- STG/PRD环境的EC2实例创建 -> 中间件安装 -> 部署,都是用ansible-playbook来执行的。
-
- 我也让开发团队执行了ansible-playbook命令。
-
- 各种环境的部署都是从EC2服务器上执行的。
-
- 在电子表格中,我记录了ansible-playbook在各个服务器和每个任务上的命令,并让他们执行。
- 之前我作为基础设施工程师一直在搭建AWS和日志分析监控基础设施,所以我几乎没有编程技能,所以我想借此机会学习一下golang。
问题和担忧
我想要解决的问题和担忧有以下三点。
-
- 存在执行命令时由于复制粘贴错误导致误执行的风险。
-
- 我们无法知道“谁”进行了执行。
- 如果没有登录服务器,就无法部署。
做好的东西 (zuò de
対象URLgo-slack-ansiblehttps://github.com/jkkitakita/go-slack-ansible

前提 (Qian ti)
我参考了Mercari的@deeeet所写的关于使用Golang编写Slack互动消息机器人的文章进行创建。
目錄結構
ansible
├ inventory
│ ├ stg
│ │ ├ group_vars
│ │ └ host
│ └ prd
│ ├ group_vars
│ └ host
go-slack-ansible
├ ansible
│ ├ config
│ │ └ config.go // ansible-playbookのconfig関連
│ ├ ansible_playbook.go // ansible-playbookで、provisioningとdeploy実行
│ ├ branch.go // デプロイするブランチを指定
│ ├ config.yaml // hostとrepoの対応一覧 & ansibleのtagの一覧
│ ├ const.go // 定数
│ ├ inventory_scanner.go // ansibleのinventoryを読み取って、対象ホストを取得
│ ├ tag.go // 指定するtagを取得する
│ └ terminate.go // ansible-playbookでサーバーのterminateを実行
├ cmd
│ └ bot
│ ├ handler.go //
│ ├ main.go // Slack Interactive Messages
│ └ slack.go //
├ config
│ └ config.go // logger等の設定
├ logger
│ └ logger.go // zapにて、logging
├ scripts
│ └ restart.sh // 再起動スクリプト
├ .env // slack BotID Channel,GitHub token etc...
├ go.mod
├ go.sum
└ Makefile
努力过的地方
我想保留前面讯息的情况。
只需一种方式,能够用中文进行改写:
通过观看上面的gif,您可以看到选择的主机和标签将在选择后显示在消息中。
为了覆盖现有消息的状态,需要在Slack互动消息中将replace_original设为true。
替换原始消息
https://api.slack.com/interactive-messages#building_workflows
如果不这样做

在这种情况下,会被浪费地发布。
而且,还可以重新编辑和选择之前的帖子。
对于使用nlopes/slack的这种情况来说。
originalMessage.ReplaceOriginal = true
通过将replace_original参数设置为true并进行每次覆盖,就可以实现这个功能。
在zap的日志记录器中添加logvel、caller和trace。
虽然和机器人完全没有关系,但试着想学习一下logger,之前尝试安装zap,但是发现它的文档很少,因此在添加logger方面遇到了一些困难,记录一下。当使用zap.New时,可以按照下面的方式传入参数:
return zap.New(
zapcore.NewCore(enc, w, zapConfig.Level),
zap.AddCaller(),
zap.AddStacktrace(zapcore.WarnLevel),
)
ex. INFO
{"severity":"INFO","timestamp":"2018-12-14T22:24:08.972+0900","caller":"go-slack-ansible/main.go:58","message":"[INFO] Start slack event listening"}
ex. WARN
{"severity":"WARN","timestamp":"2018-12-14T22:26:27.968+0900","caller":"go-slack-ansible/slack.go:71","message":"[WARN] Invalid bot: Jun Kitamura [10:22 PM]","trace":"main.(*SlackListener).handleMessageEvent\n\t/Users/jun.kitamura/go/src/go-slack-ansible/cmd/go-slack-ansible/slack.go:71\nmain.(*SlackListener).ListenAndResponse\n\t/Users/jun.kitamura/go/src/go-slack-ansible/cmd/go-slack-ansible/slack.go:37"}
以后的问题
-
- 一开始就没写test..对不起..
-
- 本来想用method来写,结果全部都成了普通的函数func..
- 结构体和接口还在学习中..
最后
这是我第一次尝试使用golang语言。
我使用了各种不同的参考书籍和文章进行学习。
代码和文章的构成都充满了可以插入的地方,我知道不知道从哪里关注会比较好,
如果有“这里不对吧!”或者“这里应该这样做!”之类的指正,随时都欢迎您
留下评论。我会非常高兴的。