# Question
Title: Managing state (e.g. presence/absence) in Ansible, any established best practices?
Ansible lists a nice set of best practices in its documentation. One of the items is:

> ### Always mention the state
>
> For many modules, the `state` parameter is optional. Different modules have different default settings for `state`, and some modules support several `state` settings. Explicitly setting `state=present` or `state=absent` makes playbooks and roles clearer.

In my case the main point isn't so much about making playbooks or roles clearer, instead my goal is to manage the presence/absence of items throughout the lifetime of my servers.

Probably many of you have had the issue of installing package `xyz` as a "bread'n'butter" package on your machines, but a few months later it turns out your workflow has changed and you don't really need `xyz` anymore. Or it was replaced by `xyz-ng` ... or what have you ...

So now it's time to express somehow to remove that `xyz` package consistently across your infrastructure. In my case with Debian/Ubuntu I'd use the `apt` module with `state=absent` for the respective packages. No surprise.

However, I'd like to factor this into my roles from the outset. As an example it would be nice to have a dictionary variable (as an example):

```
packages:
  present:
  - elinks
  absent:
  - lynx

```

This way the presence and absence would dynamically be managed by variables and I can use `when:` to cover for an empty list and so on; potentially even by including a task dynamically and passing along a `state` variable that coincides with the key in the dictionary.

Another case where this must have come up for someone before is the creation of local users, or has everyone moved to directory services? When someone leaves the company I'd like to be able to put that someone on a list populated with usernames to be put into a locked state.

However, since there *are* established best practices for Ansible in general, I was wondering:

**Q:** are there best practices about managing the state of "entities" on the configured infrastructure?

# Answer
> 3 votes
This can be done with two tasks with loops:

```
# tasks/packages.yml
- name: pkgs | Ensure Good
  package:
    name: "{{ item }}"
    state: present
  loop: "{{ packages['present'] }}"

- name: pkgs | Ensure Bad
  package:
    name: "{{ item }}"
    state: absent
  loop: "{{ packages['absent'] }}"

```

This will loop over all of the items in the list that you define and ensure that they are either `present` or `absent`.

You could also use a shorthand:

```
# tasks/packages.yml
- name: pkgs | Ensure Good
  package:
    name: "{{ packages['present'] }}"
    state: present

- name: pkgs | Ensure Bad
  package:
    name: "{{ packages['absent'] }}"
    state: absent

```

This would run faster, since you don't have a list of tasks, but a task with a list, but you would lose some visibility into which packages you're actually ensuring the state of.

Caveats:

Ensure that there is no overlap between the two lists. One way would be to make an assertion on the lists before you run the task:

```
- name: ensure no overlap between good and bad
  assert:
    that: "{{ packages['present'] | intersect(packages['absent'] }} == [] }}"

```

Also ensure that the lists are not empty.

To answer your final question:

> Q: are there best practices about managing the state of "entities" on the configured infrastructure?

It is usually *my* practice (I wouldn't call it "best", but take it for what it's worth) to declare the explicit state of a resource. It's quite difficult to do this exhaustively for packages that should be `absent` \- this is something akin to maintaining a "blacklist". One approach might to be start from a policy and implement specific controls in it. *IE* for ssh config ensure that protocol v1 is absent, *etc*.

---
Tags: ansible
---


title: Failed to install kubernetes on centos

text:
# Question
Title: Failed to install kubernetes on centos
Following the official documentation, I have an error when trying to install kubernetes cluster yum package.

I am on Centos 7 using yum. So I run this commands:

```
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF

# Set SELinux in permissive mode (effectively disabling it)
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

```

Indeed when I am trying to run `yum install -y kubelet kubeadm kubectl` I have this error:

```
Loading mirror speeds from cached hostfile
No package kubelet available.
No package kubeadm available.
No package kubectl available.
Error: Nothing to do

```

What if the real problem about the installation ?

# Answer
When I navigate to the URL, there do not appear to be any packages in the repo. Consider trying a mirror like: mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86\_64
> 1 votes

---
Tags: kubernetes, linux, kubectl, centos, kubeadm
---


# Question
Title: Jenkins declarative pipeline Warning: JENKINS-41339 probably bogus PATH
I am struggling with this issue inside my declarative pipeline. I am trying to use python's docker image as my agent and run some scripts and I am receiving warning:

```
Warning: JENKINS-41339 probably bogus PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:/opt/android-sdk-linux/tools:/opt/android-sdk-linux/platform-tools; perhaps you meant to use ‘PATH+EXTRA=/something/bin’

```

I do not have access to Jenkins server global variables configuration. I am using one of the Debian slaves.

I have read other issues about this problem stackoverflow/43987005 and stackoverflow/44378221. Also discussion on Jenkins forum and Jenkins official documentation.

This is code I am executing:

```
//  https://www.jenkins.io/doc/book/pipeline/syntax/
pipeline {
  environment {
    PATH = "/bin/sh:$PATH"
  }
  agent {
    docker {
      image "python:3.9"
    }
  }
  stages {
    stage('Test') {
      steps {
        withEnv(["PATH+EXTRA=$PATH"]) {
          sh "PATH is: $PATH"
        }
      }
      post {
        cleanup {
          cleanWs()
        }
      }
    }
    stage('Build') {
      steps {
        echo "'Let's build"
      }
    }
    stage('Deploy') {
      steps {
        echo "'Let's deploy"
      }
    }
  }
}

```

Problem appeared after I wanted to implement docker image as agent and by changing ***environment*** section inside my pipeline still haven't fixed my problem. I was trying also these alternatives:

```
PATH = "/usr/local/bin:$PATH"
PATH = "/usr/local/bin:${env.PATH}"

```

I also went to `Configure`, section `Prepare an environment for the run` and filled up `Properties Content` input but I still didn't receive $PATH content into my job. I am still receiving global value of $PATH. I also unchecked the `Keep Jenkins Environment Variables` checkbox.

The server I am using has Environment Injector Plugin plugin installed.

# Answer
> 1 votes
This post explains that/why environment variables don't propagate to Docker agent.

If you need a custom container, you could define path and whatever else as layers on top of base image in a Dockerfile. Then using that image in pipeline would be what I think is usual way of doing it. You can build that image outside of Jenkins, but it's also possible to build container from within pipeline too if you want (get Dockerfile from SCM or some other use case).

In the context of your question, I think you can still use base image, and if you know full path you'd like to set, do that at container (agent) startup with args. But `$PATH` variable won't be available at host to be resolved within container at startup. If you must dynamically set path in container, could adjust it in shells.

```
pipeline {
    agent {
        docker {
            image 'python:3.9'
            // cannot resolve $PATH var in container (becasue HOST does not know what it is).
            args '-e PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/i/know/my/full/path/ahead/of/time'
        }
    }
    stages {
        stage('Test') {
            steps {

                // as set by args above. Applies to all shells
                sh 'echo $PATH'

                // You can also adjust it within container in each shell
                sh '''
                    export PATH=/even/more/path:$PATH
                    echo $PATH
                   '''

                // But this is back to what's in args in a new shell instance
                sh 'echo $PATH'
            }
        }
    }
}

```

---
Tags: jenkins, jenkins-pipeline, jenkinsfile
---


# Question
Title: Error 502 before execute Ansible playbook
I execute an Ansible playbook with an `ansible` user. The playbook executes properly, with no errors in the application log, no errors in the Ansible log. This `.war` usually deploys with user "tomcat" when the deploy is manual.

Could this be the cause of the problem? Execute playbook with different users

This is my playbook (syntax is correct):

```
- name: Deploy war
  hosts: grupo1
  tasks:
    - name: Stop Tomcat
      command: systemctl stop tomcat

    - name: Delete old war1
      command: rm -rf /opt/tomcat/catalina_base/webapps.old/portal-admin
      args:
        warn: false

    - name: Delete old war
      command: rm -rf /opt/tomcat/catalina_base/webapps.old/portal-client
      args:
        warn: false

    - name: Copy the old war
      copy:
        src: /opt/tomcat/catalina_base/webapps/portal-client
        remote_src: true
        dest: /opt/tomcat/catalina_base/webapps.old/

    - name: Copy the old war2
      copy:
        src: /opt/tomcat/catalina_base/webapps/portal-admin
        remote_src: true
        dest: /opt/tomcat/catalina_base/webapps.old/

    - name: delte the war fileclient
      shell: /bin/rm -rf /opt/tomcat/catalina_base/webapps/portal-client/*
      args:
        warn: false

    - name: deploy warclient
      command: unzip /tmp/portal-client.war -d /opt/tomcat/catalina_base/webapps/portal-client/
        args:
          warn: false

    - name: delete the war fileadmin
      shell: /bin/rm -rf /opt/tomcat/catalina_base/webapps/portal-admin/*
      args:
        warn: false

    - name: deploy waradmin
      command: unzip /tmp/portal-admin.war -d /opt/tomcat/catalina_base/webapps/portal-admin/
      args:
        warn: false

    - name: Start tomcat
      command: systemctl start tomcat

```

The error when I execute the playbook is

```
Proxy Error
The proxy server received an invalid response from an upstream server.
The proxy server could not handle the request GET /portal-client/cm/misalud/.

Reason: Error reading from remote server

```

# Answer
First - @caxcaxcoatl is completly right - your playbook is not Ansible, it is a bash script inside Ansible and that isn't Ansible.

Your error doesn't have something to do with your playbook, but with that, what the playbook is doing. You're redeploying an application and then the proxy in front of the Tomcat cannot read the response from your Tomcat. So your deployment is wrong, has some failures, what ever. You should have a look at your Tomcat HTTP response (without the Proxy in front) direct on the machine (with `curl`, `telnet` or whatever). Maybe you should also check the logs of Tomcat to get the error. The proxy sends the error, because the Tomcat is answering with a 500 HTTP error code, when the proxy hits `/portal-client/cm/misalud/`.

