Jenkins — Active Choice: Git branch

 

Для параметризованной сборки с выбором ветки, понадобится плагин Active Choices

Переходим в настройки Jenkins

 

Раздел "Управление плагинами"

 

Переходим к вкладке "Доступные" и в поиске указываем "Active Choices"

Устанавливаем его.

Создаем "New Item" — "Pipeline", указываем, что это будет параметризованной сборка, и добавляем параметр "Active Choices Reactive Parameter"

 

Указываем, что это "Groovy Script" и вставляем туда следующее:

def gettags = ("git ls-remote -t -h ssh://git-codecommit.eu-west-1.amazonaws.com/v1/repos/artem-services.git").execute()
return gettags.text.readLines().collect { 
  it.split()[1].replaceAll('refs/heads/', '').replaceAll('refs/tags/', '').replaceAll("\\^\\{\\}", '')
}

 

Где "ssh://git-codecommit.eu-west-1.amazonaws.com/v1/repos/artem-services.git" путь к вашему репозиторию. Jenkins должен иметь доступ к данному репозиторию по протоколу SSH

 

 

Теперь при сборке с параметрами будет выбор ветки

Jenkins — Изменить язык по умолчанию

 

По умолчанию Jenkins использует язык настроек вашего браузера. Для того, чтобы принудительно его поменять можно воспользоваться плагином Locale

Переходим в настройки Jenkins

 

Раздел "Управление плагинами"

 

Переходим к вкладке "Доступные" и в поиске указываем "Locale"

 

Устанавливаем его. И возвращаемся в настройки Jenkins'а, вкладка "Конфигурация системы"

 

Находим блок "Locale" и указываем необходимый язык. Так же ставим галочку, чтобы игнорировать настройки браузера.

 

Готово. Сохраняем изменения.

FIX ERROR — Ansible AWS SSM: AnsibleError: An unhandled exception occurred while templating

При попытке получить значение с AWS SSM Ansible Playbook используя в качестве интерпретатора Python3 выдает следующую ошибку:

fatal: [localhost-py3]: FAILED! => {"changed": false, "msg": "AnsibleError: An unhandled exception occurred while templating '{{ lookup('aws_ssm', 'server_listeners', decrypt=false, region=’eu-west-1′) }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while running the lookup plugin 'aws_ssm'. Error was a <class 'ansible.errors.AnsibleError'>, original message: botocore and boto3 are required for aws_ssm lookup."}

В документации Ansible сказано, что нужны зависимости для PIP:

  • boto3
  • botocore

Но ошибка по прежнему присутствовала, пока не был добавлен в зависимости PIP'а модуль "ansible"

Решение:

---
- name: Ensure boto3, botocore and ansible modules are installed
  pip:
    name: 
      - boto3
      - botocore
      - ansible
    executable: /usr/bin/pip3

CodeCommit — Git

HTTPS

Для того, чтобы можно было работать с Git репозиторием в CodeCommit используя AIM роль, на инстансе должен быть установлен AWS Cli. Так же понадобится "credential-helper", для этого создадим файл конфигурации для Git'а:

~/.gitconfig

 

И скопируем в него следующее:

[credential]
    helper = !aws codecommit credential-helper $@
    UseHttpPath = true

 

Теперь можно работать с CodeCommit по протоколу HTTPS не указывая логин/пароль.

 

SSH

Для работы по протоколу SSH, нужен IAM пользователь, с правами к CodeCommit. Так же нужно добавить SSH Public Key, для этого в настройках IAM пользователя нужно перейти во вкладку "Security Credentials" и спуститься к блоку "SSH keys for AWS CodeCommit"

 

И загрузить публичный ключ. После чего вы увидите "SSH Key ID" вашего ключа, он нужен для работы с CodeCommit:

git clone ssh://{YOUR_ID_FOR_SSH_KEY}@git-codecommit.us-east-1.amazonaws.com/v1/repos/artem-test

 

Но чтобы постоянно не указывать его, можно его указать в конфигурации SSH:

vim ~/.ssh/config

 

Копируем следующее содержимое:

Host git-codecommit.*.amazonaws.com
User {YOUR_ID_FOR_SSH_KEY}
IdentityFile ~/.ssh/id_rsa # path to your private ssh key

 

И задаем ему нужные права:

chmod 600 ~/.ssh/config

Теперь можно работать с CodeCommit, не указывая "SSH Key ID"

Jenkins — Проверка, задано ли значение string параметра

 

Проверяем задано ли значение переменной "GIT_COMMIT_ID", если да, то делаем checkout по хешу коммита, если нет, то делаем checkout по имени ветки. Переменная "GIT_BRANCH_NAME" берется из Active Choice параметра.

Jenkinsfile:

pipeline {
  agent any
  parameters {
    string(defaultValue: '', description: 'If you need to build a specific commit, enter it in this field.', name: 'GIT_COMMIT_ID')
  }
  stages {
    stage('Checkout') {
      steps {
        script {
          if ( env.GIT_COMMIT_ID.isEmpty() ) {
            sh "echo Checkout branch: $GIT_BRANCH_NAME"
            checkout([
              $class: "GitSCM",
              branches: [[name: "${GIT_BRANCH_NAME}"]],
              userRemoteConfigs: [[url: "${GIT_URI}"]]
            ])
          }
          else {
            sh "echo Checkout commit: $GIT_COMMIT_ID"
            checkout([
              $class: "GitSCM",
              branches: [[name: "${GIT_COMMIT_ID}"]],
              userRemoteConfigs: [[url: "${GIT_URI}"]]
            ])       
          }
        }
      }
    }
  } 
}  

AWS Cli — Поиск EC2 инстансов по тегу и состоянию

 

Чтобы получить IP адреса всех инстансов с тегом "Application" и его значением "Frontend", и так же отфильтровать по состоянию, чтобы вывести информацию только о тех инстансах, которые в состоянии "running".

aws ec2 describe-instances --filter "Name=tag:Application,Values=Frontent" "Name=instance-state-name,Values=running" --query "Reservations[*].Instances[*][NetworkInterfaces[0].PrivateIpAddresses[0].PrivateIpAddress]" --output text

 

Чтобы вместе с IP адресом вывести имя истанса:

aws ec2 describe-instances --filter "Name=tag:Application,Values=Frontend" "Name=instance-state-name,Values=running" --query "Reservations[*].Instances[*][Tags[?Key=='Name'].Value[],NetworkInterfaces[0].PrivateIpAddresses[0].PrivateIpAddress]" --output text

Ansible — Получить IP адрес другого хоста с hosts файла

Пример, как получить IP адрес другого хоста с "hosts" файла, выполняя задачу на другом хосте.

 

  • server1 — на нем будет выполнятся наш Playbook
  • server2 — его IP адрес нам нужен в Playbook

 

hosts:

[default]
server1 ansible_host=192.168.1.101
server2 ansible_host=192.168.1.102

 

Для того, чтобы получить IP адрес, мы будем использовать "hostvars", где укажем имя нужного нам сервера, в нашем случае это "server2"

Playbook:

---
 
- name: example
  gather_facts: No
  hosts: server1
  
  tasks:
    - name: get-ip-from-server2
      debug:
        msg: "Server2 IP address is {{ hostvars[ 'server2' ].ansible_default_ipv4.address }}"

 

Результат:

ok: [server1] => {
    "msg": "Server2 IP address is 192.168.1.102"
}

Ansible — Использовать значения в цикле с hosts файла на другом хосте

 

Есть "hosts" файл, в котором есть группа "db". Это инстансы с базами данных, которые выполняют разную роль. Цель добавить тип роли в "hosts" файл, чтобы потом это значение мы могли использовать в цикле, который будет выполнятся совершенно на другом хосте, к примеру "management"

 

Исходный "hosts" файл:

[db]
db1 ansible_host=192.168.1.101
db2 ansible_host=192.168.1.102
db3 ansible_host=192.168.1.103

 

Добавим ключ "role" с нужным значением для каждого хоста в группе "db":

[db]
db1 role=development ansible_host=192.168.1.101
db2 role=staging ansible_host=192.168.1.102
db3 role=production ansible_host=192.168.1.103

 

Пример Playbook'а:

---

- name: management
  gather_facts: No
  hosts: management
 
  tasks:
    - name: debug
      debug:
        msg: "Instance {{ item.1 }} with IP {{ hostvars[ item.1 ].ansible_host }} is {{ hostvars[ item.1 ].role}}"
      with_indexed_items: "{{ groups['db'] }}"

 

Результат:

ok: [management] => (item=[0, u'db1']) => {
    "msg": "Instance db1 with IP 192.168.1.101 is development"
}
ok: [management] => (item=[1, u'db2']) => {
    "msg": "Instance db2 with IP 192.168.1.102 is staging"
}
ok: [management] => (item=[2, u'db3']) => {
    "msg": "Instance db3 with IP 192.168.1.103 is production"
}

Ansible — Количество хостов группе

Есть "hosts" файл, в котором в группе "db" есть N количество хостов, нужно в плейбуке автоматически задавать переменную, равную количеству хостов в определенной группе

hosts

[db]
db1 ansible_host=192.168.1.101
db2 ansible_host=192.168.1.102
db3 ansible_host=192.168.1.103
db4 ansible_host=192.168.1.104
...

 

example.yaml

---
- hosts: localhost
  roles:
    - db/example
  vars:
    DB_COUNT: "{{ groups['db'] | length }}"

FIX ERROR — MS SQL: The database 'YOUR_DB_NAME' is enabled for database mirroring.

При попытке удалить базу данных в MS SQL возникла следующая ошибка:

The database 'YOUR_DB_NAME' is enabled for database mirroring. Database mirroring must be removed before you drop the database.

 

Решение:

ALTER DATABASE "YOUR_DB_NAME" SET PARTNER OFF;
GO

DROP DATABASE "YOUR_DB_NAME";
GO