How to keep configuration files automatically during apt-get upgrade or install? When performing and apt-get update; apt-get upgrade -y on a server I encountered the message:

Setting up sudo (1.8.16-0ubuntu1.5) ...

Configuration file '/etc/sudoers'
==> Modified (by you or by a script) since installation.
==> Package distributor has shipped an updated version.
What would you like to do about it ?  Your options are:
    Y or I  : install the package maintainer's version
    N or O  : keep your currently-installed version
      D     : show the differences between the versions
      Z     : start a shell to examine the situation
The default action is to keep your current version.
*** sudoers (Y/I/N/O/D/Z) [default=N] ?
Setting up ubuntu-minimal (1.361.1) ...

I know that debconf can be used to configure packages, like MySQL, to answer questions to prompts.

Which Linux Program/Module/Function/etc should I use to prepare an answer to this prompt?

I would really like to know a solution that be performed via Ansilbe if one exists. In addition to a BASH script.

Please note: ALL my distributions are done via IaC and thus automation is critical.

There are options you can pass through apt-get to dpkg that will handle the config choices. We usually do something like:

apt-get install -y --no_install_recommends -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold' <package_name>

When using ansible you can do:

  apt:
    pkg: "{{ item }}"
    only_upgrade: yes
    install_recommends: no
    force: yes
    dpkg_options: 'force-confdef,force-confold'
    state: latest
  with_items:
    - <package_name>

For further details on the ansible apt module options look here


How to move a containerized application to a different host? We have a forum application made of two containers: a container for the database, and another one for the bulletin board application itself. Both containers are running on the same host for quite some time now. That application does not follow the "microservice" architecture since the database files are stored in the writable layer of the database container. And the configuration settings of the forum were directly set up in the writable layer of the bulletin board application.

We would like to migrate that forum to a different host since the current server has reached end-of-life. We see two ways of doing that:

using docker commit to make an image of both containers, then uploading those images to a repository and pulling them back from the new host.
using docker export to create archives of the container filesystems, and importing them on the new host.

What are the pro and cons of both approaches for ad-hoc container migration? Is there a better-suited solution for our specific needs?

From what I understand of https://stackoverflow.com/questions/28734086/how-to-move-docker-containers-between-different-hosts, docker export will only save the container filesystem. But no metadata such as the default command, leading to that error when you try to run the imported archive:

sh# IMAGE=$(docker import phpbb.tar)
sh# docker run "${IMAGE}"
docker: Error response from daemon: No command specified.

Given my need, it is sufficient to docker commit the container to a new image, then docker save the image, and finally docker load and docker run it on the new host:

old# docker commit CONTAINER name:tag
old# docker save name:tag |gzip > archive.tar.gz
old# scp archive.tar.gz root@new:.

new# docker load < archive.tar.gz
new# docker run name:latest

It is important to save the image by repository name:tag and not by id to preserve the tag in the archive.


Issue connecting to ECR using Spinnaker on Kubernetes I installed Spinnaker onto a Kubernetes cluster via Helm. I have tried to add the ECR registry as per the docs and so far not working. I found that the aws cli is missing even though in issue 2394 it was adding into the Dockerfile, looks like as of master it is included still. Wondering what helm used that was so wrong to not have it?

Am I missing something?

Update for anyone else who runs into this issue, when Spinnaker is installed using helm it's using an older version of the Halyard container which doesn't have the AWS CLI tool. This seems to be hard to resolve as just updating the values file for helm to the latest version doesn't seem to work and I didn't dig much into the specifics as didn't want to go down that rabbit hole.


Include pre- and post_tasks transparently for all Ansible roles I am looking for a way to execute some actions before and after each role has run.
pre_tasks and post_tasks look like a good candidate, but I have found no way to include them transparently for all defined roles/playbooks. I don't want to add these manually to all playbooks since this seems like a maintenance nightmare.
Another angle to solve this might be to abuse the fact that Ansible logs in via ssh. However I am not aware of any identifying properties of an Ansible login as opposed to a regular user login.
My specific issue is:
I want to trigger etckeeper before and after each execution of a role.
If you have any other "out-of-the-box" ideas to solve this, I will be grateful to hear them.

Not tested this, but is include_role any help? so instead of a playbook like this,
 ---
 - name: Example
   hosts: all
   roles:
    - first_role
    - second_role
    - third_role

maybe this,
 ---
 - name: Example
   hosts: all
   tasks:
    - etckeeper_task
    - include_role:
        name: first_role
    - etckeeper_task
    - include_role:
        name: second_role
    - etckeeper_task
    - include_role:
        name: third_role
    - etckeeper_task

alternatively (also untested) you could build a role, let's call it wrap_role with tasks/main.yml containing,
---
# Replace this task with your actual before-role etckeeper task,
- name: etckeeper pre-actions
  meta: noop

- include_role:
  name: {{role_name}}

# Replace this task with your actual after-role etckeeper task,
- name: etckeeper post-actions
  meta: noop

Now your top-level playbook can be something like,
 ---
 - name: Example
   hosts: all
   roles:
     - { role: wrap_role, role_name: first_role }
     - { role: wrap_role, role_name: second_role }
     - { role: wrap_role, role_name: third_role }

not ideal based on your question, but at least it leaves the roles untouched, even if you have to alter top-level playbooks. If I get the time I'll test the above suggestions and update this answer accordingly.


How to prevent failure from introduced changes? The DevOps Report by Puppet Labs states that "devopsy" companies have 3x times lower failure rate. While other companies must have a fairly regular rate of failures from deployments to production.

What are the companies who have very low failure rates do differently?
How can other companies mimic such decrease in failures of changes in their production (and other) environments?

This is pretty deep in to "opinion based" but here goes:

While most definitions of "DevOps" are independent of specific tools and techniques, it is very often combined with things like test automation (e.g. Jenkins, Travis-CI) and deployment automation (e.g. Chef, Capistrano, Kubernetes). Those two together act as a forcing function to push up quality levels of software by making it both easier to use tests to ensure things don't break and making it easier to fix breakages when they do occur.

That said, I really doubt that number captures the full story. Like so many things, "software quality" is easy to talk about but difficult to define.


What options are available to report the build status of Jenkins Multi Pipeline's first branch build on k8s to bitbucket-cloud? Background

The Bitbucket Status Notifier plugin has been configured. The status was reported, but since more and more jobs have been moved to Jenkins-on-steroids that is running on k8s, buildStats are not reported if a branch is built for the first time.

Aim

The aim is to report the build status to bitbucket-cloud by jenkins multi-branch when a branch is built for the first time.

Attempts to solve the issue

This related issue was found and a comment was added on Jenkins' Jira.

As a workaround, this suggestion was tried, but it caused a couple of issues and it is not a permanent solution.

def call(buildId, jobName) {
    if ("${buildId}" == "1") {
        build job: "${jobName}", wait: false
        currentBuild.result = 'ABORTED'
        error("Skipping build ${buildId} as it doesn't play nice with bitbucket notifications")
    }
}

Questions

The question is twofold.

First, what other options are available to report build statuses from jenkins-on-steroids to bitbucket-cloud that also work if a build is run for the first time in a branch (BUILD_ID==1) if the multi-branch plugin is used?
Second, if the first question cannot be answered, what steps could be taken to solve the bug?

As I was not able to tackle the bug in the Java code and the bug was already reported in 2017 I decided to write this plugin. This binary is able to send a build status even when a branch is built for the first time.


What is "Infrastructure as Code"? The phrase "Infrastructure as Code" has been mentioned several times in the last two weeks in different contexts.  What does it actually mean in a practical sense to have Infrastructure as Code?

TL;DR: Infrastructure as Code is a way to automate and backup your environment. In ideal case, after a disaster, you could restore your Infrastructure fully and automatically by Provisioning new resources, Restoring Configuration from Code Repository and Recovering Data from Backup.

Overview

Infrastructure as Code relies on three main concepts:

Automation of Configuration Management, called Continuous Configuration Automation a field pioneered by prof. Mark Burgess
Code Repository for changes to Infrastructure, where changes are first committed, documented, reviewed, tested and then deployed through automation.
Managed Infrastructure Provisioning. Infrastructure as a Service (IaaS). Either through Cloud Computing, Private or Managed Cloud or Managed Datacenter Services

Automation

Configuration Management is in its 3rd generation of tools. Building on CFEngine a new set of tools for Automated Configuration Management is being widely deployed now. The most popular in alphabetical order are Ansible, CFEngine, Chef, Puppet, PowerShell DSC and SaltStack. Each will have a Language to describe state of your infrastructure, Code Modules to apply those changes and provide ability to extend the tools, some Agent to execute those on the servers and a Central Repository of information.

They will generally operate in push or pull mode, either connecting to servers from a central location(s) and executing changes remotely or running on each server and pulling information about state from central location and that either in client/server model or in a distributed way.

The important concept is for the system administrator or site reliability engineer to not make changes directly to the infrastructure, but let the automation do changes. Anything done manually by a human should be considered either perishable, being soon corrected back by automation or in stricter form violating the integrity of the infrastructure and triggering destruction and rebuild of the affected components.

Code Repository

Code Repository, ideally separate from Repository holding Software, would be used to manage all changes to the Infrastructure and related Automation. It should hold Configuration files and templates, Playbooks (Cookbooks) describing process of changes to be reviewed, Code extending the CM automation tools, Provisioning configurations, Infrastructure Tests and Alerts, Staging/Deployment Tests, Documentation, Manual (not yet automated) Process Descriptions.