To give you a hint, how a playbook could look like (of course this wasn't the question, and it could be done much better then this with includes for a unspecific WAR and just call include\_tasks on all available WARs in the main playbook, or with a Ansible module written in Python just giving the params of the new WAR etc.):

```
- name: Deploy war
  hosts: grupo1
  vars:
    webapps_cur "/opt/tomcat/catalina_base/webapps"
    webapps_old: "/opt/tomcat/catalina_base/webapps.old"
  tasks:
    - name: "Stop Tomcat"
      systemd:
        name: tomcat
        state: stopped

    - name: "Delete old Backup WARs"
      file:
        path: "{{ webapps_old }}/{{ item }}"
        state: absent
      with_items:
        - "portal-admin"
        - "portal-client"

    - name: "Backup the current WARs"
      copy:
        src: "{{ webapps_cur }}/{{ item }}"
        dest: "{{ webapps_old }}/{{ item }}"
        remote_src: true
      with_items:
        - "portal-admin"
        - "portal-client"

    - name: "Delete the current WARs"
      file:
        path: "{{ webapps_cur }}/{{ item }}"
        state: absent
      with_items:
        - "portal-admin"
        - "portal-client"

    - name: "Deploy new WARs"
      unarchive:
        src: "/tmp/{{ item }}.war"
        dest: "{{ webapps_cur }}/{{ item }}"
        user: "tomcat"
        group: "tomcat"
      with_items:
        - "portal-admin"
        - "portal-client"

    - name: "Start Tomcat"
      systemd:
        name: tomcat
        state: started

```
> 2 votes

---
Tags: ansible, deployment
---


title: SSL Expiration Date

text:
# Question
Title: SSL Expiration Date
I play this playbook to get amount of days between two expiration certificates dates:

```
---
- hosts: localhost
  gather_facts: no
  connection: local

  tasks:

  - name: Save the old date
    shell:
       cmd: >-
           date --date="$(openssl x509 -noout -dates -in cert1.crt
           | grep 'notAfter' | cut -d= -f2)" --utc +"%d-%m-%Y"
    ignore_errors: true
    args:
       executable: /bin/bash
    register: x1

  - name: Save the new date
    shell:
       cmd: >-
           date --date="$(openssl x509 -noout -dates -in cert2.crt
           | grep 'notAfter' | cut -d= -f2)" --utc +"%d-%m-%Y"
    ignore_errors: true
    args:
       executable: /bin/bash
    register: x2

  - name: Show mount of days with dedug module
    debug:
      var: "{{ (( x2.stdout | to_datetime('%d-%m-%Y')) - ( x1.stdout  | to_datetime('%d-%m-%Y'))).days }}"

  - set_fact:
       diff: "{{ (( x2.stdout | to_datetime('%d-%m-%Y')) - ( x1.stdout | to_datetime('%d-%m-%Y'))).days }}"

  - name: Show diff variable
    debug:
      var: diff

```

The playbook run well and i can show the resultat with debug module (task name: Show mount of days with debug module):

```
ok: [localhost] => {
    "msg": "357"
}

```

Otherwise the task (Show diff variable) show me a null output:

```
ok: [localhost] => {}

```

I can't find what is wrong with set\_fact , anyone have an idea please ?

# Answer
When I have a look at your posted output and compare it to mine, there is something wrong:

```
ok: [localhost] => {
    "msg": "357"
}

```

That output comes from the debug message. But only with `debug msg={{ value }}` and not with `debug var={{ value }}`. When I do it with var= then I get (in my case) `"32": "32"` as a response.

But that's not the problem. The problem is:

```
- name: Show diff variable
  debug:
    var: diff

```

The name `diff` for the variable is somehow reserved. You need to set the diff as Jinja

```
- name: Show diff variable
  debug:
    var: "{{ diff }}"

```

And then I see

```
ok: [localhost] => {
    "32": "32"
}

```

When I rename the variable to `diffa` everything is normal. I can't find any documentation for it.

```
- name: Show mount of days with dedug module
  set_fact:
    diffa: "{{ (( x2 | to_datetime('%d-%m-%Y')) - ( x1  | to_datetime('%d-%m-%Y'))).days }}"

- name: Show mount of days with dedug module
  debug:
    var: diffa

```

output:

```
TASK [Show mount of days with dedug module] *********************************************
ok: [localhost] => {
    "diffa": "32"
}

```
> 0 votes

---
Tags: ansible
---


# Question
Title: How to skip reviewer for project administrator pull request?
Is it possible to configure the repository to skip "At least one reviewer must approve the most recent iteration" in case the person who performs the Pull request is the project administrator?

I have the below branch Policy:

I made the review approbation for my own commit.

But when I'm going to complete the pull request, I get the below message:

> At least one reviewer must approve the most recent iteration.

It's possible to skip review requirement only for project administrators?

# Answer
> 4 votes
As a workaround, you can add "bypass policies" for project admins.

The documentation: Security groups - Git repository (object-level)

---
Tags: git, azure-devops
---


# Question
Title: Definition of change failure rate and mean time to recovery DORA metrics
There has been a lot of talk in recent years about the Accelerate book and the DORA metrics.

As the DORA survey was looking at a wide variety of organisations, teams and cultures all with potentially very different current processes and technologies, the questions asked were fairly general and probably leave a fair bit of wriggle room for teams to interpret things their own way. Which is all fair enough.

However, I'm specifically trying to understand what change failure rate and mean time to recovery are trying to measure. Are they just trying to measure if the release process is good or if all of the changes in that release are good?

If I do 10 releases in a row and the release process works smoothly for that and I get no downtime, no manual release tweaks, no alerts, etc...then it looks like I've got a 0% failure rate. But what if there was a relatively subtle bug in that very first release and it doesn't get picked up for 3 days so there is a bug fix going into the next release to fix it. And of course the next release might also have some bugs and so on, so you could say I've got a 100% failure rate due to the bugs.

My instinct is that I should have a high failure rate in this scenario because although the process on the day of release looks good, it the software itself is not good. Just because you have not tested your release before or immediately after release, it doesn't feel like you should get away with claiming no failures.

So if I do get a bug that isn't fixed until the next release in say a week's time, then my mean time to recovery might be a week...unless I did a rollback of that initial release?

What are the common interpretations/implementations of these metrics?

# Answer
> 2 votes
You are asking the right questions and hitting on a very important aspect of these metrics. **Individual metrics are not super helpful and measurements need to be defined.** Having worked with these measurements across small and large organizations, let me walk you through my thought process.

Definitions:

* Metrics - Some sort of calculation on one or more measures
* Measure - An amount of something using a specific unit
* Change Failure Rate (CFR) - The percentage of deployments causing a failure in production
* Mean Time to Recover (MTTR) - How long it takes an organization to recover from a failure in production

This conversation could include Service-Level Indicators (SLI), Service-Level Objective (SLO), and Service-Level Agreement (SLA), however, for this purpose I will assume we have measurements (SLI) to ensure we are meeting our goals (SLO) and not breaking our promise to users (SLA).

Before getting into the details, the main question asked is:

**What are we trying to measure?**

At the end of the day, any organization exists to create value, these metrics are meant to track any interruption in the flow of value from the organization to its consumers / users.

*As an example, if we wanted to measure how efficiently the organization adds new value to users, Lead Time for changes is a great way. How long does it take new code or business ideas (depending on if you would like to include non technical business processes) to get from creation / ideation to the user? Lead Time includes CFR and MTTR, both of these can interrupt getting value to the consumer and increase Lead Time.*

Using the value creation lens, let's look at CFR first.

**What does the organization consider a failure in production?**

I have typically used it as an event needing immediate fixing, on the call during the production deployment. The service we deployed needed to be rolled back, a hotfix needed to be pushed immediately to correct an issue discovered during the deployment, or something equally catastrophic. These are all interruptions to value reaching the user. A bug not presenting itself for a few days, would not create a Change Failure with this definition. However, if the bug began to trip indicators (SLI) (example, degraded speed or experience for the end user), exceeds our objectives (SLO), or even breaks or promise to users (SLA) then an incident is created and it will bring us to your next measurement, MTTR.

Assuming the bug mentioned creates an incident, MTTR measures how long it takes to fix it. If the fix is a roll back for the original release, or a hotfix of the release, it really does not matter. The measurement is how long it takes to correct.

**Pulling this together.**

1. Determine what the measure is.

*For CFR, what does the organization consider a production failure? I provided a few examples, but all organizations are free to create their own measure. For MTTR, the measure is time, hopefully from issue creation to correction, sometimes we need to settle for incident discovery to correction.*

2. With the Measure, track the Metrics.

*How many failed production releases are there? How long, on average, does it take to correct production incidents?*

3. With the Metrics, track and, hopefully, improve the flow of value from the organization to the consumer.

*If a deployment is successful, it should not trip the measurement for Change Failure, however, if there are bugs, their interruption to value will be caught with Mean Time To Recovery.*

These measurements and metrics (Lead Time To Change, Mean Time to Recovery, Deployment Frequency, and Change Failure Rate) are meant to tell a story in aggregate.

*Assuming weekly deployment, if an organization has 0% CFR, but a 14 Month MTTR with incidents occurring every week, then the flow of value is constantly interrupted and the amazing CFR score means very little. Or, if the CFR is 50% and the MTTR is 2 Mins, then the high CFR looks horrible, but the actual interruption to users is only 2 Mins * bugs per week. It really takes both, or all four of the metrics, to create an accurate picture of the real state of the code and deployment process.*

Hopefully this helps. Working through these measurements and metrics is a journey, probably with no conclusion, with a goal of improving the amount of value an organization can create for its consumers.

---
Tags: metrics
---


# Question
Title: How to mount a single 100TB SSD on AWS and access the device over nfs from different machines within the same VPC?
I have a bad experience with Storage Gateway (SGW) and would to consider the possibility to setup a 100TB SSD device (via EFS or similar) on AWS and allow an access to the storage device from different clients such as: Amazon Workspaces sessions, EC2 machines, AWS Batch and other station within the same VPC.

The main issue is that SGW fails quite frequently to mirror the s3 bucket properly even after 24 hours upon update of the bucket.

# Answer
> 1 votes
1. create storage in AWS Console
2. mount created storage into VM
3. configure nfs deamon to present the storage volume in the VPC
4. configure Clients to use/mount NFS volume coming from server

sometimes the easiest is the best, this even works on other systems, not just AWS.

---
Tags: amazon-web-services
---


# Question
Title: Does a DB connection prevent AWS Aurora Serverless from pausing its compute capacity?
I want to host an application that connects to a DB and makes queries to it. The application holds onto the connection indefinitely but only makes queries to the DB when the user interacts with the frontend.

I know that AWS Aurora Serverless has a "pause compute capacity" feature to only charge you for the DB's storage after a specified amount of time. If the application is still connected to the DB (even without making queries), does that prevent the DB from scaling down to 0 compute units and pausing its compute capacity?

# Answer
I believe you are correct, a single long-running connection will prevent AWS Aurora Serverless from triggering the pause-and-resume feature.

> Aurora Serverless v1 can also scale to zero capacity when there are no connections if you enable the pause-and-resume option for your DB cluster's capacity settings.

Source: How Aurora Serverless v1 works

Take this with a grain of salt, though, as I haven't tested this behaviour myself, and the docs aren't perfect. The same doc goes on to reference "no activity" without defining it:

> You can choose to pause your Aurora Serverless v1 DB cluster after a given amount of time with no activity.

Which begs the question: "does an idle connection count as activity?"

I think the best hint that an idle connection counts as "activity" is that the moment a connection is needed, Aurora Serverless resumes:

> If database connections are requested when an Aurora Serverless DB cluster is paused, the DB cluster automatically resumes and services the connection requests.
> 1 votes

---
Tags: amazon-web-services, amazon-rds, serverless
---


# Question
Title: Is there any Selenium-like software for executables?
I have some app I want to test i.e. it has a window opening up and I want to press some of the buttons and fill in some text boxes, and I need to do the same process multiple times.

I heard about selenium but it seems it only works on web-based apps, whereas my program is an executable program (and quite a heavy one while at it). Is there something similar to this, a module to be added to selenium or a library for python/Matlab/C?

I’d appreciate any help with this.

# Answer
> 1 votes
I'm not a Windows user, but I'd start at Comparison of GUI testing tools, looking for those supporting Windows for both **testing** and **tested** system.

# Answer
> 0 votes
SikuliX may fit your needs:

"SikuliX automates anything you see on the screen of your desktop computer running Windows, Mac or some Linux/Unix. It uses image recognition powered by OpenCV to identify GUI components and can act on them with mouse and keyboard actions. This is handy in cases when there is no easy access to a GUI's internals or the source code of the application or web page you want to act on"

https://github.com/RaiMan/SikuliX1

# Answer
> 0 votes
At the other end of sikulli is AutoIt, it supports record play and interaction by object ID'S.

As a side note testing through the GUI is not really efficient, scalable or reliabile, consider testing "under the GUI" if possible and leave only the most necessary things to it.

# Answer
> 0 votes
For MATLAB you can use the app testing framework, but this is intended for interacting with MATLAB uifigures only. If thats what you are doing then this framework should enable that workflow.

---
Tags: automation, selenium
---


# Question
Title: Jenkins trigger build if shared library changes
I have Jenkins `Pipeline` job define in my git repo as.

```
// File: deployment/jenkinsfiles/staging/Merge

@Library("my_shared_lib") _

import com.company.myteam.Constants

pipeline {
    agent { label "common" }

    triggers {
        pollSCM("H/2 * * * *")
    }

    options {
        buildDiscarder(logRotator(numToKeepStr: "50", artifactNumToKeepStr: "50"))
    }

    stages {
        stage ("Staging Merge") {
            steps {
                script {
                    def config = new Constants().repoconfig
                    ansiColor("xterm") {
                        myteam.pipelines.stagingMerge(config)
                    }
                }
            }
        }
    }
    post {
        always {
            cleanWs()
        }
    }
}

```

Then I created jenkins job configuration as below.

Now, When I check the `Git Polling Log` its polling `shared-library` too.

```
Started on Feb 25, 2020 5:33:07 PM
Using strategy: Default
[poll] Last Built Revision: Revision 681f996e689bdeb9cfca2b167002b8ccd99590cb (origin/staging)
using credential github_username_with_token
 > git --version # timeout=10
using GIT_ASKPASS to set credentials Github Service Account Username with token
 > git ls-remote -h https://myuser@github.company.com/myteam/myrepo # timeout=10
Found 6 remote heads on https://myuser@github.company.com/myteam/myrepo
[poll] Latest remote head revision on refs/heads/staging is: 681f996e689bdeb9cfca2b167002b8ccd99590cb - already built by 53
Using strategy: Default
[poll] Last Built Revision: Revision e80628ec7c9dbc59decbc81a3b884dcaa963a8dc (refs/remotes/origin/master)
using credential github_username_with_token
 > git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repositories
 > git config remote.origin.url https://myuser@github.company.com/myteam/jenkins-shared-libraries.git # timeout=10
Fetching upstream changes from https://myuser@github.company.com/myteam/jenkins-shared-libraries.git
 > git --version # timeout=10
using GIT_ASKPASS to set credentials Github Service Account Username with token
 > git fetch --tags --progress https://myuser@github.company.com/myteam/jenkins-shared-libraries.git +refs/heads/*:refs/remotes/origin/* # timeout=10
Polling for changes in
 > git rev-parse refs/remotes/origin/master^{commit} # timeout=10
 > git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10
 > git log --full-history --no-abbrev --format=raw -M -m --raw e80628ec7c9dbc59decbc81a3b884dcaa963a8dc..869b3a16e07d21a88d557f1857376bfed7717a6e # timeout=10

```

Whenever I change code in `jenkins-shared-library`, its start build for the job.

I tried `workaround` given in https://issues.jenkins.io/browse/JENKINS-39615?focusedCommentId=280729&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-280729, but no luck.

I changed my `pollSCM` to `githubPush`, but this also trigger when I change in `shared-library`.

I tried solution given in https://issues.jenkins-ci.org/browse/JENKINS-41497 as `Ignore on push notifications` for `githubPush()` but still its triggering job.

Before moving to `pipeline`, I had `freestyle` project. Where there is section **Source Code Management**, where we can define the branch, and `githubPush()` was listening on that branch only.

When we select project type as `pipeline` there is no **Source code management** section. May be due to that, its listening for all push events.

By `push` or `poll`, I want to restrict my jenkins job to trigger only when there is changes on `myrepo.git` only.

# Answer
> 4 votes
This issue can be solved by using legacy SCM option. Go to Jenkins -\> Manage Jenkins -\> Configure System and select "Legacy SCM" option for share libs. this will resolve the issue completely, It worked for us.

# Answer
> 1 votes
Do I understand correctly that you don't want changes in the shared library to trigger builds for your project/pipeline?

If so, you can do it per-pipeline by modifying the `@Library("my_shared_lib") _` statement to include `changelog=false` parameter, like so `@Library("my_shared_lib", changelog=false) _`.

You can also do that globally, for a specific library - uncheck the `Include @Library changes in job recent changes` checkbox (in global Jenkins configuration).

---
Tags: jenkins, jenkins-pipeline, git, git-hooks
---


# Question
Title: what is difference between "sudo shutdown now" versus "aws ec2 stop-instances"
When logged onto a AWS EC2 instance say some Ubuntu box and I issue

```
sudo shutdown now

```

how is that different from stopping the same instance using

```
aws ec2 stop-instances --instance-ids  $curr_instanceid --region $AWS_REGION

```

either way I see the instance gets into the state of `stopped` and it will transition into state `running` once this is run

```
aws ec2 start-instances --instance-ids   $curr_instanceid --region $AWS_REGION

```

# Answer
> 1 votes
Just to state the obvious for junior folks who might come across this: `sudo shutdown now` requires access to the operating system (via SSH keys, inbound security groups, etc), while `aws ec2 stop-instances` is an AWS CLI command which simply requires API authentication (via IAM credentials or STS tokens).

Aside from the obvious difference in invocation, the shutdown is the same.

> When you stop or hibernate an instance, we shut it down. You can restart your instance at any time. Before stopping or hibernating an instance, make sure it is in a state from which it can be restarted. Stopping an instance does not preserve data stored in RAM, but hibernating an instance does preserve data stored in RAM. If an instance cannot hibernate successfully, a normal shutdown occurs.

Source: stop-instances documentation

The `--hibernate` flag defaults to `false`, so a normal shutdown is triggered immediately by your CLI command.

When `--hibernate` is `true`, the suspend-to-disk process differs from a regular shutdown (such as `sudo shutdown now`), and is further documented here.

---
Tags: amazon-ec2
---


title: How to safe restart Jenkins?

text:
# Question
Title: How to safe restart Jenkins?
I need to make some configuration changes on our Jenkins instance that will involve restarting Jenkins a couple of times. However, our developers are committing frequently enough that I haven't seen Jenkins without jobs running in three days.

Is there a native way (either through the GUI or via command line) to safe-restart Jenkins? IE: wait for current jobs to finish before going down, and keep track of queued jobs to start once Jenkins comes back up.

I know there's a plugin but in order to install it I need to restart Jenkins...

# Answer
If you navigate to `$YOUR_JENKINS_URL/updateCenter/` you should see the following page:

Here you can check `Restart Jenkins when installation is complete and no jobs are running` which should be fairly safe.
> 23 votes

# Answer
Visiting https://youjenkinsdomain/safeRestart will set it in the mode when it waits for jobs to stop and then restarts.
> 35 votes

# Answer
You can execute the safeRestart command using either the Jenkins Rest API (*\[jenkins\_url\]/safeRestart*) or you can execute the command via the Jenkins CLI.

```
sudo /etc/init.d/jenkins safeRestart

```

> Running a CLI command
>
> The general syntax is as follows (the design is similar to tools like svn/git):
>
> java -jar jenkins-cli.jar \[-s JENKINS\_URL\] command \[options...\] \[arguments...\]
>
> JENKINS\_URL can be specified via the environment variable $JENKINS\_URL. This environment variable is automatically set when Jenkins fork a process during builds, which allows you to use Jenkins CLI from inside the build without explicitly configuring the URL.

NOTE: When running the safeRestart command, any jobs set to be executed during the restart will be queued up and executed when the server is back online. Make sure this does not cause any conflicts upon reboot!
> 12 votes

# Answer
To restart Jenkins manually, you can use either of the following commands (by entering their URL in a browser):

`(jenkins_url)/safeRestart` \- Allows all running jobs to complete. New jobs will remain in the queue to run after the restart is complete.

`(jenkins_url)/restart` \- Forces a restart without waiting for builds to complete.
> 5 votes

# Answer
I think this is a real problem that many are trying to solve. There are at times where it is preferable to restart Jenkins upon plugin installation. One of the suggestions that I can provide based on my experience is to:

* Restrict access to the admin module so that not every developer can install plugins
* Instruct developers on the downtime and inform them ahead of time
* Install all the required plugins in bulk and restart Jenkins
* Inform the developers that Jenkins is ready for use

I understand that this requires a manual effort and coordination. But this has worked so far so well in our project, thought no harm in mentioning.
> 2 votes

# Answer
Navigate to the **Plugin Manager**, then click on the **Installed** tab and scroll to the bottom. There should be a button there that says something along the lines of **Restart Jenkins once no jobs are running**.
> 2 votes

# Answer
Visiting "https://jenkins/safeRestart" does not wait for "jobs/builds" to be finished completely in case of pipeline jobs.

It seems to wait for steps to finish and perform jenkins restart and resume the pipline after jenkins have came up again.
> 1 votes

---
Tags: jenkins
---


# Question
Title: How can I find the version of Docker I am using?
As the title says, how can one find Docker's version?

# Answer
> 2 votes
For the daemon's version (meaning the engine's version) that's running on your server:

```
$ dockerd --version
Docker version 20.10.2, build 8891c58

```

For your client's version that's running on your local computer and with which you send commands to the daemon on the remote server:

```
$ docker --version
Docker version 19.03.13, build 4484c46d9d

```

---
Tags: docker
---


# Question
Title: How to get GitLab CI to rebuild on JIRA issue status change?
I would like to start builds in `GitLab CI` in response to `issue transitions` in `JIRA`.

I have not found a direct way to do that from searching online. I have found ways to get GitLab to tell JIRA what to do, but seemingly no solutions in the other direction.

We have a constraint which would make `JIRA` to `GitLab` messages very helpful: we must deploy to servers under the rule that a branch gets deployed

1. to ...test.example.com when the JIRA issue has status `QA`
2. to ...stage.example.com when the JIRA issue has status `Stage`
3. to ...beta.example.com when the JIRA issue has status `Beta`
4. to ....example.com when the JIRA issue has status `Done`

Note that we have added a `Merge Request` field to issues in our `JIRA`, so we know "the branch for an issue" (and "the issues for a branch").

To satisfy this constraint we run a python script to do deploys for `QA`, `Stage`, `Beta` every hour in a crontab for every project. That script has too many top-level loops, and too many features (being old).

Instead I would prefer to have `JIRA` notify that an issue is ready for re-build, and then ask our `GitLab CI` to re-build the relevant `Merge Request`.

