Jenkins – Active Choice: Git branch

 

For a parameterized build with branch selection, you will need a plugin Active Choices

Go to Jenkins settings

 

Section “Manage Plugins

 

Go to the “Available” tab and specify “Active Choice” in the search.

Install it.

Create a “New Item” – “Pipeline“, indicate that it will be a parameterized project, and add the parameter “Active Choices Reactive Parameter

 

We indicate that this is “Groovy Script” and paste the following into it:

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("\\^\\{\\}", '')
}

 

Where “ssh: //git-codecommit.eu-west-1.amazonaws.com/v1/repos/artem-services.git” is the path to your repository. Jenkins must have access to this repository over SSH

 

 

Now, when building with parameters, there will be a branch selection

Jenkins – Change default language

 

By default, Jenkins uses your browser’s settings language. In order to force change it, you can use the Locale plugin

Go to Jenkins settings

 

Section “Manage Plugins

 

Go to the “Available” tab and specify “Locale” in the search.

 

Install it. And back to Jenkins settings, tab “Configure System

 

Find the “Locale” block and specify the desired language. We also check the box to ignore browser settings.

 

Done. Save changes.

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

When trying to get a value from AWS SSM, Ansible Playbook using Python3 as an interpreter generates the following error:

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.”}

The Ansible documentation says that dependencies are needed for PIP:

  • boto3
  • botocore

But the error was still present until the “ansible” module was added to the PIP dependency

Solution:

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

CodeCommit – Git

HTTPS

In order to be able to work with the Git repository in CodeCommit using the AIM role, AWS Cli must be installed on the instance. You will also need “credential-helper“, for this we create a configuration file for Git:

~/.gitconfig

 

And copy the following into it:

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

 

Now you can work with CodeCommit over HTTPS without specifying a username/password.

 

SSH

To use the SSH protocol, you need an IAM user with rights to CodeCommit. You also need to add the SSH Public Key, for this, in the IAM settings of the user, go to the “Security Credentials” tab and go down to the “SSH keys for AWS CodeCommit” block

 

And upload the public key. After which you will see the “SSH Key ID” of your key, it is needed to work with CodeCommit:

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

 

But in order not to constantly indicate it, you can specify it in the SSH configuration:

vim ~/.ssh/config

 

Copy the following contents:

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

 

And provide the necessary permission to it:

chmod 600 ~/.ssh/config

Now you can work with CodeCommit without specifying “SSH Key ID

Jenkins – Checking if a string value is set to a parameter

 

Check if the value of the variable “GIT_COMMIT_ID” is set, if so, then do a checkout by the hash of the commit, if not, then do a checkout by the name of the branch. The variable “GIT_BRANCH_NAME” is taken from the Active Choice parameter.

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 – Search EC2 instances by tag and state

 

To get the IP addresses of all instances with the “Application” tag and its value “Frontend“, and also filter by state to display information about only those instances that are in the “running” state:

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

 

To display the name of instance along with the IP address:

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 – Get the IP address of another host from the hosts file

An example of how to get the IP address of another host from the “hosts” file by performing a task on another host.

 

  • server1our Playbook will be executed on it
  • server2we need its IP address in the Playbook

 

hosts:

[default]
server1 ansible_host=192.168.1.101
server2 ansible_host=192.168.1.102

 

In order to get the IP address, we will use “hostvars“, where we indicate the name of the server we need, in our case it is “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 }}"

 

Output:

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

Ansible – Use values in a loop from hosts file on another host

 

There is a “hosts” file in which there is a group of “db“. These are database instances that play a different role. The goal is to add the role type to the “hosts” file, so that later we can use this value in a loop that will be executed on a completely different host, for example “management

Source “hosts” file:

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

 

Add the “role” key with the necessary value for each host in the “db” group:

[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 example:

---

- 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'] }}"

 

Output:

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 – Number of hosts per group

There is a “hosts” file in which in the “db” group there are N number of hosts, you need to automatically set a variable in the playbook equal to the number of hosts in a particular group

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.

The following error occurred while trying to delete the database in MS SQL:

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

 

Solution:

ALTER DATABASE "YOUR_DB_NAME" SET PARTNER OFF;
GO

DROP DATABASE "YOUR_DB_NAME";
GO