【DEVOPS】Ansible + Windows + Tomcat

关于如何使用Ansible实现Windows环境下的Tomcat自动安装部署。

1. 前言

为了在部门内部推进这DEVOPS,笔者感觉现在自学的新增知识里,运维性的内容占比是越来越大了,最近被列入书单目录的居然多了两本关于Ansible知识系统的,而且还把搁置了好几年的Powershell和BAT语法全部又捡回来了(笔者上一次接触Powershell还是在这篇2017年的博客【效率】Windows之QuickStart-续)。

1.1 几个疑问
  1. 为什么不部署到Linux?
    一言难尽。
  2. 为什么不用Docker?
    一言难尽。

好了,玩笑话到此结束,接下来让我们步入正文,本文延续之前的风格,尝试提供一站式解决方案,你找到这就算是到家了。当然也是非常欢迎读者提出各自的问题和困惑,笔者将保持文章的更新。

2. 准备工作

笔者是最近才开始沉下心研究Ansible,所以以下实现并没有完全遵从Ansible的最佳实践,目前阶段还是以实现功能为主,后期将在足够熟悉之后再回头进行相应的优化。

首先来看看目录结构:

# /etc/ansible/
		ansible.cfg
		batscript/  # 存放将要在目标Windows服务器上被执行的bat或ps1脚本, 这些脚本将被
		            # ansbile playbook拷贝到目标Windows服务器上. 至于为什么会有ps1脚本,
		            # 原因其实很简单, 因为笔者以.NET研发人员身份进入地这个行业, 并且时至          
		            # 今日都非常喜欢这个身份。
		hosts       # 配置远程服务的链接地址和登录信息等
		playbooks/  # playbook的集中地, 用yaml形式声明操作, 实现操作的持久化和配置化.
		    var-XXXX.json
		    windows_deploy_war.yaml
		    windows_destory_tomcat.yaml
		    windows_install_tomcat.yaml
		roles/      # 使用Role组织任务,可以将复杂的Playbook剧本进行拆分,达到缩小文件,任务重用的作用。本文中我们不会用到这个特性。
		software/   # 存放一些常用的安装包和软件, 降低网络带宽限制, 例如本次将要进行演示的tomcat。

介绍完整体的目录结构,接下来让我们看看主要的配置项:

# 配置将要被远程控制的Windows远程服务器地址
vi /etc/ansible/hosts
[windows_80]
xxx.16.3.80 ansible_ssh_user="Administrator" ansible_ssh_pass="xxxx@80" ansible_ssh_port=5985 ansible_connection="winrm" ansible_winrm_server_cert_validation=ignore

# 配置由多个playbook公用的全局变量参数配置文件.
vi /etc/ansible/playbooks/var-XXXX.json
{
     
 "ANSIBLE_HOME":"/etc/ansible",
 "tomcat_version":"7.0.72",
 "tomcat_install_dir_local":"/opt/",
 "tomcat_install_win_dir": "E:/_applications/XXXX/",
 "tomcat_server_name":"tomcat7XXXX",
 "project_name":"xxxx-shell"
}

3. playbook

对于能够找到本文,并阅读到这里的读者而言,playbook内容应该才是他们所作为关心的,所以这里我们将其作为单独的章节进行统一的描述。

本次示例中,一共有三个playbook。

3.1 windows_install_tomcat.yaml

本playbook作用是进行tomcat的安装,毕竟相较于应用的部署,tomcat的安装和配置频率并不高,所以这里进行单独处理。

- hosts: windows_80
  vars:
  vars_files:
    - var-XXXX.json 
  tasks:
    - name: copy tomcat software to remote host
      win_copy:  src={
     {
     ANSIBLE_HOME}}/software/apache-tomcat-{
     {
     tomcat_version}}-windows-x64.zip dest={
     {
     tomcat_install_win_dir}}    
    - name: unzip tomcat zip
      win_unzip: creates=yes src="{
     {
     tomcat_install_win_dir}}/apache-tomcat-{
     {
     tomcat_version}}-windows-x64.zip" dest="{
     {
     tomcat_install_win_dir}}" delete_archive=yes
    - name: copy  bat script for install tomcat server to dest windows server
      win_copy: src={
     {
     ANSIBLE_HOME}}/batscript/tomcatWindowsService4Install.bat dest={
     {
     tomcat_install_win_dir}}
    - name: copy  bat script for remove tomcat server to dest windows server
      win_copy: src={
     {
     ANSIBLE_HOME}}/batscript/tomcatWindowsService4Remove.bat dest={
     {
     tomcat_install_win_dir}}
    - name: copy ps1 for modify tomcat port to dest windows server
      win_copy: src={
     {
     ANSIBLE_HOME}}/batscript/tomcatWindows4ModifyPort.ps1 dest={
     {
     tomcat_install_win_dir}}
    - name: modify tomcat http/ajp port
      win_command: "powershell.exe -ExecutionPolicy ByPass -File {
     {tomcat_install_win_dir}}/tomcatWindows4ModifyPort.ps1 1888 1999 >> {
     {tomcat_install_win_dir}}/modifyTomcatPort.log"
    - name: install tomcat as windows server
      win_command: "cmd.exe /c {
     {tomcat_install_win_dir}}/tomcatWindowsService4Install.bat >> {
     {tomcat_install_win_dir}}/installTomcatServer.log"
      register: installtomcatserver_out