The important concept is to institute peer reviews for changes, to have record of all changes and ability to automatically revert to previous state in case of unpredictable and/or untested issues, ability to deploy to staging environment and test configuration changes and ability to automatically deploy changes without variation caused by human error.

Managed Infrastructure

Managing Physical Infrastructure is a real world task that goes beyond software and requires very different set of skills. By being able to abstract this layer through Cloud Computing or a Managed Datacenter, you have your team focus on the part of managing Infrastructure that adds business value.

While Cloud Computing offers a way to start and scale quickly at a later stage companies often realize some benefits and even significant savings in moving parts of the Infrastructure in their own data centers for a hybrid model. Owning or renting the hardware does not mean that you also have to employ the people who handle it. At this scale you need data centers geographically distributed around the world and having people with all the required skills in all places would be very expensive. Flying them around the world adds high latency to any changes and additional level of operational inefficiencies, which is another reason for outsourcing the datacenter management.

The important takeaway is that Managed Physical Infrastructure is often forgotten or overlooked concept, but just as important. Even if you've got everything automated, all configuration stored in a backed up code repository, unless you have a way to quickly provision, you have a huge bottleneck, which could easily erase all the benefits you've gained by the other two steps.


How to calculate server capacity? I am trying to answer a question:
Do we need more worker machines to handle current load?
We have a variable number of jobs coming in and each job takes different time. Here is a snapshot of our system for a period 12 hours.

But the number of jobs in system changes based on day and time.
How can I calculate throughput of our system and build monitoring around max load that our system can handle?

(N.B. this answer is, in the spirit of the question, high-level and not very concrete...)

  How can I calculate throughput of our system

If by "calculate" you mean to take some data points, dry run some formulas and get a pretty close approximation to your throughput - that is pretty much impossible, unless you have a lot more information - which may also include pretty random parts, hence quite hard to do theoretically.

If you mean "measure", then it could be as simple as checking your logfiles and counting lines per time unit.

  and build monitoring around max load that our system can handle?

Unless you're NASA, that's probably a case for trial and error. Run your system(s) and see how much troughput you get. Increase worker nodes. See what happens.

If you already know the behaviour of your overal system - i.e., whether it scales linearly, whether there are bottlenecks like databases, lock contention and such, then you can take shortcuts or good guesses.

That's one of the reasons for doing the container-based scaling we do these days - you can throw a few more workers at it relatively easily.

How you actually (technically) do that depends on what platform you are using. AWS, Kubernetes/OpenShift etc. come with techniques or settings do do it automatically for you. I assume those work mainly with the metric of "free workers" - trying to get the "free:busy worker" ratio into some target corridor so that every new request has a very high likelihood to hit a free worker, at any time, thus getting (theoretical) constant time for each request.


Regarding Use On Docker I have some questions regarding docker.

In docker image template, there is template that define for Ubuntu.

1) May I know is it possible to build and run this Ubuntu docker image on Redhat server?

2) Is it possible to use this docker image as environment for development for solution that use debian dependencies packages?

I not sure whether such question can be asked in this forum. if no, please enlighten me to the correct forum to raise such question.

Sure. You can run a Linux-based Docker image on any Linux host.
Yes, it is possible. You can run & develop in a debian-based docker container.


How do I use docker command's "--format" option? I can't seem to find any good documentation on how to use the docker command's "--format" option in real life. I know how to use Go templates. But specific to docker, how do I know what placeholders are available to use?

I tried docker inspect on a container and I see JSON output, but I can't use the names from that as Go template placeholders. I did find out that the placeholders are case-sensitive, which seems unfortunate. The default output isn't much help either, since (I assume) it isn't showing me everything I might use, the columns that are there are all uppercase, and they sometimes have spaces in them. docker container ls, for example, has a column called "CONTAINER ID". No combination of underscores, quoting schemes, or so on will make that name work. I figured out that it's "{{.ID}}".

How am I supposed to be using "--format"? How do I discover placeholders for any given docker object?

I take the risk of being downvoted here, but I find Go templates a nightmare to use beyond the most basic use cases. Don't take me wrong: they are extremely powerful as you can guess it by reading the docs, but I find the syntax unfriendly, and for the most complex cases, I prefer parsing the JSON output with jq. Anyway:

Formatting expect commands

sho$ CID=$(sudo docker run --rm -d busybox sleep 3000)
sh$ sudo docker inspect $CID
[
    {
        "Id": "0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967",
        "Created": "2019-02-05T16:41:40.040349047Z",
        "Path": "sleep",
        "Args": [
            "3000"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 26467,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2019-02-05T16:41:40.659056612Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:3a093384ac306cbac30b67f1585e12b30ab1a899374dabc3170b9bca246f1444",
        "ResolvConfPath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/hostname",
        "HostsPath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/hosts",
        "LogPath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967-json.log",
        "Name": "/vibrant_shaw",
        "RestartCount": 0,
        "Driver": "aufs",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "docker-default",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
           "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": true,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "shareable",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DiskQuota": 0,
            "KernelMemory": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": 0,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/asound",
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": null,
            "Name": "aufs"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "0470a3549d2f",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "sleep",
                "3000"
            ],
            "Image": "busybox",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {}
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "654da638965d9bb26e394ba61036ea713bdccb6304eb09bee86f3c0611a26ca5",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/654da638965d",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "c69ef9cb870a3c477105c7bc19e370683886e4e3c62fac8444d3e1e097551250",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.3",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:03",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "5ec8728b05efd5ce6bfde5cbe6e42f247348345e0fdfb305fda76566327fc151",
                    "EndpointID": "c69ef9cb870a3c477105c7bc19e370683886e4e3c62fac8444d3e1e097551250",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.3",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:03",
                    "DriverOpts": null
                }
            }
        }
    }
]

Returning scalar properties

You can query any scalar attribute by its name, prefixed by a dot:

sh$ sudo docker inspect $CID --format '{{.Id}}
0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967
sh$ sudo docker inspect $CID --format '{{.Name}} {{.Driver}}'
/vibrant_shaw aufs

# jq notation
sh$ sudo docker inspect $CID | jq '.[].Id'
"0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967"

sh$ sudo docker inspect $CID | jq '.[]|(.Name,.Driver)'
"/vibrant_shaw"
"aufs"

You can also query nested fields:

sh$ sudo docker inspect $CID --format '{{.State.Running}}'
true

# jq notation
sudo docker inspect $CID | jq '.[].State.Running'
true

Returning entire objects and arrays

But it does not work as expected for nested structures:

sh$ sudo docker inspect $CID --format '{{.State}}'
{running true false false false false 26467 0  2019-02-05T16:41:40.659056612Z 0001-01-01T00:00:00Z <nil>}

You end up having the data, but without the field names, it is pretty useless--unless you are assuming some predefined field order (something that is probably not safe).

When accessing entire objects, there are chances you want an explicit formatter:

sh$ sudo docker inspect $CID --format '{{json .State}}'
{"Status":"running","Running":true,"Paused":false,"Restarting":false,"OOMKilled":false,"Dead":false,"Pid":26467,"ExitCode":0,"Error":"","StartedAt":"2019-02-05T16:41:40.659056612Z","FinishedAt":"0001-01-01T00:00:00Z"}

# jq notation
sh$ sudo docker inspect $CID | jq '.[].State'
{
  "Status": "running",
  "Running": true,
  "Paused": false,
  "Restarting": false,
  "OOMKilled": false,
  "Dead": false,
  "Pid": 26467,
  "ExitCode": 0,
  "Error": "",
  "StartedAt": "2019-02-05T16:41:40.659056612Z",
  "FinishedAt": "0001-01-01T00:00:00Z"
}

Same thing for arrays:

sh$ sudo docker inspect $CID --format '{{.HostConfig.ReadonlyPaths}}'
[/proc/asound /proc/bus /proc/fs /proc/irq /proc/sys /proc/sysrq-trigger]

sh$ sudo docker inspect $CID --format '{{json .HostConfig.ReadonlyPaths}}'
["/proc/asound","/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"]

sh$ sudo docker inspect $CID --format '{{join .HostConfig.ReadonlyPaths ":"}}'
/proc/asound:/proc/bus:/proc/fs:/proc/irq:/proc/sys:/proc/sysrq-trigger

# jq notation
sh$ sudo docker inspect $CID | jq '.[].HostConfig.ReadonlyPaths'
[
  "/proc/asound",
  "/proc/bus",
  "/proc/fs",
  "/proc/irq",
  "/proc/sys",
  "/proc/sysrq-trigger"
]
sh$ sudo docker inspect $CID | jq '.[].HostConfig.ReadonlyPaths | join(":")'
"/proc/asound:/proc/bus:/proc/fs:/proc/irq:/proc/sys:/proc/sysrq-trigger"

Arrays of objects

More complicated (according to my limited Go Template skills) is accessing fields nested in an array of objects:

# This works as expected
sh$ sudo docker network inspect bridge --format '{{json .IPAM.Config}}'
[{"Subnet":"172.17.0.0/16","Gateway":"172.17.0.1"}]

# But not that
sudo docker network inspect bridge --format '{{.IPAM.Config.Gateway}}'

