【ChatOps】通过golang + slack + ansible,从配置到部署

首先

这是关于使用Ansible Playbook作为部署工具,从Slack进行部署的故事。

背景:Background

    1. STG/PRD环境的EC2实例创建 -> 中间件安装 -> 部署,都是用ansible-playbook来执行的。

 

    1. 我也让开发团队执行了ansible-playbook命令。

 

    1. 各种环境的部署都是从EC2服务器上执行的。

 

    1. 在电子表格中,我记录了ansible-playbook在各个服务器和每个任务上的命令,并让他们执行。

 

    之前我作为基础设施工程师一直在搭建AWS和日志分析监控基础设施,所以我几乎没有编程技能,所以我想借此机会学习一下golang。

问题和担忧

我想要解决的问题和担忧有以下三点。

    1. 存在执行命令时由于复制粘贴错误导致误执行的风险。

 

    1. 我们无法知道“谁”进行了执行。

 

    如果没有登录服务器,就无法部署。

做好的东西 (zuò de

go-slack-ansible-trim.gif

前提 (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

如果不这样做

go-slack-ansible-replace.gif

在这种情况下,会被浪费地发布。
而且,还可以重新编辑和选择之前的帖子。
对于使用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"}

以后的问题

    1. 一开始就没写test..对不起..

 

    1. 本来想用method来写,结果全部都成了普通的函数func..

 

    结构体和接口还在学习中..

最后

这是我第一次尝试使用golang语言。
我使用了各种不同的参考书籍和文章进行学习。

代码和文章的构成都充满了可以插入的地方,我知道不知道从哪里关注会比较好,
如果有“这里不对吧!”或者“这里应该这样做!”之类的指正,随时都欢迎您
留下评论。我会非常高兴的。

bannerAds