3.2 windows_destory_tomcat.yaml

本playbook负责tomcat服务的停止以及其他的清理工作。

---
- hosts: windows_80
  vars_files:
    - var-XXXX.json
  tasks:
    - name: stop tomcat server
      win_service:
        name: tomcat7XXXX
        state: stopped
    - name: remove tomcat windows server
      win_command: "cmd.exe /c {
     {tomcat_install_win_dir}}/tomcatWindowsService4Remove.bat >> {
     {tomcat_install_win_dir}}/removeTomcatServer.log"
      register: removetomcatserver_out
    - name: remove tomcat directory
      win_file: path={
     {
     tomcat_install_win_dir}}/ state=absent 
3.3 windows_deploy_war.yaml

本playbook负责WAR的发布。这个playbook是需要注意细节最多的,是最需要投入精力的。读者可以在本样例的基础上进行迭代。

---
- hosts: windows_80
  vars_files:
    - var-XXXX.json  
  tasks:
    - name: stop tomcat server
      win_service:
        name: tomcat7XXXX
        state: stopped
    - name: rm current project in tomcat/webapps/
      win_file: path={
     {
     tomcat_install_win_dir}}/apache-tomcat-{
     {
     tomcat_version}}/webapps/{
     {
     project_name}} state=absent
    - name:  download war form nexus
      win_get_url: url="http://xxx.xx.xxx.xx:xxx/nexus/service/local/repositories/snapshots/content/com/xx.war" dest="{
     {
     tomcat_install_win_dir}}/apache-tomcat-{
     {
     tomcat_version}}/webapps/"
    - name: rename war file name
      win_shell: |
         cd {
     {tomcat_install_win_dir}}/apache-tomcat-{
     {tomcat_version}}/webapps
         mv xx.war yy.war
    - name: Start tomcat server in windows server
      win_service:
        name: "{
     {tomcat_server_name}}"
        state: restarted
3.4 bat和ps1

秉承送佛送到西的原则,这里一并提供所有相关的bat和ps1脚本。

#### tomcatWindowsService4Remove.bat
cd %~dp0\apache-tomcat-7.0.72\bin
set CATALINA_HOME=%~dp0\apache-tomcat-7.0.72
rem 这里的服务名推荐以参数传入
%~dp0/apache-tomcat-7.0.72/bin/service.bat remove tomcat7XXXX

#### tomcatWindowsService4Install.bat
cd %~dp0\apache-tomcat-7.0.72\bin
set CATALINA_HOME=%~dp0\apache-tomcat-7.0.72
rem 这里的服务名推荐以参数传入
%~dp0/apache-tomcat-7.0.72/bin/service.bat install tomcat7XXXX

### modifyTomcatPort.ps1 (作废,此功能可以使用ansible自带的 win_lineinfile 模块来实现。具体实现可以参见下方的参考链接)
<#
    modifyTomcatPort.ps1 newHttpPort newAjpPort
#>

Function getParentDirPath($sFilePath){
     
    # https://blog.csdn.net/Q215046120/article/details/100123294
    $file = [io.fileinfo]$sFilePath;
    return $file.DirectoryName;
}

if($args.Length -lt 2){
     
    Write-Error "pass [newHttpPort], [newAjpPort]"
    return 
}

$newHttpPort=$args[0] # 18080
$newAjpPort=$args[1] #18009
#$newAjpRedirectPort=19443
$filePath = "$PSScriptRoot/apache-tomcat-7.0.72/conf/server.xml"
$newFilePath =  ($filePath -replace "server.xml", "server-tmp.xml")

$allLines = Get-Content $filePath
foreach($line in $allLines){
     
    # HTTP port
    if($line -match '){
     
        Write-Host "================当前行匹配" + $line
         ($line -replace $Matches.num, $newHttpPort)  | Out-File -Encoding utf8 -Append $newFilePath
        continue;
    }

    # AJP port
    if($line -match '){
     
        Write-Host "================当前行匹配AJP: " + $line
         ($line -replace $Matches.num2, $newAjpPort)  | Out-File -Encoding utf8 -Append $newFilePath
        continue;
    }
    
    # TODO更多的替换
   
    Write-Host "当前行不匹配" + $line
    #  Write-Output $line >> $newFilePath
	$line | Out-File -Encoding utf8 -Append $newFilePath
}

cd (getParentDirPath $filePath)
copy "server.xml" "server-bak.xml"
mv $newFilePath $filePath -Force

3.5 一些额外说明
  1. 为什么要将tomcat安装为服务?
    因为只有这样tomcat才能被指令启动,这也是笔者在很早之前接触到Ansible之后进过反复尝试才最终认命的结果。
  2. tomcat7的下载地址。
    这里笔者提供一个 tomcat7版本的官方下载地址 。
  3. 很多毛糙的地方。
    是的,这就是接下来改进的方向和动力。

4. Links

  1. 官方文档 - Ansible管理Windows
  2. 利用ansible实现tomcat自动安装和配置 这个的安装逻辑比较严谨,虽然是linux版的,但拿来参考还是绰绰有余的。

你可能感兴趣的:(DevOps,Ansible,devops,Ansible,Windows,Tomcat)