Template parsing error: template: :1:7: executing "" at <.IPAM.Config.Gateway>: can't evaluate field Gateway in type interface {}

When I want to extract such nested value, I resort on an explicit range loop:

sh$ sudo docker network inspect bridge --format '{{range .IPAM.Config}}{{.Gateway}}{{end}}'
172.17.0.1

# jq notation
sh$ sudo docker network inspect bridge | jq '.[].IPAM.Config[].Gateway'
"172.17.0.1"

sh$ sudo docker network inspect bridge | jq -r '.[].IPAM.Config[].Gateway'
172.17.0.1

Formatting ls commands

With the json formatter, we can obtain (some? all?) the possible selectors you can later use with --format:

sh$ sudo docker network ls --format '{{json .}}'
{"CreatedAt":"2019-01-07 14:28:55.63238018 +0100 CET","Driver":"bridge","ID":"5ec8728b05ef","IPv6":"false","Internal":"false","Labels":"","Name":"bridge","Scope":"local"}
{"CreatedAt":"2019-02-05 15:36:57.701603791 +0100 CET","Driver":"bridge","ID":"45d6f09ca923","IPv6":"false","Internal":"false","Labels":"com.docker.compose.network=default,com.docker.compose.project=compose-demo,com.docker.compose.version=1.23.2","Name":"compose-demo_default","Scope":"local"}
{"CreatedAt":"2019-02-05 17:30:47.98883918 +0100 CET","Driver":"bridge","ID":"aaff418d1c56","IPv6":"false","Internal":"false","Labels":"com.docker.compose.network=net,com.docker.compose.project=compose-demo,com.docker.compose.version=1.23.2","Name":"compose-demo_net","Scope":"local"}
{"CreatedAt":"2018-05-26 10:31:48.149819089 +0200 CEST","Driver":"host","ID":"988954899b53","IPv6":"false","Internal":"false","Labels":"","Name":"host","Scope":"local"}
{"CreatedAt":"2018-05-26 10:31:48.118573602 +0200 CEST","Driver":"null","ID":"ce1680ed377f","IPv6":"false","Internal":"false","Labels":"","Name":"none","Scope":"local"}
{"CreatedAt":"2019-02-05 19:44:21.286955573 +0100 CET","Driver":"bridge","ID":"41c62c023d16","IPv6":"false","Internal":"false","Labels":"com.docker.compose.version=1.23.2,com.docker.compose.network=default,com.docker.compose.project=test","Name":"test_default","Scope":"local"}

Here, you can see docker network ls exposes, among others, the "ID", "Driver" and "Scope" fields. You can use them in your format:

sh$ $ sudo docker network ls --format '{{.ID}}: {{.Driver}} ({{.Scope}})'
5ec8728b05ef: bridge (local)
45d6f09ca923: bridge (local)
aaff418d1c56: bridge (local)
988954899b53: host (local)
ce1680ed377f: null (local)
41c62c023d16: bridge (local)

The best of both worlds

The docker ... ls commands only exports a small subset of the docker object's properties. Depending your needs, you may prefer something along the lines of docker ... inspect $(docker ... ls -q).

For example, docker image ls does not export the image architecture. but you can obtain it with docker image inspect. If you want that information, you could use something like that:

sh$ sudo docker image inspect \
         --format '{{.Id}}: {{.RepoTags}} ({{.Architecture}})' \
         $(sudo docker image ls -q)
sha256:fc37804350a8adea0b41dba0c413a6c967140ca2ed6dfeefdbe88d7868902406: [compose-demo_monitor:latest] (amd64)
sha256:a6f30c0890bca94e3cf5930ad5c3358b06cb38450e92d4ddabeb208ee34383f8: [compose-demo_app:latest] (amd64)
sha256:a79892b33e0bb51598e9311cc1d23ca8d0e3013a5a15fd67d202d22ffd08a6af: [] (amd64)
sha256:394c82635f220db389b8532e316001674965b51679dbc8dff747d5f224e6d568: [] (amd64)
sha256:95f0c755feb65af441c0cb8727bb13b35517977a3bed06e4a3456c95d6a69dd4: [redis:5.0-alpine] (amd64)
sha256:1f6c34f7921c7b50ef4452737399b5cff0eb834fc183d188d82886fd23b7fc34: [node:8] (amd64)
sha256:3a093384ac306cbac30b67f1585e12b30ab1a899374dabc3170b9bca246f1444: [busybox:latest] (amd64)


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.

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.


How to share RDS snapshots across account roles? I'm using an AWS account which has different roles for the different environments we use. For example, we have a Development role for our development environment and a Production role for our production environment.

At any point of time, we switch into or assume as one of the roles to access the services in the particular environment. Neither roles can see nor access each other's services and they function as though they are separate accounts.

The problem now is, there are some application issues with an RDS instance in the production environment. The production database resides in the Production role. My intention is to clone the database in production over to the development environment for debugging reasons. However, since the environments are in different roles, they can't see each other's resources. The snapshots of the databases in one environment is not visible in another.

Since the roles are technically not accounts, I can't use the "Share snapshot" feature too because that would require me to input an account number instead of a role name.

Is it possible for me to allow the use of RDS snapshots across account roles so that I can clone the RDS instances? If so, how can I do it in the AWS console?

To my knowledge there are only Tag based Iam policies available to limit access to resources for certain users or user groups.

Because of this, you should simply be able to tag an RDS snapshot both production and development for you to access it with your development user or group.

There are a large number of security considerations to think through, so don't undermine the security setup. I would therefore expect that only manual tagging is appropriate for this specific use case


Implications of introducing Docker to the development team We always tend to have a moral implications of certain critical decisions taken for development irrespective of the realisation if the decision is critical or not. Say for example switching an entire stack for a team of developers or enforcing them to start using a new frontend framework, etc.

For now, I am trying to understand the implications of introducing docker to the development team. I have the following questions:

Why should a developer care about Docker ? His / Her job is to fulfil the business requirement and that's it. Why should he / she be bothered about the dockerfile or which orchestrator his / her app should be running etc.
When the application is crashed several times due to the issue in the orchestrator (swarm, kube, mesos) or due to poor orchestration of the developer due to lack of knowledge, who is responsible ? The one who sets up the orchestrator (DevOps maybe) or the developer himself ?
What is the role of SRE ? Should an SRE be keeping an eye on the infrastructure 24/7 or he / she should become a part of the dev team, fix development issue related to infrastructure, provide containerisation to the dev team, etc. Basically should he / she become a watch dog for the infrastructure or the one who becomes bridge between devs and devops to tackle infrastructure related issue.
Is it necessary for every developer to learn and understand the concepts of docker and various orchestration platform out there ?
Is docker just a tool for ease of deployment or it holds some value in the development as well (I can't think of one right now) ?

I think docker can become a playground for blame game and I wish to avoid it. I want to understand the roles that needs to be placed in Dev and DevOps teams in order to avoid chaos when the app fails to deliver its SLA.

@Abhay Pai

why not posting this as 5 different questions?

Google for "left shift" in DevOps context.
Consider DevOps team patterns http://web.devopstopologies.com/
"While DevOps raise problems and dispatch them to Dev to solve, the SRE approach is to find problems and solve some of them themselves." https://devops.com/sre-vs-devops-false-distinction/
Depends on your requirements to their profile IMO but in general I think that the question is like "do smb has to learn advanced things which might help a lot..?" no, but.. ;)
Try out Docker as integration testing tool combined with your CI/CD solution.


How to become a CIO? According to this blog, one could become a CIO if one meets the following criteria:

BSc in Computer Science
Proven experience in Project Management
Specialized in an certain area by becoming certified
IT Governance and Risk Management
MBA

Discussion

I wonder whether the above mentioned criteria would be sufficient to become a CIO. I think that soft skills are important as well to be promoted to such a function right? I do not think whether only mastering hard skills would be sufficient to become a CIO.

I really hate this kind of discussion, as if there's a mold that fits a good CTO or CIO.

Let's examine the qualities of a good executive rather:

Practices enabling and empowering engineers and local team leadership
Deflects bureaucracy from external sources
Helps remove organizational blockers to change and improvement
Does not mandate architecture from the top down
Acts as an evangelist for software first solutions
Promotes automation and solid foundations for solving problems rather than implementing patches
Knows how to avoid unrealistic deadlines and demands quality, but not perfection, over quantity of features
Uses data to solve problems and constantly evaluates the integrity of the data gathering
Values iterative development rather than long, cumbersome planning processes
Values education and internal training & advancement over outsourcing

I'll add some more if I can think of them. We need to stop assuming a CTO or CIO is a list of resume qualifiers and start hiring people who really understand the process of building, maintaining, and delivering software from sun rise to sun set.


Is there a way to acquire metadata about an Amazon RDS database instance using only SQL? For example, if I have a SQL Server instance in RDS, and I have only a connection string to connect to the server, is there a sproc or some pre-configured tables I can access via SQL on the instance that would report the instance size string? (db.r5.xlarge)

I don't have a SQL Server on AWS to check, but you could see if it's in xp_msver, or figure it out from ProcessorCount, ProcessorType and PhysicalMemory in that sproc.


Is Docker right for my use case? My company has a system we sell that consists of basically a mini-computer "Smartbox" that is running Ubuntu 12.04. This box runs a Django application plus a number of different upstart processes related to it. Not much else. We have thousands of these boxes out on the field. We manage the package dependencies, process registration, etc. through a deb package with varying degrees of success.