In a JIRA workflow status transitions can "Trigger A Webhook", but it seems we will have to supply our own `REST api` to which `JIRA` can `post` messages, and which can then ping `GitLab`. That's a new internal app, which will need maintenance, and gain features, so we would like to find out if there are any other solutions.

# Answer
> 3 votes
I didn't get what's wrong with webhooks You just create a webhook on Gitlab CI side and provide this URL to your Jira account.

```
https://gitlab.com/api/v4/projects/PROJECT_ID/ref/REF_NAME/trigger/pipeline?token=TOKEN

```

`PROJECT_ID` \- unique project id on Gitlab

`REF_NAME` \- your `qa` / `stage` / `beta` branches within repository

`TOKEN` \- uniquely generated access token (gitlab provided)

Look here for more details how to trigger build on Gitlab via this call

# Answer
> 1 votes
One option for doing this is to create a database trigger.

## In Mysql

In MySQL and MariaDB, you can do this with mysql-udf-http. From perodriguezl answer from Stack Overflow:

> You can use a mysql-udf-http and then create a trigger like this:

```
delimiter $$
CREATE TRIGGER upd_check BEFORE UPDATE ON account
FOR EACH ROW
  BEGIN
    IF NEW.amount > 0 THEN
      set @json = select json_object(account_id,amount)
      select http_post('http://restservice.example.com/account/post',@json);
    END IF;
  END;$$

delimiter;

```

## In Postgres

In Postgres, you can write a stored procedure and use `plperlu` with `REST::Client`

From JustMe's Answer on Stack Overflow:

> ...the fastest way is to use `plperlu` with `REST::Client` package, e.g.:

```
CREATE OR REPLACE FUNCTION restful.put(auri character varying, ajson_text text)
 RETURNS text
 LANGUAGE plperlu
 SECURITY DEFINER
AS $function$
  use REST::Client;
  use Encode qw(encode);
  my $client = REST::Client->new();
  $client->getUseragent()->proxy( 'https', 'http://some-proxy/' ); # use for proxy authentication
  $client->addHeader('Content-Type', 'application/json');          # headers
  $client->POST( $_[0], encode('UTF-8', $_[1]));                   # encoding
  return $client->responseContent();
$function$

```

## Using Oracle

On an Oracle database, You will need to use `UTL_HTTP` \- Lucas Jellema's blog has a good example. There are also several others available.

## Conclusion

