11
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Jenkins PipelineでAnsibleを使ってファイル転送をさくっと行う

Last updated at Posted at 2017-12-20

はじめに

  • Jenkinsサーバから、成果物やその他ファイルをリモートホストへ転送する方法を紹介します
  • Jenkins PipelineとAnsibleを組み合わせたらシンプルに実装ができました

経緯

  • 今まで以下の組み合わせでやっていてイケてなさすぎたので、最近のイケてるツールで実装してみたかった
    • JenkinsジョブのGUI設定 + scpでのファイル転送(expectでPASSWORD入力)

補足

  • Jenkinsfileとは?

    • Jenkins2.0からビルトインで提供されている機能。今までジョブの設定はWebUIベースであったが、DSL(Groovy)を記述することでジョブの設定が可能になる
  • Ansibleとは?

    • サーバの構成管理ツール。YAML形式でタスクを定義することで様々な処理を自動化することが可能

イメージ図

overview.png

Jenkinsで使用するリポジトリの構成

  • 今回はGitlabを使用していますが、GitHub,SVNなんでもよいです

  • 簡単なサンプルはこちらGithub

.
jenkinsfile/
    deploy_file.groovy              # Jenkinジョブで呼び出すJenkinsfile

ansible/
    ansible.cfg
    hosts                           # リモートホストの接続情報を定義
    deploy_local_file.yml           # Ansible taskファイル

    deploy_files/                   # 転送するファイルの一時置き場
        test.txt

検証環境

  • CentOS 7
  • Jenkins ver. 2.73.1
  • ansible 2.4.0.0

実行サンプル

  • まずはどんな感じで使えるかをサンプルで

Jenkinsジョブ設定

Pipelineジョブの作成

jenkins-job-create.png

Pipeline設定

jenkins-job-setting.png

Jenkinsジョブ実行

  • ※ Jenkinsfileでパラメータを設定する場合、一度ジョブを実行してJenkinsfileを呼び出さないとジョブの設定に反映されません

パラメータ付ビルド

jenkins-job-execute.png

jenkins-job-result.png

  • ファイルが転送されました!
[remote_user@remote_host ~]$ ls -l /tmp/test.txt
-rw-r--r-- 1 remote_user group 5 xxx xx yy:yy /tmp/test.txt

ソースコードを書けばあとはジョブの設定して、実行するだけです!

これから中で何が動いているのかを記載します

仕組み解説

  • 今回の例
    • 転送するローカルファイル: test.txt
    • 転送先リモートホスト: stg の /tmp配下

Ansible

実行するtask

  • 今回使用するAnsibleモジュールはcopyモジュールです

  • taskファイルは以下

    • 変数は実行時にextra-varsとして渡します
deploy_local_file.yml
- hosts: '{{ host }}'
  tasks:
   - copy:
       src: '{{ local_path }}'
       dest: '{{ remote_path }}'
       force: yes

hosts

  • 複数リモートホストを定義しています。今回は環境ごとにホストを定義しました
  • Jenkinsジョブのパラメータとして指定できるようにします
## prd
[prd]
192.168.10.100

[prd:vars]
ansible_ssh_port=22
ansible_ssh_user="remote_user"
ansible_ssh_pass="password"

## stg
[stg]
192.168.20.100

[stg:vars]
ansible_ssh_port=22
ansible_ssh_user="remote_user"
ansible_ssh_pass="password"

## dev
[dev]
192.168.30.100

[dev:vars]
ansible_ssh_port=22
ansible_ssh_user="remote_user"
ansible_ssh_pass="password"
  • 今回は環境識別子でホストを定義していますが、以下のように定義することも可能です
## web server
[web]
192.168.10.200

[web:vars]
ansible_ssh_port=22
ansible_ssh_user="remote_user"
ansible_ssh_pass="password"

呼び出し方法

  • 後述しますが、ansible-playbookで以下のように実行します
  • extra-varsとして以下の変数をtaskファイルに渡します
    • host : hosts内で定義しているホスト
    • deploy_file: ローカル上の転送するファイルのパス
    • remote_file: 転送先のパス
ansible-playbook deploy_local_file.yml --extra-vars "host=${remote_host} local_path=${deploy_file} remote_path=${remote_path}"

Jenkinsfile

  • ジョブパラメータ設定
    • リモートホストを指定できるようにパラメータ化しています
deploy_file.gvy
// ジョブパラメータ設定
properties([
  [$class: 'ParametersDefinitionProperty',
    parameterDefinitions: [
      [$class: 'StringParameterDefinition',
        name: 'REMOTE_HOST',
        //defaultValue: 'some value', デフォルト値も設定可能だが、今回は使用しない
        description: '環境識別子[prd,stg,dev]']]
  ]
])
  • 変数定義
deploy_file.gvy
// Define
def remote_host = "${env.REMOTE_HOST}" // get Jenkins Parameter
def deploy_file = "./deploy_files/test.txt"
def remote_path = "/tmp/"

// for git clone
def credentialsId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" // Jenkinsで使用可能なCredential
def git_repo_jenkins = "jenkins-pipeline-ansible-deploy"
def git_url_jenkins = "https://github.com/tarosaiba/${git_repo_jenkins}.git" // 自環境に合わせて設定

// for get deploy file (使用しないが例として)
// def wget_url = "http://xx.xx.xx.xx:8080/job/hoge-job/lastSuccessfulBuild/artifact/fuga-artifact.tar.gz"
  • Pipeline
deploy_file.gvy
// Pipeline
node {
   stage('Workspase') {
      // Workspace有効化
      ws('workspace') {
      }
   }
   stage('GitClone') {
      // Jenkins repoをclone
      git credentialsId: "${credentialsId}", url: "${git_url_jenkins}"
   }
   stage('GetDeployFile') {
      // 転送用ファイルの取得
      // 本サンプルは"./deploy_files/test.txt"を使用するため何もしない
      sh ":"
      //// Sample 以下のようにJenkinsの成果物をwgetで取得することも可能
      //// sh "wget ${wget_url}  -P ./ansible/deploy_files"
   }
   stage('DeployFileToRemotehost') {
      // 指定ファイルの転送
      sh "cd ./ansible && ansible-playbook deploy_local_file.yml --extra-vars \"host=${remote_host} local_path=${deploy_file} remote_path=${remote_path}\""
   }
}

転送用ファイルについて

  • 転送用ファイルは、GetDeployFileのstageにて以下のようにして準備すると便利です

    • Jenkinsジョブの成果物をwget (ソースの例)
    • 他リポジトリをJenkinsPipeline内でクローンして、指定ファイルを"./ansible/deploy_filesに移動"
    • など、色々
  • 転送用ファイルのファイルパス"deploy_file"をJenkinsジョブのパラメータ化してもよいです。(例えば以下)

    • もちろん"remote_path"も可能
(..)

// Define
def remote_host = "${env.REMOTE_HOST}" //get Jenkins Parameter
def deploy_file = "${env.DEPLOY_FILE}" // 転送用ファイルパスのパラメータ化

(..)

最後に

  • JenkinsのPipeline as Codeは、最初はなれませんでしたがGUIでやっていたことはほとんど設定可能でした

    • 慣れてしまったらこっちの方が絶対にいいです。管理がすごく楽
  • Ansibleのtaskファイルで作業を定義すると、処理がかなりシンプル(YAML形式)に定義できてうれしい

    • Ansibleはサーバプロビジョニングだけではなく、普段の作業の自動化に役立てそうなことがたくさんありました
11
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?