We need a way to efficiently and robustly push updates out to our users out in the field. We also need something that as we upgrade the OS (we are way overdue for a Ubuntu upgrade as you can tell) we can feel relatively secure about our packages "just working".

I don't know much about Docker, but when I first heard about our problem (I'm a new hire), Docker was my first thought. But the more I thought about it I felt like maybe it wasn't, as these boxes are ours we control the OS on it which is a big part of the value proposition of Docker, or so I understand. So if we KNOW our boxes will always be Ubuntu and we basically just have a Django app plus some processes to run, is Docker any better than a deb package?

TL;DR: Docker vs deb packages for a distributed appliance that will always run Ubuntu so platform independence is not that important.

I'm not 100% sure I understand from the question, but it sounds like the Docker solution would be to go from having an (physical?) appliance with an OS and your app installed on it, to having an appliance with an OS and Docker on it, running a single container with your app in it. That doesn't obviate the need to update the OS in the host, and it adds a layer of complexity (and more updates to contend with, as you'll now have to keep Docker and the OS patched) with no readily-apparent benefit as far as the specific areas mentioned in the question are concerned.

However, if you're talking about going from a virtual appliance to a Docker container, that could potentially smooth things out for you, but it also adds Docker as a dependency for your product; you're shutting out anyone who isn't using Docker and doesn't want to add it to their stack just to use your product. You could continue to support those that don't/won't use Docker by continuing to ship the (now "legacy") virtual appliance as before, but now you've just doubled your workload because you have two distributions to support instead of one.


Limits of, or preconditions for of Blue-Green deployment? I find a lot information about the blue green deployment pattern but maybe miss a point. Please help me to understand.

Could it be scenarios where you can't successfully duplicate the information flow?

Examples:

Captcha request from a local API; can you ensure same captcha goes to blue and green?
Randomly generated hardware-based UUID's: blue and green wouldn't get same random number, or?

Or does blue/green mean, that exactly such considerations have to flow as well into the software design?

I must admit that I don't quite get the examples your giving. Sure, random numbers will be different between the two environments.

Blue-green means simply to have two nearly identical production environments with some kind of router/load balancer in front. Clients talk to the load balancer, and the LB routes requests to one of the two environments.

To deploy a new version, you provision all machines/services/etc. in the inactive environment, test to your heart's content, and then do the instant switch (on the router) if you're satisfied.

Actually, I don't see anything that requires any precondition at all about this. Obviously, one precondition is that you are at all able to create a second, fully fledged production environment in the first place; and that there is a technical solution that works as a load balancer in the above sense. That may get very complicated if you have a widely distributed system which you want to switch completely at once. That may just become to complex.

But aside from that, nothing special compared to, for example, running a separate test environment next to your dev/prod environments.


What is a gating continuous integration (CI) system? I often find myself in the position of mentioning gating CI systems and I thought it would be good to have a post I can easily reference explaining what that is. So here goes:

What is a gating CI system and how is it different from the traditional CI systems (i.e. the majority of the CI systems/tools presently out there)?

A traditional CI system is reactive, it detects regressions, but requires human intervention for repairs.

Traditional CI relies on automated quality checks performed on the already integrated code - after changes are committed/merged into the integration branch (typically triggered by those events). The results of these checks indicate if the integration was successful, i.e. if the branch at that point is a good candidate for any subsequent steps towards delivery/deployment or if regressions occurred. Some regressions are considered catastrophic (for example build failures) and must be repaired ASAP as they're effectively blocking development on the branch. Unfortunately in most cases the repairs require human intervention, which can be a significant bottleneck.

By contrast a gating CI system is proactive, it prevents regressions and, with proper orchestration, can be entirely automated.

Gating CI performs the quality checks on candidate changes prior to them being committed/merged into the integration branch. If the checks are successful the changes are committed/merged into the branch, ideally in an automated manner, performed by the CI system itself, without human intervention. If the checks reveal regressions considered catastrophic/blocking the candidates are rejected (i.e. their commit/merge into the branch is prevented). Hence their gating characteristic - they will prevent "bad" changes from even reaching the branch.

A simple example would be a pull request (PR) based integration with one or more automated validations (for example a build and maybe a smoketest) hooked up in the PR processing which must be successful for the PR to be merged. A fairly common practice for many development teams.

Unfortunately rejecting "bad" changes alone is not sufficient to ensure the integration branch maintains a minimum quality level at all times.

It is always possible to have multiple candidates outstanding at the same time. But having multiple quality checks (on different candidates) active at the same time means that at least some of the checks do not take into account the other candidates in flight, leaving room for regressions due to changes interfering with each-other - see a simple example in How can successfully pre-verified changes cause regressions that should have been caught?.

It is for this reason that those using a PR-based system as mentioned above can probably recall that the branch can still see breakages once in a while.

This can be addressed with proper orchestration of the quality checks. The purpose of the orchestration is to completely eliminate the risk of interference between changes by controlling when each check is started/stopped and what candidate change(s) it covers, based on one or more inputs which can include: other candidates submissions/current states, results of other checks, actual commits/merges, availability of resources necessary for the checks, etc.

A very basic orchestration algorithm for the PR-based CI system mentioned above would be, for example, to only allow the merge if the tip of the branch at merge time is the same as it was when the automated PR validation started (i.e. no other change was committed/merged in the mean time). Effectively serializing PR processing, it could work great for small teams, but probably will not be able to keep up in a large scale project.

The orchestration algorithm (or lack thereof) is ultimately what dictates a gated CI system's scalability, performance ability to maintain the integration branch' quality level. An algorithm 100% efficient in preventing blocking regressions would no longer require human intervention for normal operation, a gated CI system using such algorithm can typically be entirely automated - a pipeline accepting change candidates at one end, filtering out regression-causing changes on a mid tap and outputting guaranteed stable branch tags at the other end.

It's probably worth mentioning that using a traditional or a gating CI only covers the integration stage and brings no fundamental restrictions on the CD (delivery/deployment) portion of a CI/CD pipeline - any traditional CI/CD tool can be plugged in behind a gated CI to perform additional (but non-gating) CI verifications (if needed) and the CD steps. Similarly any release strategy (see Should I use release branch to push my changes?) can be used with either of them.

Note: for distributed version control systems like git the context of the answer is the master/origin/central repository, not the local replicas.


Cannot configure node group in new EKS cluster due to no Node IAM role found I've created a new EKS cluster, and am trying to add a new node group to it.

I'm stuck on selecting a Node IAM Role from the dropdown.

I followed the link, and created all options for roles I could see fit, still none appear in the dropdown.

Note: currently I don't really care about restricting access, I'm only trying to run some POC against EKS with a test account.

This is actually pretty well described in the docs.

Before you create worker nodes, you must create an IAM role with the
following IAM policies:
AmazonEKSWorkerNodePolicy
AmazonEKS_CNI_Policy
AmazonEC2ContainerRegistryReadOnly

Also you need to make sure that this role could be assumed by EKS.
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}


How to run aws cli with www-data? I can successfully upload a file to my S3 bucket using the AWS cli version 1 with my normal linux user. However, I'm having trouble doing the same with Apache2's www-data.

I have a personal project where I have a web form and after submission, I use shell_exec to run some shell commands. I've tried the following command but it does not seem to work and I'm not getting any errors so debugging is a bit hard:

shell_exec('/home/pi/./local/bin/aws s3 cp /path/to/test.txt s3://s3-bucket-name/');

If it makes any difference, I'm doing this on a Raspberry Pi. I'm suspecting it has something to do with the fact that AWS CLI has been installed under the normal user I use and www-data cannot access it.

Any suggestions?

Edit: One solution I found was to use allow www-data to run commands with another user without prompting for password. So this worked then:

shell_exec('sudo -u pi /home/pi/.local/bin/aws s3 cp /path/to/test.txt s3://s3-bucket-name/');

I'd say you can:

Using pip, install aws-cli for the www-data user specifically.
Example:

pip install awscli --user
Copying aws binary to some folder (for example awsonlybin) where it is the only command there and then adding the path of this folder to the www-data user's PATH. Example:

export PATH=$PATH:/usr/local/awsonlybin

In addition to that you should also do one of the following options:

Create an IAM user and access and secret keys and attach a relevant IAM policy to that user and then configure awscli to use that access key and configure them under the www-data user.
Create an IAM role and attach a relevant policy to that role and attach the role to that instance.


Schedule Jenkins Job with Active choice Reactive parameters and Reactive reference parameters I have created a Jenkins job which have Choice Parameters, Active Choice Parameters, Active choice reactive params and Reactive reference params.
This job needs to be scheduled with parameters.
As the active choice params and reactive choice params are dynamically executed with groovy scripts.
How can I pass these parameters to schedule a job with cron present in Jenkins.
I'm using Parameterized Scheduler plugin for scheduling.
EDIT
Say I have a job which have
1 Active choice parameter PARAM_A
1 Active choice reactive parameter PARAM_B
2 active choice reactive reference parameters PARAM_C and PARAM_D.
I tried by hard coding active choice parameter in the cron like below
15 7 * * * % PARAM_A=somestring

But with the provided active choice value, the job is getting failed.
Because the reactive reference parameters which were written in groovy script are not getting executed when i triggered with scheduler in jenkins.
In a jenkins schedule job using parameterized-scheduler, where if we give input