In each case, You would then presumably want to tweak your trigger to watch for an `update` statement on the table and check for the status you want to trigger off of (eg, you probably don't want to trigger off of new/closed) as well as make sure it is for the right project (Not quite sure how JIRA's schema is laid out - it might do one table per project. Eg, you probably don't want to trigger builds off of IT's tickets, but only off of dev or QA's JIRA project if you have multiple.)

---
Tags: gitlab, gitlab-ci-runner, jira
---


# Question
Title: How to find future (planned) versions of Docker?
I need to know a rough release date for the next Docker version(s) or the version scheme they are using for their releases (like "a new version every 3 months" or similar).

So I can plan updates in advance to reserve time for them.

Where might I find information about upcoming Docker releases?

# Answer
> 2 votes
I'll assume you're talking about Docker Engine for Linux.

Docker doesn't plan releases like that currently. What they do is:

Release major and minor versions on GitHub: https://github.com/moby/moby/releases

Put release notes in their docs: https://docs.docker.com/engine/release-notes

The version number is date based on the month they begin the release process, so the current version "20.10" started its release process in October, 2020 and was eventually released in December, 2020. The last major release before that was 19.03.

Finally, you can see what they are working on (features) and what's next on their Roadmap https://github.com/docker/roadmap/projects/1

---
Tags: docker
---


title: How to skip play in ansible-playbook?

text:
# Question
Title: How to skip play in ansible-playbook?
I have 2 plays in my sites.yml file:

---

```
- name: First play
  hosts: all
  remote_user: root
  roles:
       - role1

- name: Second Play
  hosts: all
  remote_user: ansible
  become: yes
  become_method: sudo
  connection: ssh
  gather_facts: yes
  roles:
     - role2
     - role3

```

The reason behind this is that, the first play will create ansible user with sudo access. Here, I have used root user to run the play. Then I have to run another play as ansible user.

My question is how to run these play one after another? I first want to run first one then after that second one.

If I run the playbook then it will get stuck because it will first run first play and tries to run second play where it gets stuck.

I am running playbook with the following command:

```
ansible-playbook -i inventory.ini -l web sites.yml --ask-pass -c paramiko

```

This is for 1st part.

# Answer
> 1 votes
Although the comments have highlighted the fact that this playbook is fine, as long as it is designed to do what it needs to do:

> The reason behind this is that, the first play will create ansible user with sudo access. Here, I have used root user to run the play. Then I have to run another play as ansible user.

In the first play, you have only one role: `role1`. If in `role1` you have a task that creates the ansible user, then you can use that user to connect the next time. This is actually something many people do, including myself, to put a known baseline on a service:

```
- name: Ensure Ansible user is present (RedHat)
  user:
   name: ansible
   comment: "ansible user created by bootstrap playbook"
   generate_ssh_key: yes
   groups: wheel
 tags:
 - bootstrap
 when: ansible_os_family=="RedHat"

- name: Ensure Ansible user is present (Debian)
  user:
   name: ansible
   comment: "ansible user created by bootstrap playbook"
   generate_ssh_key: yes
   groups: sudo
  tags:
  - bootstrap
  when: ansible_os_family=="Debian"

- name: update sudoers to ensure ansible user can sudo
  lineinfile:
    dest: /etc/sudoers
    state: present
    regexp: '^ansible'
    line: 'ansible ALL=(ALL) NOPASSWD: ALL'
  tags:
  - bootstrap

```

This will ensure that the user is added, and included in the right groups, with sudo rights -- it is just an example of how you could achieve this, there are other strategies of course.

> My question is how to run these play one after another? I first want to run first one then after that second one.

That's exactly how playbooks work.

> If I run the playbook then it will get stuck because it will first run first play and tries to run second play where it gets stuck.

If you do not have a task to configure the user required in the next play, then yes, it will fail (not get stuck). The point is that since Ansible is idempotent, you don't have to worry about skipping the play because if the user is properly configured, the first play will simply have no effect.

However, to answer the actual question

> How do I skip a play in an Ansible playbook ?

This is done using the conditional execution using `when`

# Answer
> 1 votes
I also tried to make something more "practical" so i just search a bit around and found the task: "include\_role" which allows loops. So i decided to loop that task with my target roles and use a when. Here the snippet:

```
- name: "Redhat"
  hosts: all
  become: yes
  tasks:
    - name: ADD Roles
      include_role:
        name: "{{role}}"
        apply:
          ignore_errors: yes
      with_items:
        - role1
        - role2
      loop_control:
        loop_var: role
      when: ansible_os_family=="RedHat"

```

---
Tags: ansible
---


title: Keeping AWS RDS Instances up to date

text:
# Question
Title: Keeping AWS RDS Instances up to date
We are running databases in AWS RDS (MySQL Databases), EC2 instances etc. We keep the EC2 instances up-to-date with the latest AMI based on the latest security patches etc, we do this through terraforms.

I assume that, AWS RDS being a managed service does not require the kind of updates that we are following for EC2. Please correct me if I am wrong and suggest the best practice.

# Answer
Your assumption is correct: you will not need to perform patching on an RDS instance, AWS handles that for you. There is a caveat, though: the majority of updates are not *forced* by AWS, but require an automated maintenance window to execute.

> Periodically, Amazon RDS performs maintenance on Amazon RDS resources. Maintenance most often involves updates to the DB instance's underlying hardware, underlying operating system (OS), or database engine version. Updates to the operating system most often occur for security issues and should be done as soon as possible.

> Some maintenance items require that Amazon RDS take your DB instance offline for a short time. Maintenance items that require a resource to be offline include required operating system or database patching. Required patching is automatically scheduled only for patches that are related to security and instance reliability. Such patching occurs infrequently (typically once every few months) and seldom requires more than a fraction of your maintenance window.

Source: Maintaining a DB Instance

That document has a lot of useful information about the types of maintenance, the maintenance windows, and the manual actions you can take.

Database engines need patching, too, and AWS refers to this as a minor engine upgrade. When necessary, these upgrades happen during the aforementioned maintenance windows, **but** you need to ensure your RDS instance has **Auto Minor Version Upgrade** enabled to take advantage of this feature.

Source: Automatically Upgrading a Minor Engine Version
> 2 votes

---
Tags: amazon-rds
---


# Question
Title: Is cross-region Kubernetes a thing, and if so, what role does VPN place in this context?
Given you are going to overcome risks of a whole cloud region going offline, you would implement some cross-site distribution mechanisms.

In terms of Kubernetes, cluster communication would happen across public network.

Therefore, probably, you need to setup end to end VPN connections?

Does this all make sense or how do you approach the problem?

# Answer
First, etcd is a core component in Kubernetes clusters. It is based on the Raft Consensus Algorithm and a **weaker point** with it is when the latency between the members (e.g. in the distribued etcd database) in the cluster is *larger* and *vary more*. It might work to deploy it with longer latency between the nodes (e.g. regions as in cross-region) but it might not be the best idea, at least not out of the box.

But if you use cross-region deployments, one of the main reason to do it is probably to tolerate a full region outage - but then I think it is even a better idea to deploy independent (e.g. can work without the other) clusters.

What might be interesting in relation to this is Kubernetes Federation Evolution and kubefed.

I don't see VPN (e.g. a single network?) very related to this (this is more its own topic) - at least not when you want independent clusters. SSL/TLS might also be related. And if you do cross-regions, e.g. Software Defined Network or cloud VPC might be related as well. E.g. Amazon VPC is located on a single region, but Google Cloud VPC is global (multi-region).
> 3 votes

---
Tags: kubernetes, sre, vpn
---


# Question
Title: Gitlab CI/CD fails to build docker image
I have built a custom base image from alpine and use it as the base for ruby services that we develop.

```
FROM ruby:2.4.2-alpine
...

```

I use Gitlab and Gitlab's docker registry along with it. Each project has its own docker image storage.

I created a separate project for the **alpine-ruby-service** dockerfile. Then build and pushed the image to Gitlab.

In the ruby service project docker images, I reference it as follows

```
FROM gitlab.mycompany.dk/alpine-ruby-service-base
...

```

I have a CI/CD pipeline (.gitlab-ci.yaml) which builds these ruby service images when there is a commit to one of the branches.

The problem is that when the CI/CD pipeline is run it fails with the following message

```
 $ docker build --pull -t $CONTAINER_TEST_IMAGE .
   Sending build context to Docker daemon  709.6kB

 Step 1/13 : FROM gitlab.mycompany.dk:xxxx/alpine-ruby-service-base
 pull access denied for gitlab.mycompany.dk:xxxx/alpine-ruby-service-base,
 repository does not exist or may require 'docker login': denied:
 requested access to the resource is denied

```

I have an instruction to login to the Gitlab docker registry before the build command above using

```
 docker login --username=gitlab-ci-token --password=$CI_JOB_TOKEN gitlab.mycompany.dk:xxxx

```

the login succeeds but the following docker build instruction fails!!! can someone point me what is going wrong?

# Answer
It looks like that the `docker login` and the `docker build` were done by different users. If a `docker login` is performed, then a `~/.docker` directory will be created in the namespace of user X, if the build is done by user Y then the latter user does not have a .docker folder and is not authorized to pull the image. One could verify this by `echo $USER` in the pipeline, in this case gitlab-ci.yaml to check this.
> 2 votes

# Answer
This could also be happening if you perform a `docker login` before the `docker pull` in a gitlab runnner as instructed if:

Your shell runner is configured to run multiple builds and all the builds share the same home directory /home/gitlab-runner-username. Per default `docker login` saves the credentials in ~/.docker/config.json. When there is multiple build jobs running the second build job may overwrite the credentials of the first one. When the second one is triggered by a different user or finishes before the first one, the first one may get the `denied: requested access to the resource is denied` message even tough you logged in properly.

On our servers i solved this by using a custom credentials script that does not store the credentials in a shared file but uses the credentials present in the gitlab ci job environment
> 0 votes

---
Tags: docker, gitlab, cicd, docker-registry
---


# Question
Title: Importing non-default workspaces in Terraform
I'm having a bit of trouble with Terraform. I have a Terraform project which is shared by a few developers and uses non-default workspaces (i.e. named workspaces, not the default one). I would like all the developers to share access to the Terraform state of this shared workspace the same way as if it was the default workspace. I have set up remote state with S3, so the state file is singleton, but for some reason I can't get the remote state file to be recognized on each developer's machine.

Basically the workflow I would like is, when developer A pushes a change to Terraform (using `terraform apply`) then any other developer who runs `terraform state list` should see that change reflected in the deployed infra, and that this workflow should work for any workspace, not only the default workspace.

How do I accomplish this?

# Answer
As the docs state, workspaces are for *distinct* resources:

> Named workspaces allow conveniently switching between multiple instances of a single configuration within its single backend. They are convenient in a number of situations, but cannot solve all problems.

> A common use for multiple workspaces is to create a parallel, distinct copy of a set of infrastructure in order to test a set of changes before modifying the main production infrastructure. For example, a developer working on a complex set of infrastructure changes might create a new temporary workspace in order to freely experiment with changes without affecting the default workspace.

If you would like all developers to see the same state, they have to use the same workspace. If you want this to be the case for *arbitrary* workspaces, then it seems that this is an abuse of the concept of the workspace. It is possible, but I would strongly advise against it, to import resources from non-default workspaces into the default one, in some kind of automated way. You could also use the default workspace state as the non-default's remote state, but again, I would strongly advise against this, arguing that it introduces unnecessary complexity and fragility to your process.

If you want all developers to see the same resources in the state, then they should simply all use the same workspace. If they are not seeing the correct state, it is because the workspace or the remote state location that they are using is different.
> 1 votes

---
Tags: terraform, infrastructure-as-code
---


# Question
Title: Azure DevOps deploy to Azure VM's without a public IP
Is it possible to deploy from Azure DevOps to an Azure VM that only has a private IP address? I need to deploy to VM's that won't always have a public IP address.

I thought there might have been some internal Azure network that could be used but running the deployment agent script on my VM without a public IP fails (it works if the machine does have a public IP). Other than that can Azure DevOps connect to a Azure VPN (Virtual Network Gateway) to access the VM's on my Virtual Network?

# Answer
Yes, it is possible. You can use Self-Hosted agents directly on one or all of the VMs: Link
> 1 votes

---
Tags: azure-devops, azure
---


# Question
Title: Docker container can't reach host services
I am running a nodejs app in a docker (v 20.10.2) container on a Ubuntu 20.04 LTS (this is for dev purpose only)

My docker-compose config

```
  test:
    container_name: forge_test
    restart: always
    image: "node:lts"
    volumes:
      - ../src:/home/node/app
    command: "node test.js"
    user: "node"
    working_dir: /home/node/app
    extra_hosts:
      - "host.docker.internal:host-gateway"

```

In the docker, I can ping `host.docker.internal` (which does not work without extra\_hosts), however I can not reach any services that I have running on any port (the port I am actually trying to reach is 7545 but none work) on the host.

Searching for a few hours now, no solutions I have found (adding docker0 to iptable, adding docker.host.internal to /etc/hosts) work.

Am I missing something? Could there be a firewall blocking access somewhere (II have ufw installed but tbh I don't really know how to use it)?

I can't find any similar issue where `host.docker.internal` can be pinged but the posrts not accessed

# Answer
> 1 votes
It happens that the problem comes from ufw not allowing connections from docker containers on host ports. Deactivating it helped for now, since it's only for dev purpose.

---
Tags: docker
---


# Question
Title: What is the AWS equivalent of Azure Management Groups?
Microsoft Azure has Management Groups. (They are a level above subscriptions that allow you to organize subscriptions into containers called "management groups" and apply your governance conditions to the management groups. )

When I studied for my AWS Associate Architect, I don't recall running across an equivalent concept. I'm trying to work out if Amazon Web Services has an equivalent.

My question is: **What is the AWS equivalent of Azure Management Groups?**

# Answer
There is no direct equivalent to Management Groups in AWS.

You can achieve some of the same functionality by using AWS Control Tower, specifically around access controls. I.e. you can set up groups and assign roles to any accounts in an AWS Organization on a per-account or per-group basis and have them deployed to child AWS accounts.

However, there is no such equivalent around, for example, resource allocation.

You can achieve some of the same functionality by using CloudFormation, or by using CT IAM policies policies with specific restrictions, but it's a much more convoluted process than with Azure.
> 1 votes

---
Tags: amazon-web-services, azure, management-groups
---


# Question
Title: how to set automatic git pull from bitbucket and complie project on ec2 instance create event with auto scaling
I have just started reading about AWS services. I have a project where the backend is created with `Spring-Boot`, front-end is created with `React` and `PostgreSQL` is used as database. Both backend and frontend is different `bitbucket` repository. I want to use two different `EC2` instance for front & back-end and `RDS` for `PostgreSQL`. Now I also want to use the autoscaling feature. The problem is how can I set the autoscaling feature in such a fashion where it automatically clone the app from bitbucket and then run a shell script file to compile and run the application.

# Answer
You want to make use of user\_data scripts.

It's basically a bootstrap shell script that gets executed on an instance during launch.

You can embed your app configuration script in there (either directly via bash, or have it call your configuration management software like Ansible or Chef).

Then, if you attach this script to a Launch Template or a Launch Configuration (which is an instance template required as part of an AWS ASG), it will be applied to the whole autoscaling group.

Then, when you have a scaling event, any new instances that come up in the ASG will run the script and deploy your code.

However, I would recommend you look into immutable infrastructure instead. I.e. set up automation (i.e. via Packer) that builds your application code into your AMI, with user\_data only used for actually starting the app.

Then, when you have a new build, have the same automation build a new AMI and replace your ASG (note you'll need to have your ASG created/deployed in a programmatic fashion.. I personally recommend Terraform).
> 1 votes

---
Tags: amazon-ec2, deployment, autoscaling
---


# Question
Title: Is it possible to have an aws EKS infrastructure as code?
Is it possible to declare "a complete production level EKS with other aws services" using terraform? I know that terraform has an eks module and an aws provider. But I'm not sure if one can create everything (ALB, IAM roles and policies, security groups, ebs, efs, rds, aws networking, ...) using terraform.

I want to learn aws by experimenting. But I cannot afford spending that much money. So I need to be able to destroy everything and recreate the exact infrastructure whenever it's needed.

I've found a really good aws workshop. But like almost all of tutorials, it's based on running "eksctl and aws cli" commands.

Is there a reliable way of declaring everything once and recreate the whole infrastructure declarativly (without touching aws console)?

# Answer
> Is it possible to declare "a complete production level EKS with other aws services" using terraform?

Yes, and that is what many larger organizations do. I have implemented Kubernetes with other AWS resources this way for larger companies e.g. a bank, using Terraform.

> I want to learn aws by experimenting. But I cannot afford spending that much money. So I need to be able to destroy everything and recreate the exact infrastructure whenever it's needed.

That should go well. You can use e.g. `terraform apply` to provision infrastructure and `terraform destroy` to take it down. I would also recommend to add tests on your infrastructure using e.g. Terratest and perhaps use tfsec in a *pipeline* so that you are comfortable that new changes does not break your cluster - using *Infrastructure as Code* the full way.

> Is there a reliable way of declaring everything once and recreate the whole infrastructure declaratively (without touching aws console)?

Yes, that is a best practice.
> 3 votes

---
Tags: amazon-web-services, terraform, amazon-ec2, infrastructure-as-code, eks
---


# Question
Title: How to skip Build without creating Drop and not triggering Release in Azure DevOps
Currently we have a build pipeline which checks if there is a PR for the current branch and if yes it sets a variable and skips the other build steps.

But when this happens the Release still completes as Successful and a empty drop is created. This triggers a release which fails because drop is empty.

This is the dumbed down version of the build pipeline:

```
    stages:
    - stage: CheckShouldBuildStage
      displayName: Check Should Build
      jobs:
      - job: CheckShouldBuildJob
        displayName: Check Should Build
        steps:
          - powershell: |
                $doBuild = $True
                $sourceBranchName="$env:BUILD_SOURCEBRANCHNAME"
                $buildReason="$env:BUILD_REASON"

                # Get PR information for branch
                ...

                if ($branchHasPr -eq $True -and $buildReason -ne "PullRequest" -and $buildReason -ne "Manual") {
                   $doBuild = $False
                   Write-Host "Pr Build found, and not the merged PR build. Cancelled build."
                }

                ...

               if ($doBuild -eq $True) {
                  Write-Host "DoBuildVar=YES"
                  Write-Host "##vso[task.setvariable variable=DoBuildVar;isOutput=true]YES"
                } else {
                  Write-Host "DoBuildVar=NO"
                  Write-Host "##vso[task.setvariable variable=DoBuildVar;isOutput=true]NO"
                }
            name: CheckShouldBuildTask
            displayName: Check Should Build
    - stage: BuildAndTest
      condition:
        eq(
          dependencies.CheckShouldBuildStage.outputs['CheckShouldBuildJob.CheckShouldBuildTask.DoBuildVar'],
          'YES'
        )
      dependsOn: CheckShouldBuildStage
      displayName: Build and Test
      jobs:
         ...

```

What should be the correct way to skip a build and not trigger a Release? Is it possible to just disable the creation of an empty drop?

I tried to disable the creation of an empty drop, but all my search results are just people where there was no drop created on mistake.. so this was a dead-end.

I also know I can just fail my build pipeline but this would show up in the stats. As far as I can tell there really only is Success and Fail as a status for a pipeline. So this solution is also not working out for me.

# Answer
Try and add a Stage condition to only run that stage for a specific branch.

```
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'))

stages:
- stage: A
             .....

- stage: B
  **condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'))**
  jobs:
  - job: B1
    steps:
      - script: echo Hello Stage B!
      - script: echo $(isMain)

```

Reference : https://docs.microsoft.com/en-us/azure/devops/pipelines/process/conditions?view=azure-devops&tabs=yaml

PS : Will refine the answer in future, currently we are still using GUI for releases and we are using this branch filter to control this scenario.
> 1 votes

---
Tags: azure-devops, azure, azure-pipelines, build-pipeline
---


title: Migrating to AWS with Devops

text:
# Question
Title: Migrating to AWS with Devops
What are they key stages of migrating to AWS with Devops ?

Can anyone list a use case or workflow?

# Answer
Continuous Deployment is certainly a no brainer for mission critical applications but you may try Azure DevOps from MS which integrates with AWS beautifully and has provisions for environment approvals which can help move to that state in a user friendly and elegant manner. IMO, AWS code deploy is still not at par with Azure DevOps. And perhaps you may want to incrementally move there and refine your used case.

e.g. Instead of weekend deploy, you can make the process decoupled and efficient that you can do it on a Friday night, then setup blue/green in Beanstalk or EKS et to reach that state. Also for the 6000 hosts, you definitely want to try and see which can live in Kubernetes for ephemeral instances and review the infrastructure footprint. Don't forget cloud is expensive, a lift and shift of that many VMs would have exponential costs in cloud.

I work in healthcare so unsure about retailers, but thought I will suggest that tool (Azure DevOps) incase your client isn't familiar with DevOps for easier transition.

Also to be more comprehensive, consider monitoring, security etc also as a part of your effort in your white paper.

One of the most comprehensive DevOps roadmap (evolving) is this, you may consider all the aspects from this chart for your whitepaper -

https://roadmap.sh/devops
> 2 votes

---
Tags: amazon-web-services, amazon-s3, aws-lambda, workflow, migration
---


title: Change docker container’s log PATH

text:
# Question
Title: Change docker container’s log PATH
Team: All my container logs are under /var/log/containers..

Where in kubelet or docker config can I specify this path such that logs are instead created under new path? Ex : /shared ? Instead of /var/log

# Answer
> 1 votes
I got a work around to this case. basically, My root volume is 100GB and I created a separate partition out of it as 70GB and I set it to a new device sda3 and mounted it to /var/lib.

now, all docker container logs are written in same path but in backend they are mounted to a different drive. with this setup, even if there is disk pressure, the node does not become unavailable.

so my drive now looks liek below

```
sda1
sda2 / 30GB
sda3 /var/lib 70GB.  << new device

```

---
Tags: docker, kubernetes, containers
---


title: Pattern(s) to scale node.js based ETL

text:
# Question
Title: Pattern(s) to scale node.js based ETL
I have a node.js ETL application that transforms data from 1..n locations and from each location there will be 0..m transactions. The application is started via cron on a configurable interval, currently 15 minutes. Currently, the pattern employed is to use Promise.map({concurrency:x}) at both the location and transaction level to obtain a combined degree of concurrency to achieve the maximum throughput (constrained by DB I/O.

Right now the app runs on a single Ubuntu VM, processing 6 locations and ~ 1000 transactions/location. So minimal data processing overhead. The pattern works. But when there are 1000+ locations and possibly more transactions per interval, the pattern will still work of course, but the time to complete all locations will grow. Being node, the process is single threaded and so the pattern is not leveraging the available cores.

So I’m thinking about how to change the pattern to scale. Options I’m considering (not mutually exclusive)

* containerise the app, start one for every n locations - based on some manual determination of # of locations to process per container.
* remain non containerised but use fork() to leverage additional CPU’s and partition on n locations

Based on my reading to date, my approach is:

* forget “fork"
* containerise the app
    + spin up x apps, x being determined based on manual determination since the parameters are known vs dynamic
    + each container would be responsible for n locations
    + each app would set its own “cron” to orchestrate its batch processing

Not being an expert in docker (but reasonably familiar) and certainly a newbie to orchestration, I would appreciate any guidance on how containers / orchestration might help.

# Answer
I ended up following this path

Rather than use cron, i used a scheduling framework (in my case Bree.js) which allowed me to "jobify" the tasks and also execute these tasks in separate processes - this allowed me the vertical expansion needed (ie: using more processor cores)

A docker container contains the dispatch (scheduling) and jobs - so once the container is started, jobs (and associated processes) are created/managed within that container

Eventually, when I need to scale horizontally, the "dispatch" function will morph to running a job whose sole purpose is to post an event (eg: Azure service bus). I will have an orchestrator running various containers who read from the queue and process accordingly.
> 1 votes

---
Tags: docker, kubernetes, node.js, orchestration, scalability
---


# Question
Title: Jenkins: Access job/plugin configuration values inside pipeline
I am trying the access the values set on a job's configuration page from within my pipeline. These values are not made available as params, nor are they injected as envvars.

**Setup**

* Jenkins, v2.263.1
* GitLab Branch Source plugin, v1.5.3 (link)
* Multibranch pipeline job which is pointed to a Gitlab repo
* Remote Jenkinsfile Provider, v1.13 (link)

**Problem**

Ordinarily, one would have a *Jenkinsfile* in the root of the repo and therefore the scm would be associated with the repo we want to checkout and build. However, in my case the code I want to build is in a different repo to the Jenkinsfile (hence the *Remote Jenkinsfile Provider* plugin).

This means that I need to checkout the code I wish to build as an explicit step in the pipeline, and to do that I need to know the repo. This repo is, however, already defined in the job config.

The *Branch Source* plugin does export things like the branch name or merge request number/branch/target into appropriate envvars, but NOT the actual repo.

As this is a multibranch pipeline, I cannot use something like *envInject* either (multibranch jobs do not provide the option to 'Prepare an environment for the run' as with other jobs)

**Goal**

I would like to be able to access the `server`, `owner` and `project` fields set in the job config page. Ultimately I could manage with just the project's ssh/http address even.

**Is there some clever way of accessing a job's config from within the pipeline?**

Thanks for any suggestions!

**Reference images**

# Answer
> 2 votes
This is possible, but you'll have to use scripted Pipelines, not declarative, disable the Groovy sandbox for pipelines, and dig deep into the Jenkins API.

For instance, I wrote a Pipeline job that edits the parameters of a second job which has a full name of "SCA/deploy\_to\_environment/master". Here's a snippet of that code - I'm eliding how to create the "Param" objects in the first line for brevity, this snippet is just to give you an idea of what a similar use case looks like:

```
def paramProp = new ParametersDefinitionProperty(envParam, pgParam, infoParam)

def job = Jenkins.instance.getItemByFullName('SCA/deploy_to_environment/master')

// There is no "setProperty" - we need to remove and replace.
// removeProperty is safe to run even if no matching properties are set on the job.
// However, this method only removes one property per method call.
// Theoretically, this means the job could accumulate multiple conflicting
// ParametersDefinitionProperty properties.
// TODO: run removeProperty in a while loop to eliminate all matching properties for extra safety.
job.removeProperty(ParametersDefinitionProperty)

job.addProperty(paramProp)

```

So to fetch the values instead of simply editing them, you would need to instead call `getProperty` (API doc here), passing the class name of the GitLab Project parameter classes. I suspect the class name you'll need is available somewhere in the source code or the API docs for that plugin, but I'm not sure.

---

However, I have to ask, why do you want to do this? What's the big picture here?

It sounds kind of like you want to share a single Jenkinsfile or build pipeline among multiple repositories. I also have this use case at my job - we need to have one Jenkinsfile shared across nearly 200 repositories. If this is similar to your need, then consider using Jenkins Shared Libraries. You can put all of your build pipeline code into a single shared library, then call the shared library in a single line from the Jenkinsfile in your individual repositories.

---
Tags: jenkins, jenkins-pipeline, gitlab, jenkins-plugins, jenkinsfile
---


title: Skip stages in Jenkins pipeline

text:
# Question
Title: Skip stages in Jenkins pipeline
I am using a scripted pipeline where I am required to skip some stages conditionally.Is there a way to show skipped stages on Jenkins UI other than importing **org.jenkinsci.plugins.pipeline.modeldefinition.Utils** in the jenkinsfile as the import is giving me "cannot resolve class" error while running build.gradle for some other script.

# Answer
> 1 votes
By default, there is no way to visualize skipped stages in the Jenkins UI. See this issue report on the Jenkins JIRA about visualizing skipped stages.

There are a few workarounds that I'm aware of:

You can disable the Groovy sandbox to allow importing the aforementioned class.

You can also use the imperative-when plugin for scripted Pipelines as described in this blog post to add visualization (note that I haven't tested this personally).

Or you can skip the visualization altogether and wrap your build steps in an if clause to conditionally execute them. You'll see in the Jenkins UI that a stage takes 0ms to execute if it has no steps, so there's at least some indication that it was skipped even if it doesn't explicitly say "skipped".

---
Tags: jenkins, jenkins-pipeline, jenkins-plugins, jenkinsfile
---


# Question
Title: How do i print the list of jobs per plugin in Jenkins
I'm trying to list the jenkins jobs per plugin is being utilized. I see there's a plugin in jenkins, https://github.com/jenkinsci/plugin-usage-plugin, which displays the plugins usage in the Jenkins UI. But how do i get the same output from the groovy script?

# Answer
> 1 votes
They quick and dirty answer is to "Display jobs group by the build steps they use" as updated below.

```
import hudson.model.*
import hudson.tasks.*

//All the projects on which we can apply the getBuilders method
def allProjects = Jenkins.instance.allItems.findAll{ it instanceof Project }

//All the registered build steps in the current Jenkins Instance
def allSteps = Builder.all()

//Group the projects by the build steps used
def projectsGroupBySteps = allSteps.inject([:]){
   map, step ->
   map[step.clazz.name] = allProjects.findAll{it.builders.any{
        it.class.name.contains(step.clazz.name)}}.collect{it.fullName}
   map
}

//Presentation
projectsGroupBySteps.sort().each{
    println "--- ($it.value.size) $it.key ---"
}
println ''

println 'Occcurences:'
projectsGroupBySteps.sort().each{
println "--- ($it.value.size) $it.key ---"
    it.value.each {
        println it }
    println ''
}
return

```

Note that a job has multiple sections: **builders**, **publishers** and **buildWrappers**. Depending on what you are looking for, replace

```
[allSteps = Builder.all(), allProjects.findAll{it.builders.any ]
[allSteps = Publisher.all(), allProjects.findAll{it.publishers.any ]
[allSteps = BuildWrapper.all(), allProjects.findAll{it.buildWrappers.any ]

```

Plugins may also be involved in the **SCM** section and as **properties** (eg: `hudson.plugins.buildblocker.BuildBlockerProperty`, `com.sonyericsson.jenkins.plugins.bfa.model.ScannerJobProperty`)

Obviously, same limitations of plugin-usage apply: does not scan pipeline steps plugin usage or build steps nested within an `org.jenkinsci.plugins.conditionalbuildstep`

---
Tags: jenkins, jenkins-plugins, groovy
---


title: Deply method for python project

text:
# Question
Title: Deply method for python project
I have made a web application in django. Currently I'm deploying by SSH'ing into my ubuntu instance at AWS and using git pull. However I know this isn't a very scaleable solution but I have very limited knowledge of DevOps. So, my question is if anyone could recomend which applications I need to use to achieve the following:

* I can launch more instances with just a click (probably Docker if I've understood it?)
* When I git push by project, all running servers pull and run migrations and reboot.

# Answer
What you're looking for is a CI/CD pipeline. There's lots of articles around it, but the main steps would be as follows:

1. Some form of build artifact (it can be a docker container, but it can also be a tarball, or just code in a git repo).
2. Some way to automatically deploy your code. This is done by using a CI/CD tool (literally any of them will work fine, but for the love of god, don't use Jenkins, you'll thank me later).

For something as simple as how you describe your app, you can just use a CICD tool to SSH in and deploy to your existing server.

For example, CircleCI (one of my favourite tools and what we use at my current job), has a free tier that gives you 2500 minutes of build time a month. It also has an SSH orb you can include in your pipeline configuration that will SSH into your server and run a few commands to pull down the latest code and restart your server.

Here is a good Getting Started guide that should get you up and running with Circle.

If you'd like to start using docker, here is a good guide on how to run your Django app with it. From there, you would need to set up a Dockerhub account and push your docker image there, to be deployed on a server. Note you'll have to make sure you can configure your application through environment variables. It's never a good idea to have an artifact with "baked in" configuration, since this method doesn't scale in any real way.
> 3 votes

---
Tags: docker
---


# Question
Title: Is there a way to combine helm with some other tool for k8s configuration management without conflicts?
Currently I have a k8s project with multiple services which are managed by a helm chart. Said helm chart is installed on my local machine and I want to keep it this way if it's possible. But now I need to provide a simple user-friendly way to change versions of some service's docker images for other people. I was thinking about creating a jenkins task which would allow changing "image" field for those services, but it would create conflicts with my helm release: next time I update something with helm, it would rollback jenkins "image" field changes to the values in my helm chart.

Is there a simple way to resolve this conflict, like saying helm not to change "image" field? If not, how can I continue using helm for project configuration while allowing "image" field changes from jenkins?

# Answer
Helm isn't made to be used this way. If you'd prefer to use a static deployment, you're better off using a plain Kubernetes manifest. Then, people changing the image field won't break your release.

You can easily convert it to one simply by running helm get manifest command

Helm is used to manage release versions. I.e. every new release (and a docker image change definitely qualifies as one), you would push a change to your helm chart.

The other alternative you have is defining docker image as a value. Then you can pass a command-line argument to replace the image tag with a new one and re-run helm from Jenkins any time you have a new deploy.

Example:

in values.yaml:

```
image:
  repo: foo
  tag: bar

```

On command line when running helm:

```
helm upgrade --install my-app --set image.tag=newtag

```

Final, and least recommended way is to use a mutable tag (i.e. "master") and set your `ImagePullPolicy` to `Always`. This way, when you have a deploy, you just need to bounce all the pods in your deployment/daemonset/statefulset object.
> 2 votes

---
Tags: jenkins, kubernetes, deployment, helm, kubernetes-helm
---


# Question
Title: What does "eksctl create iamserviceaccount" do under the hood on an EKS cluster?
AWS supports IAM Roles for Service Accounts (IRSA) that allows cluster operators to map AWS IAM Roles to Kubernetes Service Accounts.

To do so, one has to create an iamserviceaccount in an EKS cluster:

```
eksctl create iamserviceaccount \
    --name <AUTOSCALER_NAME> \
    --namespace kube-system \
    --cluster <CLUSTER_NAME> \
    --attach-policy-arn <POLICY_ARN> \
    --approve \
    --override-existing-serviceaccounts

```

The problem is that I don't want to use the above `eksctl` command because I want to declare my infrastructure using `terraform`.

Does eksctl command do anything other than creating a service account? If it only creates a service account, what is the `YAML` representation of it?

# Answer
Yes It does more than just creating a service account. It does three things:

1. It Creates an IAM role.
2. It attaches the desired iam-policy (--attach-policy-arn \<POLICY\_ARN\>) to the created IAM role.
3. It creates a new kubernetes service account annotated with the arn of the created IAM role.

Now It's easy to declare the above steps using kubernetes and aws providers in terraform.
> 2 votes

---
Tags: kubernetes, amazon-web-services, terraform, aws-iam, eks
---


# Question
Title: Can you remove a commit made to a branch on AWS code commit?
I know of git rebase but don't know if it can be used with AWS code commit? Or if there's any other method of removing a commit to revert back to before it was made and merged?

# Answer
Simplest answer is to just revert the commit. AWS Code Commit is standard Git and will support everything Git allows you to do.

I.e. find commit hash:

```
git log -n1
commit 444c954e458cc446e2a7a1f2659adf71bdf55580 (HEAD -> my-branch, origin/my-branch)

```

Then do the revert:

```
git revert 444c954e458cc446e2a7a1f2659adf71bdf55580
git push

```

It'll revert your repo to whatever state it would be without that specific commit. Note that if you have other commits that modified the same files afterward, you will have a merge conflict and will have to fix them manually.
> 2 votes

---
Tags: amazon-web-services, git, versioning
---


title: How can I model this schema in MySQL?

text:
# Question
Title: How can I model this schema in MySQL?
I want to create a schema that reflects the following relationships, and I'm trying to do this in MySQL Workbench. (I'm no DB expert)

* I have 3 environments - sandbox, staging, and production
* I release a product version in each environment, e.g., `sb-1.0.0` for sandbox, `st-1.0.0` for staging, and `pr-1.0.0` for production. I can have multiple releases per environment, but there can only be ONE version that's currently released in each environment.
* Each product version in each environment contains a set of services, same set of services in all the environments, but differing in their version numbers. So `sb-1.0.0 = [svc1-2.0.0, svc2-2.0.0], st-1.0.0 = [svc1-1.0.0, svc2-2.0.0], and pr-1.0.0 = [svc1-1.0.0, svc2-1.0.0]`. As you can see, I have the same 2 services in all environments, but the service versions can be different (or the same) in each environment.

I want to accomplish multiple things.

* I want to be able to create new releases in each environment, with each release containing the set of services and corresponding versions. So I want to be able to create a `pr-2.0.0 = [svc1-2.0.0, svc2-1.0.0]` version.
* I want to be able to query my DB for version `pr-1.0.0` and know all the services and their respective versions in this particular release.
* I want to have the notion of a "current version" and a "desired version" for each service in each environment.
* I want to be be able to then run a script (Kubernetes?) to release each service and their respective version based on the query.
* I want to be able to extend it to more environments, e.g., add a UAT environment.

So how do I model my DB?

# Answer
I want to credit Max N for making me think about another solution.

In fact I already have the solution, right in front of me. We're a Gradle shop, and our `build.gradle` files contains our dependencies. So when I release a version, I know exactly what services+versions I need for this version. Since we have branches corresponding to our environments, I the services I need in each environment. So when I just need to

* I need to Git tag every time we do a build, including the tools that did the build
* When deploying, I then need to deploy above tag, which includes code + tools

Thanks again Max N.
> 0 votes

# Answer
Have you thought about what happen with stale/old data??

* Each new version creates a ton of new entries.
* Management becomes a nightmare
* the DB becomes a SPOF(single point of failure).

---

# Better Solution: Service discovery

The better solution would be to use a Service discovery System and annote each Service with their version and the environment as a Metadata tag. This keeps the System more manageble.

# More Help

IMHO, sticking Linux Code into a **Docker Image** and run multiple copies of it, is the best way of getting a immutable infrastructure up and running.
> 1 votes

---
Tags: databases, mysql
---


# Question
Title: Jenkins Slaves cannot connect to the Master Jenkins
I switched the Jenkins to using https on port 8080 . After a restart of the Jenkins,the slaves cannot reconnect.

I changed only Jenkins location from Configure System -\> Jenkins Location -\> Jenkins URL to https://localhost:8080

Know someone who can answer?

# Answer
It depends on how you connect you slaves via ssh or jnlp, in any case: check if you are able to connect that slave and try telnet it.
> 0 votes

---
Tags: jenkins, windows
---


# Question
Title: Confluence mySQL image doesn't start anymore
I am running a confluence container containing an image for the application itself and one for the mySQL db. This was running smoothly until I run the latest Docker update. Since then, the mySQL image is constantly trying to restart, but the start fails.

This is my docker-compose.yml:

```
version: '3'
services:
  confluence:
    build: ./confl_mysql
    restart: always
    volumes:
      - /Users/michimacmini/Confluence/data/confluence:/var/atlassian/application-data/confluence
    ports:
      - 8090:8090
      - 8091:8091
  confl-mysql:
    image: mysql
    restart: always
    command: [mysqld, --character-set-server=utf8mb4, --collation-server=utf8mb4_bin, --transaction-isolation=READ-COMMITTED, --max_allowed_packet=512M, --innodb_log_file_size=2GB]
    environment:
      - MYSQL_RANDOM_ROOT_PASSWORD=yes
      - MYSQL_DATABASE=confluence
      - MYSQL_USER=confluence
      - MYSQL_PASSWORD=mypw
    volumes:
      - /Users/michimacmini/Confluence/data/mysql:/var/lib/mysql

```

And this is what the log says:

```
Most likely, you have hit a bug, but this error can also be caused by malfunctioning hardware.
Thread pointer: 0x0
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 0 thread_stack 0x46000
/usr/sbin/mysqld(my_print_stacktrace(unsigned char const*, unsigned long)+0x2e) [0x5630e9ffe41e]
/usr/sbin/mysqld(handle_fatal_signal+0x31b) [0x5630e940508b]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x12730) [0x7f8f50967730]
/lib/x86_64-linux-gnu/libc.so.6(gsignal+0x10b) [0x7f8f500447bb]
/lib/x86_64-linux-gnu/libc.so.6(abort+0x121) [0x7f8f5002f535]
/usr/sbin/mysqld(+0x342ae53) [0x5630ea4ade53]
/usr/sbin/mysqld(+0x34168e8) [0x5630ea4998e8]
/usr/sbin/mysqld(srv_pre_dd_shutdown()+0x49d) [0x5630ea44b3ad]
/usr/sbin/mysqld(+0x1ec460f) [0x5630e8f4760f]
/usr/sbin/mysqld(plugin_foreach_with_mask(THD*, bool (**)(THD*, st_plugin_int*, void*), int, unsigned int, void*)+0x1cf) [0x5630e92cb50f]
/usr/sbin/mysqld(plugin_foreach_with_mask(THD*, bool (*)(THD*, st_plugin_int*, void*), int, unsigned int, void*)+0x1d) [0x5630e92cb71d]
/usr/sbin/mysqld(+0x1de01c1) [0x5630e8e631c1]
/usr/sbin/mysqld(+0x1de4252) [0x5630e8e67252]
/usr/sbin/mysqld(+0x1df027c) [0x5630e8e7327c]
/usr/sbin/mysqld(mysqld_main(int, char**)+0x1e73) [0x5630e8e75d33]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xeb) [0x7f8f5003109b]
/usr/sbin/mysqld(_start+0x2a) [0x5630e8e5a02a]
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains
information that should help you find out what is causing the crash.
2021-01-05 09:43:39+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.21-1debian10 started.
2021-01-05 09:43:39+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2021-01-05 09:43:39+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.21-1debian10 started.
2021-01-05T09:43:39.950273Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.21) starting as process 1
2021-01-05T09:43:39.959740Z 0 [Warning] [MY-010159] [Server] Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive
2021-01-05T09:43:39.980489Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2021-01-05T09:43:42.367077Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2021-01-05T09:43:42.383162Z 1 [ERROR] [MY-011087] [Server] Different lower_case_table_names settings for server ('2') and data dictionary ('0').
2021-01-05T09:43:42.383806Z 0 [ERROR] [MY-010020] [Server] Data Dictionary initialization failed.
2021-01-05T09:43:42.384234Z 0 [ERROR] [MY-010119] [Server] Aborting
2021-01-05T09:43:42.384313Z 0 [ERROR] [MY-013183] [InnoDB] Assertion failure: trx0sys.cc:628:UT_LIST_GET_LEN(trx_sys->rw_trx_list) == trx_sys->n_prepared_trx + active_recovered_trxs thread 140302677280768
InnoDB: We intentionally generate a memory trap.
InnoDB: Submit a detailed bug report to http://bugs.mysql.com.
InnoDB: If you get repeated assertion failures or crashes, even
InnoDB: immediately after the mysqld startup, there may be
InnoDB: corruption in the InnoDB tablespace. Please refer to
InnoDB: http://dev.mysql.com/doc/refman/8.0/en/forcing-innodb-recovery.html
InnoDB: about forcing recovery.

```

Anyone has an idea, what I could try?

Thanks Michael

# Answer
I actually found the solution here: https://stackoverflow.com/a/64150016/1526406

Maybe this helps others as well.
> 1 votes

---
Tags: docker, mysql
---


title: Nexus vs. Artifactory

text:
# Question
Title: Nexus vs. Artifactory
I was wondering what is the recommendation for a business that needs to store binaries for distribution as well as for dependencies to be used by our projects, with projects in different languages/technologies (.NET, Javascript/Java, C/C++, TAL).

Thank you, any info is appreciated!!

# Answer
Am using both right now.

Nexus will support more repo types with the free version than Artifactory

but

Artifactory will have more repos support in the paid tier

Nexus now support Conda natively (since a few weeks ago if memory serves)

Artifactory will be quite pricey, especially if you plan on having tests and staging instances to test out your config and/or custom plugins as you will have to shell for at least a Pro instance (3K+USD). Nexus will allow you to test most of these with the free version.

JFrog has exemplary support but a bit pushy with their sales. They will have help around though to get you started should you need it.

I have not tried Nexus support or sales force so I cant comment (the free version was plenty enough for our needs).

I found the plugin framework to be more usable with Artifactory though it felt a bit limited. Nexus seems more powerfull but it can be difficult to upgrade/remove plugins from a working instance. On that front I much preferred Artifactory.

Overall we did go with Artifactory, personally I find them to be pretty much equivalent. It will depend a bit on the actual technology you need supported (pypi, nuget, maven etc).
> 10 votes

# Answer
I have used both in enterprise settings a fair bit, but I had never really thought this through until reading the question. Artifactory seems much more complete/impressive to me, but I have used it more recently than Neuxs, so I was worried that I might be biased.

I just spent ~30 minutes reading online. Virtually every comparison or article is either totally biased (literally JFROG or Sonatype supported), or is just lacking in detail.

I eventually did find this though, which is fairly in line with my initial thoughts: https://www.praqma.com/stories/artifactory-nexus-proget/:

* Artifactory supports far more repository types.
* Atifactory has a far better REST API (and has often been ahead on feature development, though it seems like Nexus does catch up over time).
* Nexus is a little more extensible.
* Artifactory costs significantly more.

So... both are good. If you aren't amazingly cost conscious and want the best overall tool, probably choose artifactory. If you have specific needs and Nexus covers your required repository types, it might be worth using it to save some money as it is a solid product in the end.
> 9 votes

# Answer
To add more info to John's answer above: the author of that comparison article updated it at https://www.eficode.com/blog/artifactory-nexus-proget

From my opinion, I left jFrog and went with Nexus because Nexus free version has all my needs (repo type: Maven, yum, pypi and Docker; feature: proxy repo, private repo, group repo; authentication: LDAP/Active directory). Since I am neither using CI/CI feature nor opening my repo to the internet, I couldn't (and shouldn't) give any comments on that point.
> 3 votes

---
Tags: artifactory, nexus
---