Although I haven't tried using the Parameterized Scheduler in particular, I don't think you will be able to use this plugin to trigger a build with Active Choice parameters - most plugins don't support passing Active Choice parameters to builds.  There is currently an open bug report on this issue.

As for a workaround - I have been able to successfully trigger builds with Active Choice parameters using the HTTP REST API /build endpoint (a bit counterintuitively, NOT /buildWithParameters).  So for instance you could have a second job that runs on a schedule and does nothing but hit the API endpoint to trigger the job and pass parameters, or you could have a plain Unix cronjob that hits the endpoint, or something else along those lines.


Trunk Based Development - release branch testing We are currently using Git flow branching strategy and looking to go to a trunk based strategy - although we are quite a ways away from getting there I am trying to get all my ducks in a row, prioritize and eventually get there. I feel that its not practical to go from having multiple branches with merges etc directly to just having one branch with automated CD from that branch. I want to do this in steps while we work up our automated tests, code coverage etc. So, until then we will have to batch up our features for releases.

I was looking at something similar to this:

I could have a release branch where I would cherry pick the commits and batch them up. Obviously, we would have automated tests etc. running on the master branch. But, what about the release branches? What sort of tests should run on the release branch and at what frequency? Running all tests on both branches seems like an overkill. Since the commits are already tested in master branch, should we run only regression tests on release branch to identify any potential issues? Maybe also a CI build on the release branch that at least makes sure that the release branch is in a buildable state after a cherry-pick commit is completed?

I would appreciate your thoughts about this. Thanks for your time...VK

There are different strategies and, depending on your specific problem domain, you need to decide what makes sense for you.

For server side applications, especially micro services, you typically don't need release branches. You can work with pull requests, but once they hit master, it is common to deploy (from master) and never look back. Managing release branches comes with a cost and for server applications, there is not much benefit from my experience.

For other type of applications, release branches do make a lot of sense. In my current job, I'm working partly on Browser extensions where releases need to be planned. In contrast to the server side, pushing a broken extension release is something that you want to avoid at all costs, especially as rolling back is not possible. That is why we have code freezes (every two weeks or so).

At code freeze, we create a release branch from the current master. Trunk based development continues as before, but all new changes will not make it in the upcoming release. Instead there is a testing and stabilization window, where only bug fixes will be accept on the release branch. When a bug is found, it will be fixed on master first, and only then cherry-picked to the release branch. Once bugs are fixed, the release goes out and the whole process repeats.

Stable cycles of around 2-3 weeks tend to work well. Shorter is also good, but longer cycles can be problematic, as it encourages people to squeeze as much as possible in the upcoming release. Otherwise, if you miss it, you might have to wait for months. I would strong recommend to favor multiple small and predicable release cycles over big and unpredictable ones.

Our CI system runs for all development relevant branches (i.e., on master and all pull requests). To be best of my knowledge, we do not run tests for the release branches. Normally, a well-tested bug fix from master does not create problems on the release branch. However, I see no fundamental reason not to run tests on the release branch, too.

If you set it up from scratch, I would include release branches. However, from my personal experience, master (and pull requests) alone should give you most of the benefits already. Running tests on master helps to enforce that development does not break existing tests, or introduces warnings or other coding style violations.

In our setup, the CI system (Jenkins) runs after each commit. If there are no changes, it will not be triggered. However, in my previous job, we had costly integration tests, which were executed once a day but only on master, while unit tests ran after each commit. Again, that depends on your specific project.


How to automate installation of Windows installer on Appveyor CI? I've the installer in EXE format (mt5setup.exe) and I'd like to download it and automate the installation process on Appveyor CI. On Linux I would normally use xdotool.

Since this installer doesn't have any silent flags to use, how can I automate the installation process headlessly?

The installation of Windows application can be automated using AutoHotkey (AHK), similar as Winetricks does this for all common apps which support.

Here is example of AHK script which aims to install mentioned application:

Run, mt5setup.exe
WinWait, MetaTrader 5 Setup
ControlClick, Button1
Sleep 100
ControlClick, Button3
WinWait, MetaTrader 5 Setup, Installation successfully completed
ControlClick, Button4
Process, Wait, terminal.exe
Process, Close, terminal.exe

To integrate it with CI, AHK needs to be installed by downloading ZIP file, uncompressing it and passing the above AHK script. Suggested appveyor.yml file:

install:
- curl -sLo https://www.metatrader5.com/en/download
- curl -sLo http://www.autohotkey.com/download/AutoHotkey104805.zip
- unzip *.zip
before_test:
- dir
test_script:
- AutoHotkey.exe install.ahk
build: off
platform: x86

where install.ahk is the file to contain above AHK script which can be dynamically generated or downloaded from some repository.


In Docker, is there any advantage or disadvantage in using 'CMD cmd1 && cmd2' versus 'CMD cmd1 && exec cmd2'? In Docker, when chaining several startup commands (CMD) in shell form, is there any advantage in using the shell's exec feature to replace it with the last command of the chain instead of just running it as a child process of the startup shell?

Here is an example:

CMD npm install && npm start

versus:

CMD npm install && exec npm start

I think in the latter example, the npm start command will replace the shell as the PID 1 process. But I do not fully understand which advantages or disadvantages this would have.

When you replace pid 1 with a new executable, rather than forking it as a child pid, you reduce overhead (slightly). More importantly, you get signals directly to your application instead of having them passed to the shell running as pid 1. By default, the shell running in pid 1 will ignore the SIGTERM sent by docker to gracefully stop your application. After 10 seconds of no response, docker will send a SIGKILL which will immediately terminate the shell and child processes without giving them a chance to drain network connections or finish writing to any files. This can result in things like database corruption depending on what the app is inside the container.

Even when this doesn't apply to your application (if there's no state), you can save up to 10 seconds every time you stop the container by switching to the exec syntax (assuming your application exits when it receives a SIGTERM). Therefore the exec syntax is the one I prefer for both data safety and speed.


how to send a password to MySQL with docker? Just getting started, want to run the downloaded version of mysql:
root:~#
root:~# docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
basex/basexhttp      latest              3339bf6bc898        4 days ago          226MB
twilio/twilio-java   latest              611ab7ece1cf        12 days ago         993MB
mysql                latest              0d64f46acfd1        3 weeks ago         544MB
jetty                latest              5f997007f18d        4 weeks ago         522MB
hello-world          latest              bf756fb1ae65        8 months ago        13.3kB
root:~#
root:~# docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

root:~#
root:~# docker run mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password
2020-09-01 06:53:03+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.21-1debian10 started.
2020-09-01 06:53:03+00:00 [ERROR] [Entrypoint]: mysqld failed while attempting to check config
    command was: mysqld -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password --verbose --help
    Enter password: mysqld: Can not perform keyring migration : Invalid --keyring-migration-source option.
2020-09-01T06:53:03.366882Z 0 [ERROR] [MY-011084] [Server] Keyring migration failed.
2020-09-01T06:53:03.368621Z 0 [ERROR] [MY-010119] [Server] Aborting
root:~#

Without re-downloading the image.

As the documentation clearly states docker run command should be invoked as follows:
docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]

so when you run
docker run mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password

Docker assumes -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password is a command you want to run inside the container, not a list of options for docker run command.
The proper docker run invocation with the parameters you specified is:
docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password mysql


PHP-FPM with Nginx in different containers (share init.d response between) I have a Docker setup for my project with PHP-FPM, Nginx and many other services required by the application, but inside the PHP app I've to check the init.d/nginx configtest for new dynamic Vhosts (which are shared by volumes) generated for a tenancy based service.

The main thing its that I dont want to make a single container with PHP-FPM and Nginx for scalability reasons.

My idea is to use any Linux package for watch any change on a folder (Vhosts folder in my case) and test and then reload the service.

Any suggestion?

Note: I've RabbitMQ in one container which is used by the PHP application but now I need to connect it with the Nginx-based container (I don't know if there's a CLI or linux native client for this).

Here is nginx and php done as an s2i builder image. You can basically have plain old php in a git repo and run s2i to make a runtime image that runs it with nginx and php. You simply docker build that dockerfile and pass the resultant image as the builder image to s2i along with your source code.

You will notice I have archived that project. That is because redhat have security patched image for php at https://access.redhat.com/containers/#/registry.access.redhat.com/rhscl/php-72-rhel7 they happen to use apache httpd but since I don’t see that I use tell s2i “make a runtime container for my php code in git” and it just works and I get frequent security patches it’s way easier than messing around with my own dockerfile to do security patches.


How to run two react project through nginx on same machine I am using the react for the frontend. I have a code which runs on port 3000.
Under that admin panel code is also there which I need to move to out of the project and run separately on different port let's say 3001.
So on nginx config file
I have created the location for both the project like this
Under server block
location /admin/ {
            proxy_pass http://127.0.0.1:3001;

        }

location / {
            proxy_pass http://127.0.0.1:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }

By this way  when I open the localhost, my code is running properly.
Now if I type localhost/admin/ then it return 404.
For the nginx route confirmation, I have change the title of admin panel index.html so that it is clearly mentioned that whether my routes of nginx are working or not
So after this when I hit the admin url then through inspect element I saw that title are changed but due to routes issue of main server it return 404.
I also wrote the alert hello world under index.html file of admin panel code so that it alert will generate when admin code is rendered.
After this when I Open the localhost/admin then alert will generate and then when I close the alert modal then page redirected to 404. I don't know why main code is overriding here.
What it seems like it pick the both the route at same time. So after hit the admin url instant index.html page is load and then routes load from 3000 port project instead of 3001. On 3000 port project there is no such route like this hence it return 404.
Anyone have any idea how to tackle this type of Issues.
Both project are running fine if run individually through the port number like localhost:3000/ or localhost:3001/admin/
Please suggest me that whether there is an issue from nginx side or from react side.
Any help or suggestion is really appreciated. Thanks in advance.

Try to stop the react applications and see if the message changes - and tbh i think you should see 502 if nginx was not routing properly


Configuring Zookeeper from Ansible I'm trying to configure a Zookeeper Cluster with Ansible. As you might know Zookeeper has two important config files.

zookeeper/conf/zoo.cfg

I create this file on each cluster member using this jinja2 template:

{% for host in groups['zookeeper'] %}
server.{{ loop.index }}={{ host }}:2888:3888
{% endfor %}

The result will look like this:

server.1=processing1.srv.mycompany
server.2=processing2.srv.mycompany
server.3=indexing1.srv.mycompany
server.4=indexing2.srv.mycompany
server.5=quorumandmonitoring.srv.mycompany

data/myid

Accordind to the docs this file needs to contain an unique id for each member of the cluster.
To keep everything in sync I would like to have the value after server. in the myid of each host. This means:

myid=1 on processing1
myid=2 on processing2
myid=3 on indexing1
myid=4 on indexing2
myid=5 on quorumandmonitoring

And this is where my problem starts: how can I do this in a clever way? An ideal solution would be to use something like the for host in groups loop. I would rather not add host_vars to my inventory.

In lack of a better idea I chose this rather long approach:

myid.j2

{% for host in groups['zookeeper'] %}
{% if host == inventory_hostname %}
{{ loop.index }}
{% endif %}
{% endfor %}

The idea is to iterate over all hosts and check if the current host being processed matches the host in the list of hosts. If it matches I write the iteration counter to the file.

When I ssh into the boxes I can see their myid files were created according to my need:

[root@quorumandmonitoring data]# cat myid
5


How to use terraform import with module Terraform v0.11.11
We have a quite big AWS setup created with Terraform. Different regions are applied separately, and that is why we have most of the things in modules which are imported like this:
module "assets" {
  source       = "../modules/aws-assets"
  environment  = "${var.environment}"
  upload_users = "${var.upload_users}"
}

We have one s3 bucket created manually, and I try to import it. Terraform import command does not find the configuration file and errors.
Error: resource address "aws_s3_bucket.machine-learning" does not exist in the configuration.

Before importing this resource, please create its configuration in the root module. For example:
resource "aws_s3_bucket" "machine-learning" {
  # (resource arguments)
}

terraform apply/plan do find the configuration and wants to create it which is not what we want?
Thanks for you help!
================================
Edit:
now moved configuration to root and ended up with different error...

The terraform import command uses the "Resource Address" syntax, which is a way to talk about objects in a configuration from outside of that configuration. (This is as opposed to references in the main Terraform language, which are always resolved in the context of a particular module.)

To refer to a resource that is declared in a child module, you can add a module path to the beginning of the address:

terraform import module.assets.aws_s3_bucket.machine-learning BUCKET-NAME


Azure Powershell DSC or Ansible I wanted to find out what are you using for Desired State Configuration on your end. I am thinking to start introducing Azure Powershell DSC or Ansible for DSC of our on-prem environment and cloud environment. Would you have any recommendations? I am turning more towards Ansible but it would be nice to get to know other people opinion.

PowerShell Desired State Configuration:

Pro's

Great support for Microsoft Technologies (IIS, Exchange, SharePoint, etc.)

Con's

OS and PowerShell Version requirements can become prohibitive.
WinRM and the LCM can be flakey requiring fiddling around restarting services to get it working.
Opensource Ecosystem isn't as strong.

Ansible:

Pro's

Huge Open-source ecosystem around Ansible, with many ways of doing one task.
Support for a wide range of technologies, enabling you to use Ansible YAML for vSphere, Azure, AWS, etc.
Easy to hire people with Ansible experience.

Con's

Poor support for the nitty-gritty of Microsoft Products, however, you can use the win_dsc module to call DSC from Ansible.
Ansible is becoming less important with the advent of Cloud, Kubernetes and Terraform.

Personally, I use DSC for my workstation and that's it now.  Previously I used it to bootstrap MongoDB and Redis clusters but eventually switched to Ansible because it meant throwing away the hard to maintain DSC and using open-source Ansible modules from Galaxy.


How to retrigger a Jenkins build after failure using declarative syntax? I am using declarative pipeline syntax. I want to re trigger my build for 3 times if it fails. I want to add this step in my pipeline may be in post step:
Something like below:

post {
    failure{
        retrigger //try for 3 times atleast
    }
}

The other answer is incorrect.  There is indeed a builtin to retry arbitrary sections of your job called retry.

If you want to retry the whole job three times, you can wrap your entire job in a retry block:

retry(count: 3) {
  // your job definition here
}

However, if it's safe to do so, I would recommend wrapping individual steps or stages instead:

stage('my first stage') {
  retry(count: 3) {
    sh('some-command')
    sh('some-other-command')
  }
}


Is openstack public cloud like Google drive, aws where we can store data?? Or something else? I am using cloudberry to backup data. There are lot of options where we can store data like Google drive , aws and also openstack. I got confused because I was thinking openstack as operating system which we can install in our premise..please someone explain..what's openstack actually??

Openstack is something you might install to setup an self-service IaaS platform that manages VMs, storage and network. Whereas the top three cloud providers have written their own proprietary IaaS platforms a small cloud provider, or a large company, cannot feasibly code there own cloud-like management software, so they might setup their “private cloud” using openstack (or, say, a big vendors distribution of it) so that many internal projects can use it as self-service IaaS. To quote Wikipedia with some expansion by myself:

  OpenStack is a free and open-source software platform for cloud
  computing, mostly deployed as infrastructure-as-a-service (IaaS),
  whereby virtual servers and other resources are made available to [internal or external]
  customers. The software platform consists of interrelated
  components that control diverse, multi-vendor hardware pools of
  processing, storage, and networking resources throughout a data
  center. Users either manage it through a web-based dashboard, through
  command-line tools, or through RESTful web services.

People might talk about it being “your operating system for private cloud” which is a bad analogy. In general the term “operating system” is often deliberate misused as it has positive connotations and might indicate to none technical people the broad benefits of investing in a given technology. For example people might also talk about container orchestrators such as Kubernetes or Docker Swarm being “the new operating systems of the cloud” which is a similar poor analogy.

If a backup project said it provides connectors for AWS S3, Azure Blob, Google Cloud Storage, and Openstack Swift then it would be more clear exactly what it does: write large binary backup files into a cloud store. Such a product could then accurately say it supports AWS, Azure, GCP, and Openstack. Just to be clear I am not saying the the technology you are looking at actually uses those APIs I am making a general point about openstack having feature parity with many public cloud technologies.


What's the practice to perform a releasing with Git? I'm using GitLab CE with Maven project, and try to follow the Environment branches with GitLab flow and The 11 Rules of GitLab Flow

The step for releasing is as the following: -

feature   +---   +---          +---
         /    \ /    \        /    \
master  + ---- + ---- + ---- + ---- +
                        \            \
qa-tmp (chage ver to RC) +---         + ---
                             \             \
qa      + ------------------- + ---------- +
                             (v1.0-RC1)   (v1.1-RC1)
                              \            \
prod-tmp (chage ver to final)  +---         + ---
                                   \             \
prod    + ------------------------ + ------------ +
                                 (v1.0)         (v1.1)

Create a feature branch and merge into the master so that it is ready to be released
Create the qa-tmp branch e.g. release-v1.0-RC1 from master

2.1 Update the pom version to 1.0-RC1

2.2 Merge the release-v1.0-RC1 to qa

2.3 Tag v1.0-RC1 from merged qa branch.
When it pass the QA, create prod-tmp branch e.g. release-v1.0 from tag v1.0-RC1

3.1 Update the pom version to 1.0

3.2 Merge the release-v1.0 to prod

3.3 Tag v1.0 from merged prod branch

3.4 Bump master to version 1.1-SNAPSHOT
Develop the version 1.1-SNAPSHOT in the features & master when it is ready to be released, repeat the step 2 and 3.

The trouble is since the version is changed during merging the qa branch and prod branch, when I perform a next release there is a merge conflict for the version inside the pom. This cause me to resolve this conflict manually.

I'm not sure if I'm doing something wrong or misunderstanding about the releasing procedure or not.

Furthermore, do we have any practice to make this releasing to be an automation, e.g. via script?

Could you please help to advise?

Consider to substitute the version in POM by the git describe upon build without hardcoding the version in your repository, you could do this with e.g. sed from below version_slug.

export git_version=`git describe --tags --always`
export version_slug="$(sed s/-/\./g <<<$git_version)"

and then substitute the version_slug in pom.

In that way for each commit and/or tag in gitlab, you'll create a new version, with out actually changing the repository.

this is what i did for a ruby project: jekyll-plantuml-url, where the version is not coded in the source, but is set upon build, and after testing deployed as the git tag.

  script:
   - bundle install
   - rake set_git_tag
   - rake
   - gem build jekyll-plantuml-url.gemspec

Furthermore don't understand the need of all those branches, with CI/CD we continuously build, test and deploy, that means before accepting a merge to master you have a deployment for QA to do the testing, code review, functional testing ...etc.

Next add QA as approver for a merge to master, thus make it mandatory that QA signs of a merge request to master and integrate quality in the development cycle or have a master that is always ready for release.

One could opt to work from master and for a release tag the master branch with a version tag, as per above example.

OR

like gitlab does it, to create a branch for each release, cherry pick the features from master that are ready or planned and then tag the branch with a version tag.

where as a version tag creates a deployment for a commit, release or a RC.


Can I build docker image containing ARM executable when running docker build on non-ARM architecture? I have built on an x86-based Windows laptop a Docker image to be run as a container on an ARM-based architecture (Raspberry Pi 4).
Due to ending up with an x86 executable when this is built in the Dockerfile, as much as possible, including the library and app build, is deferred until the container actually runs on the Pi.
However, this seems absurd in that the build must be done each time the container runs (which it may on many Pis). No doubt it also needlessly increases the container's size (which is less important, but still annoyingly sub-optimal)
So in summary, I wonder if there is a way to run gcc in the Dockerfile and indicate that the target architecture is ARM and not the laptop on which the docker build is running.
My Dockerfile currently comprises :
FROM arm32v7/ubuntu:latest

# Defined only while image is being built
ARG DEBIAN_FRONTEND=noninteractive

# Set in container
ENV TZ=Europe/London

ADD ./src /app
WORKDIR /app

# Development only :
#
#   vim
#
RUN apt-get -y update \
 && apt-get -y upgrade \
 && apt-get -t install apt-utils \
 && apt-get -y install tzdata \
 && apt-get -y install dh-autoreconf \
 && apt-get -y install libcurl4-gnutls-dev \
 && apt-get -y install libexpat1-dev \
 && apt-get -y install make \
 && apt-get -y install gettext \
 && apt-get -y install libz-dev \
 && apt-get -y install libssl-dev \
 && apt-get -y install libghc-zlib-dev \
 && apt-get -y install git \
 && apt-get -y install build-essential \
 && apt-get -y install vim \
 && git clone https://github.com/eclipse/paho.mqtt.c.git

CMD ["/bin/bash", "myapp.sh"]

and myapp.sh comprises :
#!/bin/bash

# Build Paho MQTT library
#
cd /app/paho.mqtt.c
make

# Build the experiment app
#
cd /app

gcc -L/experiment/paho.mqtt.c/build/output -o myapp -lpaho-mqtt3a main.c

./myapp

I would have thought the first line "FROM arm32v7/ubuntu:latest" in the Dockerfile would tell gcc that the target architecture was ARM, but evidently not!
P.S. I know I could manually build the app outside Docker on a Pi, and simply copy the ARM executable into the Docker image. But I would rather the the app build is included as part of the image build if possible.

I've not tried this myself, but it seems that you can use docker buildx to build for multiple architectures: https://www.docker.com/blog/multi-arch-images/.


How to send local files using Terraform Cloud as remote backend? I am creating AWS EC2 instance and I am using Terraform Cloud as backend.

in ./main.tf:

terraform {

    required_version = "~> 0.12"
    backend "remote" {
    hostname     = "app.terraform.io"
    organization = "organization"
    workspaces { prefix = "test-dev-" }

  }

in ./modules/instances/function.tf

resource "aws_instance" "test" {
    ami = "${var.ami_id}"
    instance_type = "${var.instance_type}"
    subnet_id = "${var.private_subnet_id}"
    vpc_security_group_ids = ["${aws_security_group.test_sg.id}"]
    key_name      = "${var.test_key}"

    tags = {
        Name = "name"
        Function = "function"
    }

  provisioner "remote-exec" {
    inline = [
      "sudo useradd someuser"
    ]

    connection {
      host = "${self.public_ip}"
      type        = "ssh"
      user        = "ubuntu"
      private_key = "${file("~/.ssh/mykey.pem")}"
    }
  }
}

and as a result, I got the following error:

Call to function "file" failed: no file exists at /home/terraform/.ssh/...

so what is happening here, is that terraform trying to find the file in Terraform Cloud instead of my local machine. How can I transfer file from my local machine and still using Terraform Cloud?

May be a better way to manage private key is using protected variables into the Terraform Cloud. Otherwise you have to save it in repo that is not secure.


Healthcheck: CMD vs CMD-SHELL It's not clear to me what are the differences between CMD and CMD-SHELL in Docker Compose healthcheck.

What are the benefits of using CMD-SHELL compared to CMD? What are the use cases for CMD and CMD-SHELL?

Docker can either run the command using the equivalent of the OS exec syscall directly in the kernel, or it can run a shell (typically /bin/sh) to call your command. A shell provides functionality you are accustom to from the command line, including:

I/O redirection and pipes (>, >>, <, etc)
Command chaining (&& and ||)
Variable expansion ($var)

However, a shell may also intercept signals, particularly when running as pid 1, which can prevent a graceful shutdown of a container (not much of an issue for a healthcheck). In addition, to run a the shell syntax, your container's image must include a shell, which means that won't work for images based on scratch that do not include a /bin/sh.


How can I keep track of my Cloud Resource use? I am trying to automate my AWS application deployment with Jenkins.

Right now if we want to update the application in any of the environments, say UAT, we build our docker images, find the current ECS Task and update it with the new image, find the running ECS Cluster, and update the tasks.

Broadly, what is best practice for keeping track of cloud resource Id's (ECS Cluster Id's, ECS Task Id's, EC2 Id's, etc) in your Continuous Integration environment?

A judicious usage of one of the cloud "orchestration" tools, such as Terraform or possibly Fugue seems to be the best way.

You can start small, pick a less important and not very extensive environment, carefully decipher it into automatable code and proceed from there.

Broadly this is referred to as infrastructure-as-code, for googling and other buzzword-oriented media applications.

More specifically, say, if you had your environment described in Terraform's HCL files, you would have required ID's exported as "outputs" and could operate on those from scripts/Jenkins jobs/etc


How to store docker images in Nexus OSS The following documentation was found that indicates that:

  simply create a new docker (hosted) repository as documented in
  Repository Management

The problem is that the format docker seems not to be available when trying to configure a "Hosted repository"

Nexus 2 was deployed instead of Nexus 3. The docker feature seems to be introduced since Nexus 3.

This blog indicates how to configure a docker repository and how to push and pull docker images.

The blog contains multiple pictures. The following picture indicates how to enable the docker registry:


Get available CIDRs from existing VPC I'm writing a few templates to create a stack on demand.
Because of the concurrent VPC limitations (5 to start), I'm attempting to create all the feature-based dev environments on a single VPC and mostly divide the stacks by subnets. The idea is that every stack will have 2 private and 2 public subnets.
I know I can get specific CIDRs with something like this (YAML):

!Select [ 0, !Cidr [ !GetAtt MyVpc.CidrBlock, 1, 8 ]]

But I need to make sure I'm getting CIDRs that are not being used by some of the other stack.
Programmatically, I would get all CIDR blocks from the VPC and then filter all the ones that are used by other subnets, to get a final array (or simply return x items from the array).

Is getting a block of free CIDRs or a single free one something I can do with the intrinsic functions?

Don't worry about putting each stack in its own set of subnets, that's an overkill.

Simply make the resources' Security Groups refer to other SGs in your stack templates and not to subnet CIDRs.

What that means is for example the RDS SG sg-123456 will permit traffic from App SG sg-9876543 and not from the App subnet 10.20.30.0/24 you'll be fine from the network isolation perspective.

We usually have the VPC infrastructure shared for dev, test and feature stacks. That's perfectly fine. Moreover we also use CloudFormation Exports to simplify the templates.

Hope that helps :)


Any suggestion for a provider to deploy a first Dockerized application? To conclude my Docker course, I would like to make my students deploying an app on some cloud provider. A priori, the deployment will be on a single host using docker-compose (i.e., no swarm, no kubernetes).

Which provider would you suggest knowing this is for students? I am looking forward to some free solution and the deployment needs to be seamless, ideally from the command line.

I've seen DigitalOcean provides a free trial with ssh access so that could do the trick. But I never worked with them, so I'm not sure they aren't hidden issues. Also, even for the free trial, they seem to require a credit card number, which may cause difficulties to some of my students. Any other idea?

You can launch a t2.micro instance in AWS and use it free for the first year. Check for the RAM and disk space and keep your docker image and container within those limits. You can either use AWS ECR as image registry or Docker Hub.


Infrastructure as code and TDD Infrastructure as code tells us to use tools that automate your builds. Great. Tools like ansible, chef, puppet, salt stack and others push us towards writing how infrastructure looks like, while resolving the differences.

In Salt Stack those bits are called states. If state does not match the reality, the tool will resolve it for us. In other words - we are writing a test for our infrastructure and if the test fails, the tool will fix it on its own. At least that's the idea.

XP teaches us to use TDD and the question is if it's applicable to infrastructure? The tooling suggests it is.

I can imagine few type of tests that can be very useful.

We write smoke tests that are bundled with the deployed service to ensure that end-to-end the deployed service works and runs as expected. This would be an API call or/and systemctl check to make sure what we just deployed works. A lot of this functionality can be covered in the same states since tools like ansible have states to make sure a service is running.

There is project Molecule that allows running individual roles (as ansible calls its states) against docker or another temporary virtualisation engine. This forces to decouple roles and allows to execute them in isolation from the playbook while working on them. Tests mostly allow mocking the variables that the role is supposed to work with. Other examples seem like a duplication of the ansible engine though (assert a file belongs to a user...).

ThoughtWorks tech radar right now praises tools like inspec, serverspec or goss for validating that the server meets the spec. But we are writing a spec, aren't we?

So is there a point in further testing infrastructure if we are describing infrastructure in states/roles? I could suspect this becomes more required in larger organisations where one team provides the spec and other follows, or if there is a large set of roles maybe you want to run a subset of those and get a speed benefit from tests? I'm struggling to see why you would write a test if you could have a role/state for the same question in mind.

In short, I see two categories of tests for your infrastructure: 1) does it have everything you need to run your application and 2) does it not have any superfluous stuff.

First and foremost, you can treat the test suite of your actual software as a kind of "meta test" for your infrastructure. As long as you create the infrastructure from scratch for each test run, and the test suite runs completely on that infrastructure (i.e., doesn't use outside services) the fact that the whole suite is green means that your codified infrastructure is sufficient as well.

Second, especially from the security perspective, you can write tests against your infrastructure. I.e., if one part of your infrastructure is a VM running Linux, you might write a test that does a port scan against that VM, to make sure that there are no unintentional ports open, which may have been installed by an unintended apt-get install side-effect. Or you could write tests that checks whether any unexpected files were changed after your proper test suite has completed. Or you could check the ps outputs of your VMs or Docker containers for unexpected processes and such, build white-lists etc., and thus get automatic notification if some 3rd party package changed in an undocumented (or unnoticed way) in some upgrade.

These second type of tests are, in a way, similar to what you would do in a classical ops setting anyway, i.e., hardening your servers and checking for intrusions, avoiding full ressource and such.


Accessing a AWS docker instance via localhost only? Suppose I have two apps launched via the AWS ECS cluster (using Docker containers).
I want to expose one app to the world via a public IP (and I do it via the AWS load balancer) but the other one I want to be able to access only internally, so that it would not have any public IPs and would only be accessible internally.
Is this possible to do that at all? I suppose it should be easier via docker containers because I could possibly make them communicate to each other by exposing a localhost via
--network="host" in docker run

But that would work if I run the two apps on the same EC2 instance.
What if I run them on separate instances but they are using the same load balancer or — separate instances but in the same AWS zone?
What setting would I use in ECS to expose this app only via the localhost?

Have you tried using awsvpc mode? https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-networking.html
You can follow this tutorial - https://docs.aws.amazon.com/AmazonECS/latest/userguide/create-public-private-vpc.html
You need a VPC, with at least two subnets, one private and one public. After that the sky is the limit ...
If you need internet access from the private subnet, create a NAT Gateway in the public subnet, and route traffic from the private subnet to 0.0.0.0, via the NAT Gateway - https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Scenario2.html
P.S - I never use network mode host with ECS, you should read more about it here - https://docs.docker.com/network/host/ I didn't find a strong use case for using it, except for testing purposes


How to pass dynamic properties to an MSbuild task? Is it possible to pass a dynamic property group to an MSbuild task? So if I have the following properties and values:

<MyPropertyGroup>
   <Foo>bar</Foo>
   <Foo1>bar1</Foo1>
   <Foo2>bar2</Foo2>
</MyPropertyGroup>

I could call MSBuild with a short property list:

<MSBuild Projects="$(SolutionFile)" Targets="Build" Properties="MyPropertyGroup" />

But it would be the same as calling the task like this:

<MSBuild Projects="$(SolutionFile)" Targets="Build" Properties="Foo=bar;Foo1=bar1;Foo2=bar2" />

This is helpful if there's a large property list, and allows for only 1 place needs to be maintained.

This question was kindly answered on StackOverflow. For anyone else looking for an answer:

<PropertyGroup>
  <BuildParameters>
    Configuration=Debug;
    Platform=Any CPU;
        SomeOtherProperty=Foo
  </BuildParameters>
</PropertyGroup>
…
<PropertyGroup>
  <!-- this property can even be extended afterwards, e.g. when a condition is needed -->
  <BuildParameters Condition=" '$(ShallAppendThings)' == 'true' ">
    $(BuildParameters);
    AnotherProperty=SomeValue
  </BuildParameters>
</PropertyGroup>
…

<MSBuild Projects="$(SolutionFile)" Targets="Build" Properties="$(BuildProperties)" />

source:
https://stackoverflow.com/questions/46226120/how-to-pass-dynamic-properties-to-an-msbuild-task


What are the reasons Docker should not be used for databases? I'm having a discussion with a friend about use cases for Docker. One guy in the team wants to use Docker for everything - like a kind of universal unix process wrapper. The other thinks that Docker should only be used for stateless applications like Microservices and AWS Lambda style apps.

We've engineered proof of concepts for both. On our docker cluster we have a shared drive that gets mounted when the Docker host is mounted, and if a Database in a container is mounted, it simply mounts a volume to the shared drive.

My friend still sticks to his position, despite being shown the contrary evidence. (He also argues that Docker adds unnecessary risk by adding complexity to the stack.)

I'm trying to listen and understand his point of view, both in an act of empathy, but also to better reason with him. (We all get on quite well - so this is a mix of in-jest and serious discussion).

Kind of the question behind the question is: are databases cattle? This comment suggests that a good automated backup and retrieval strategy for your database is indistinguishable from a cattle server.

My question is: What are the reasons Docker should not be used for databases?

EDIT:
People have asked me to clarify my terminology. I was assuming that the database application was in the container, and the storage was in the volume. What I meant was, the RDBMS is in the container, and the database storage is in the volume.

Some commentators have suggested that the docker volume drivers aren't going to work with database writes very well. (Or something to that effect). Could you please expand on that?

When people talk about running a database in Docker, they do not mean to store the data in a container; they are talking about having a docker image with the DB software, and mounting the data as a volume (a bind volume, not a container volume).

Volumes are an essential part in Docker, and are not something that is flakey or just tacked on. Docker is not just made for stateless (micro)services.

Wish as I might, I cannot find a technical reason not to run a database in a Docker, so unfortunately I'll pick the other side of the argument and hence maybe not give you the answer you are looking for.

(I'm using Oracle as an example because I'm familiar with it, both bare metal and dockerized, and because it's quite a notorious beast for being just a bit non-trivial to operate if you go past default settings.)

Packaging up the DB software itself in a container gives you the usual benefits - having the same version everywhere, avoiding dependency/shared library issues, being able to spin up the exact same DB on developer laptops or wherever you need it.
It is a snap getting it to run anywhere; updating is trivial, and so on. All the Docker benefits apply. There is an Oracle image on Dockerhub which allows you to spin up a working DB in a minute or three (and for the others as well, of course).
People did do performance tests and found no I/O differences between volumes and bare metal (https://www.percona.com/blog/2016/02/11/measuring-docker-io-overhead/, https://stackoverflow.com/questions/21889053/what-is-the-runtime-performance-cost-of-a-docker-container).
Under the hood, it's not like Docker somehow intercepts all I/O, anyway. It just gets creative with standard Linux tools (bind mounts in this case, mangling of the internal kernel tables that make the Docker-fu possible at all).
Obviously that does not mean that you can run two instances of the DB and just have them work on the same files, but nobody is implying that. Docker does not give you automatic simultaneous and magically race-free access to volumes, and did never pretend to do so. The rest of the benefits still apply. If your DB itself does not detect conflicts like this, you better supply a CMD script to the image which refuses spinning up a second container when the volume is already in use.
You have to be a little more careful spinning up/shutting down the container (just as you would not simply switch off a bare metal DB server), but that should be quite manageable.

Now, depending on circumstances, there may be soft reasons not to do it:

Oracle (the company), for example, will certainly not support you if you run their RDBMS in a Docker container. But maybe you are using dockerized Oracle RDBMS images only for your developers and the testing environment, where you would not need their support in any case, reserving it for a bare metal production server. (But don't forget to pay your licenses...).
If the ops guys are unfamiliar with Docker, it might just be a bit easier to accidently kill everything, destroy your data files etc..
If you have big dedicated metal DB machines already, with large amounts of very fast dedicated SAN storage, and running nothing else anyways, then there would just be no point in using Docker to containerize those as you will never just spin another server up when there are 100s of GB or even TB of data. After all, for production, a RDBMS like Oracle is very, very advanced in all the replication, data integrety, no-downtime failover, etc. aspects. Note that this argument just says "you do not need to containerize your RDBMS". It does not say "you should not do it" - maybe you want to do it because you wish to roll out database software upgrades through containers or for whatever other reason you could imagine.

So there you go. By all means do dockerize your DB, at the very least for your developers (who will be eternally thankful) and your testing environments. On the production, it will come down to taste, and there at least, I would also prefer the solution that sits best with the specialized DBA/Ops - if they have decades of experience working bare metal DB servers, then by all means trust them to continue so. But if you are a startup who has all IT in the cloud anyways, then a Docker container would just be one further piece of onion in the whole picture.