What processes or tools enable Segregation of Duties when engineers both deploy and run code?

Your question doesn't seem to make any assumption about the platform/OS it is about. Which is why it may make sense to add an answer about how this is typically done/addressed in a mainframe environment, where the "engineers" (as in your question title) are actually groups of people were dozens (possibly hundreds) of people are involved. My answer is based on using the SCM product where I'm most familiar with (not sure if it's needed to disclose the product name).

1. Architecture

Here are the highlights of how I'd answer your question:

All code (and related artifacts like executables, etc) is stored in files which, all together is what we call the library structure.
For each environment on each (possibly remote) target system, there is a server (a "started task" in mainframe speak), which takes care of ALL (repeat: ALL) updates to anything in the library structure. There are a few exceptions (like security people, or space management team), but apart from that, nobody (repeat: nobody) has authorization to apply updates to any file within that library structure. In other words: the server gets exclusive update authority to the entire library structure. Attention: OPS-people will go bonkers if you walk in to limit their access (at first they are going to resist ...), so make sure you're covered by upper management (CxO) to impose those access rules ...
The actual software changes my consist of a single component (a tiny code fix in the middle of the night ...), or it may also be hundreds or thousands of sources, executables, or whatever other artifacts (during a release weekend). To make them manageable, things that should be moved (more or less) together, at the same time, are bundled together in what's called a software change package.

With the above in place, any kind of update to be applied by the server to the library structure, will only be possible via a well defined workflow, which we call the lifecycle of a software change package (SDLC if you prefer). To actually execute the various steps in that workflow, this is what it takes to make it happen:

Only the server will execute the required (and preconfigured) steps.
The server will only do a specific step (= update something somewhere in the library structure), after the required approvals (from human beings) have been gathered to perform such step.
The approvals can only be given by users who have a role that allows them (= permission) to issue such approvals.

2. Roles and permissions

The server will ensure that the user trying to make something happen (like 'approve something') will only be able to do so, if the user's permissions are appropriate. That part is easy. But you don't want to use the SCM system to administer all those permissions for all the users involved, that's what belongs in your security system (not the SCM system!), so that you can adapt your workflow (in your SCM system) to go check those permissions whenever appropriate. The steps below provide some more details on that.

Step 1: Configure the permissions (in the security system)

Define security entities in your security system, with well defined names for those entities. A few samples (add as many similar ones to fit your own needs):

PrmUnit, used for getting permission to request a Promote to say Unit-testing.
PrmQA, used for getting permission to request a Promote to say Qa-testing (let's assume this is the highest level of testing).
PrdEnduser, used by end-users involved in some level of testing, to indicate that they are satisfied by the results produced by some kind of testing. And because of that, those end-users agree with the change moving forward in the library structure.
PrdRelmgnt, used by release managers to authorize an Activation in production (= the last/highest level in the library structure).

Define groups of users in your security system. A few samples (add as many similar ones to fit your own needs):

GrpDevs, which (say) corresponds to your developers (probably more then just 1).
GrpEnduser, which (say) corresponds to your end-users (at least 1, preferably with more similar users).
GrpRelMgnt, which (say) corresponds to your release managers (at least 1, preferably a few more users).

Grant permissions, also using your security system, to allow access to selected "security entities" for selected "groups of users". To continue the example above, here is what seems appropriate (adapt to fit your own needs):

Group GrpDevs gets access to (only!) security entity PrmUnit.
Group GrpEnduser gets access to (only!) security entity PrdEnduser.
Group GrpRelMgnt gets access to (both!) security entity  PrmQA and PrdRelmgnt.

Step 2: Configure the workflow (in the SCM system)

After the permissions are configured in your security system (as in Step 1), all that's left to do in your SCM system is to configure how the various steps in the lifecyle match with the related security entities in your security system. That is, only those users who have the appropriate access to the required security entity, are allowed to request the server to perform the corresponding step in the workflow.

Here are some examples of how you'd configure your SCM system to make some magic happen:

If a user has access to PrmUnit, then such user is allowed to request a Promote to Unit-testing. Obviously, the users in group GrpDevs are the users authorized for this (note: not, e.g, the users in group GrpRelMgnt).
If a user has access to PrmQA, then such user is allowed to request a Promote to QA-testing. Obviously, the users in group GrpRelMgnt are the users authorized for this (note: not, e.g, the users in group GrpDevs, or in group GrpEnduser).
If a user has access to PrdEnduser, then such user is allowed to authorize the change moving forward in the library structure (which is typically a prereq for users in group GrpRelMgnt to even be able to review a change). Obviously, the users in group GrpEnduser are the (only) users authorized for this.
If a user has access to PrdRelmgnt, then such user is allowed to authorize an Activation in production (= the last/highest level in the library structure).

3. Expect the unexpected, and be ready for it

The above is just a blueprint, which hopefully helps to understand how in the end it is the server that takes care of the segregation of duties ... provided you have the CxO cover you to impose some access rules that not everybody will like.

To complete the picture as explained above, the server creates an audit trail (logging) of anything that's happening in the system. So that at any point in time, it is always possible to answer questions like

  What happened when and why, and which authorized user actually approved it ... upfront?

But, probably the toughest part is to have adequate reporting tools available (and know how to use them). At least to (easily) satisfy requests from IT auditors (their questions can be very challenging). But also to point to relevant log records in your SCM system to answer all sorts of "What happened"-questions in crisis situations where (part of) production is down.

PS: I leave it to everybody's own judgement if my answer is yes or no DevOps-compliant.


Is there any Jenkins plugin for pylint results?

Jenkins accepts JUnit-formatted test results with the JUnit plugin, so you could try pylint-junit to output JUnit-formatted results (I have not tried this myself).
Also it looks like a very similar question was asked and answered over on StackOverflow.


Unable to run the playbook in remote machine using Ansible job template. Connection Failed

Looking at your code it seems you try to connect to a Windows host. Usually you connect windows via WinRM and not via ssh

The user guide for this can be found here: https://docs.ansible.com/ansible/latest/user_guide/windows_winrm.html

  For Ansible to communicate to a Windows host and use Windows modules, the Windows host must meet the following requirements:

  Ansible’s supported Windows versions generally match those under current and extended support from Microsoft. Supported desktop OSs include Windows 7, 8.1, and 10, and supported server OSs are Windows Server 2008, 2008 R2, 2012, 2012 R2, 2016, and 2019.
  Ansible requires PowerShell 3.0 or newer and at least .NET 4.0 to be installed on the Windows host.
  A WinRM listener should be created and activated. More details for this can be found below.

Then you need to tell ansible to connect wia winrm

...
ansible_connection=winrm
...

Checkout the details here: https://www.ansible.com/blog/connecting-to-a-windows-host


error validating data: couldn't find type

kubernetes is picky and case-sensitive:

kind: Pod

should do it.

Also, spec should not be in metadata:

apiVersion: v1
kind: Pod
metadata:
  name: Testing
spec:
  containers:
  - name: mysql
    image: mysql
    imagePullPolicy: Always
    command: ["echo", "SUCCESS"]


Other tools to provision virtual machines

Have you considered to use Ansible?

You have some resources about using Ansible with VirtualBox and also vagrant


How to publish a docker image to a private docker registry using Jenkins' blueocean?

You can try to use scripting syntax into the declarative pipeline. For some step there is no declarative syntax yet. I had the same problem trying to use the docker global variable as a step.

stage ('Docker Build') {
  steps {
    // prepare docker build context
    sh "cp target/project.war ./tmp-docker-build-context"

    // Build and push image with Jenkins' docker-plugin
    script {
      withDockerServer([uri: "tcp://<my-docker-socket>"]) {
        withDockerRegistry([credentialsId: 'docker-registry-credentials', url: "https://<my-docker-registry>/"]) {
            // we give the image the same version as the .war package
            def image = docker.build("<myDockerRegistry>/<myDockerProjectRepo>:${branchVersion}", "--build-arg PACKAGE_VERSION=${branchVersion} ./tmp-docker-build-context")
            image.push()
        }
      }
    }
  }
}


Git Workflow with User Acceptance and Staging Environments

My favourite workflow is the development-less "branch per feature" workflow from Adam Dymitruk (http://dymitruk.com/blog/2012/02/05/branch-per-feature/). It has these branches:

Exactly one master in an unbroken line from day 0 up to the version of your app that is currently in production.
Many feature-... branches.
One (or if you are so inclined more) qa branch.

The gory details can be found on Adam's site, but in short:

Every branch goes off of master.
All branches that are in active testing are merged into qa.
qa only ever contains merge commits (i.e. feature branches merged on top of each other, starting from master), never direct manipulations.
Whenever a feature branch gets new commits, and you want those in qa, you rebuild qa from scratch.
Whenever you want to deploy a bunch of features, you create a qa from all of them, test to your heart's content, and then simply rename that branch to the new master (which, as it started out from the old master, will be a direct, unbroken line of merge commits from day 0). Then, all feature branches are rebased on that.
One fundamentally important part for this workflow is to enable the git rerere cache feature, and distribute that cache between all developers. Hence, every merge conflict needs to be resolved only once, globally.

It's trivial to have more than one qa branch at a time to test different subsets of features; in your case, you could have qa (with everything nearly close to finished, i.e., compiles without error), qa-acceptance, qa-staging or whatever you like.

In my experience, there is always a relatively large main, ongoing qa branch (recreated from the master and features regularly), and when some features are picked for release, the will be a temporary smaller qa-....

It is trivial to add and remove individual features from the set of qa or release-candidate branches on the fly, as those are recreated constantly and only ephemeral.

You will find a lot of people very much objecting to git rebase, but if one wraps their mind around the fact that this is just a tool like any other, it will be fine. You need good tooling for this of course, but this is not complicated to program yourself; the actual git commands are all pretty simple and self-explanatory.

We have extended the workflow (or rather our tooling) to even allow arbitrary sub-features (i.e., feature branches going off of another feature branch, not master), so multiple branches can go off of a common ancestor which is not yet in production; works like a charm. But you can get pretty far without this.


CORS and subdomains - do subdomains matter?

CORS is not allowing subdomains, so you need to specify them in your server configuration.

If you are using NGINX (or you could use it as a proxy and solve your problem) by providing dynamic cors header response

server {

    root /path/to/your/stuff;

    index index.html index.htm;

     set $cors "";

    if ($http_origin ~* (.*\.yoursweetdomain.com)) {
        set $cors "true";
    }

    server_name yoursweetdomain.com;

    location / {

        if ($cors = "true") {
            add_header 'Access-Control-Allow-Origin' "$http_origin";
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE, PUT';
            add_header 'Access-Control-Allow-Credentials' 'true';
            add_header 'Access-Control-Allow-Headers' 'User-Agent,Keep-Alive,Content-Type';
        }

        if ($request_method = OPTIONS) {
            return 204;
        }

    }
}

Source here


What are reasons for not not using Bitbucket-server for storing artifacts?

Reasons not to store large binaries in a git repository:

Everbody cloning your repository will download all those binaries, by default. Binaries, if built regularly, tend to consume massive amounts of storage, compared to source code - git cannot compress them, or calculate deltas, to reduce their size.
git goes to great lengths to make sure history is not lost, it will never delete anything that is part of the history of any ref (branches or tags). That also means that if you later decide to delete old, long-useless binaries due to running out of space, you will find that, while not impossible, very hard indeed.
One point of proper artifact stores is that they help phasing out outdated or compromised parts. git cannot really do that for you - you'd have to write your own tooling for that - and you will never get rid of the old versions in history.
The concept of a "commit" does not really apply to binaries. You need operations like "upload" and "download", as they are regularly involved in the build processes of your software (i.e., bundler in the ruby world, or maven in Java). Those builders know how to fetch their 3rd party libraries from artifact repositories easily, and how to upload new versions. They may be convinced to work with a  git repository for downloads, but since git has no versioning information, you again need to have your own tooling, specify the commit in which to find that binary manually, or have all binaries ever in use checked out locally. And uploading to a git repository, again, would use your own tooling (creating spurious commits as well).

In total, using git for that is just the wrong tool. If your colleagues are afraid of adding yet another complex tool like Nexus, then at least convince them to use a simple tool instead of git - like some arbitrary (s)ftp/scp repository in a VM somewhere, with https access via a simple webserver.

If you must use git, then at least make sure the build binaries are not committed together with the source code, but in their own part of history. Check out this older answer to see how to create an orphan branch. Those can at least be deleted later, and the binaries themselves removed by garbage collection; and not every client is forced to download all of it all the time.


Running a background process in Pipeline job

Any one facing the same problem and using pipeline project, set JENKINS_NODE_COOKIE instead of BUILD_ID.

Dont waste your time setting HUDSON_COOKIE, HUDSON_SERVER_COOKIE, JENKINS_COOKIE or JENKINS_SERVER_COOKIE. None of them work for pipeline project.

Refer to https://issues.jenkins-ci.org/browse/JENKINS-28182 for more details.


Communication between VPCs and a transit VPC hosting VPN Server without Masking source IP

VPC peering does not support transit traffic.

Unsupported VPC Peering Configurations described several scenarious that are not supported.

This case is not specifically mentioned, but is implicit from the other limitations.

Note also that it is impossible to fully configure the setup you are attempting, because when you route a given destination towards a remote VPC via a peering connection, there is no route table in the target VPC that is applicable to that traffic. Only the instance subnets are available.  Route tables apply only to subnets, and the default route table only applies to subnets without an explicitly assigned route table -- not to incoming traffic from a peering connection.  There is no way to route this traffic back to your instance.

This is why Hardware VPN, Direct Connect, and NAT devices are not available across peering,

A Transit VPC is not what you have described.  These use AWS VPC Hardware VPN connections on the spokes and an EC2-based router at the hub to terminate the tunnels... and the transit routing between the tunnels is done within the instance -- not by the VPC network infrastructure.


Extended Choice Parameter: How to load params dynamically from any file for jenkins build job

Use the Active Choice Parameter plugin which allows you to run a Groovy script to dynamically load values for your parameters.


How to implement the four-eyes principle for emergency fixes?

In the SCM-world where I'm mostly familiar with, the above scenario is typically addressed by what's called the "abbreviated-approval list procedure.

Here is a blueprint of it:

Define your business hours, say from 8 am to 6 pm.
Define a complete approval list of (say) 3 levels of approval (for roles X, Y and Z).
Define an abbreviated approval list of (say) only 1 level of approval (only for roles X).
Planned changes always require all approvals from the complete approval list.
For Unplanned changes, the complete approval list is used also to gather the required approvals, provided the approvals are to be issued during the defined business hours.
For any approvals of unplanned changes that are to be issued outside the defined business hours:

Only the approvals from the abbreviated approval list (such as role X above) are required to authorize the change. And after the authorization by the abbreviated approval list is given, the deployment of the change (in the target environment) will actually be performed.
But additional post-approvals will be needed afterwards (within a reasonable amount of hours/days), i.e from all roles contained in the complete approval list (such as role Y and Z above), which are not also contained in the abbreviated approval list (such as role X above). And if within the (upfront) agreed amount of hours/days not all post-approvals have been issued (e.g because the fix worked "this" time, but was only like a temporary fix), then the change might be subject to a rollback. While there is at least 1 outstanding post-approval, the change is marked as "waiting post approvals".

With such solution in place, the call can be closed around 3:23 am ... since there will be no more red flag at 3:21 am ... ggggrrreat, time for a beer to celebrate my fix to get production going again (instead of coffee) ... and fingers crossed the outstanding post approvals will come in soon ...


What is the best tool for the release management for Kubernetes in a small startup?

GitLab is a solid good option for most of this (with the appropriate plan level - I don't think the CE one has everything).  It's a single-pane-of-glass for your code, security, CI/CD, metrics, etc.  You can create and deploy to kubernetes clusters from it.

You can have multiple environments and it'll store the secrets for you to customize them.
It will monitor your kubernetes apps and show deployment marks so you can see if they get better/worse performance wise before and after deployment.
You can do multi project pipelines and actions in parallel to chain things together and get things done fast.
It supports review apps and canary deployments.
It has rollback buttons and tracks every release you do.  It also has a good API, so I assume you could hook up prometheus + alert manager and make the API trigger a rollback in response to an alert.

Spinnaker has https://www.armory.io/ if you're willing to pay a bit (not sure how much).  But that should make it easy to use / effective.

I'm not amazingly fond of Jenkins, but it can do everything.  Its hard to maintain over time / with bigger projects and teams though.  But it can be customized to do anything.  You may want to look into https://jenkins.io/projects/blueocean/ (the blue ocean plugin) for CD if you're leaning this way - it looks fairly impressive and I've heard good things.


Deploying different versions of the same application stack in the same system

First of all, I would not recommend to use a single system for running stable and testing version both on the same system. There are many reasons for this such as:

Your testing version can cause cpu and memory spikes on system which will ultimately affect your stable version and end users.
Secondly, it will be difficult to manage the dependencies and resources for multiple versions in a single system.
It can also take a lot of debugging time if the monitoring is not properly setup.

Ideally, you should use 2 different system. One for running the stable version and other testing versions. It will be easy to manage and always a good practice to keep it on different stack.

Still, if you want to use a single system, then yes, you can use docker which will avoid a lot of conflict issues which can arise. Also, the dependencies and shared libraries can be managed easily with different docker images and running docker containers.

If the team is proficient in docker, you can also use docker swarm to setup clusters. You can setup different clusters for stable and testing versions.

I hope you chose the best possible option and implement it.


Using GSuite or Github to Manage who can log into Linux or Windows VMs on Azure

I would really prefer to not have to also manage a separate Active Directory Domain within our VNets

You've already found the answer: centralized authentication.

If you use a tool like Okta, you can indirectly tie GSuite to AD (or an LDAP server).  And then of course you can tie OpenSSH there as well.

  or deal with revoking ssh keys

Centralized authentication solves this.

  or updating multiple usernames/passwords on every single VM we deploy.

And this as well.

You've already got the answer, even if you don't like it.


What are the correct volume maps for zabbix running on Docker?

There is a list of all the important paths Zabbix containers use: https://www.zabbix.com/documentation/3.0/manual/installation/containers
(scroll down a bit until you find "Volumes" part).

If I were you, instead of bind mounting these directories I would build a derivative image from the official Zabbix image and run statements like "COPY my_alertscript.sh /var/lib/zabbix/alertscripts/" in the build phase.

If, for some reason, baking your changes to the image itself is not possible, then you may still want to prefer named volumes instead of bind mounting. See: https://docs.docker.com/storage/volumes/ to read about its advantages.


Ansible: how to display the name of the currently running included_tasks playbook file?

If you want to "add base_packages.yml to the title of the task" you'll have to add it to the names of the tasks. For example

shell> cat base_packages.yml
---
- name: "base_packages: .... "

sed might help to automate it.


In the HashiCorp stack, where's the appropriate place to add users?

I am less familiar with what Azure offers, but other cloud providers offer a way to manage users external to the VMs the provide (normally IAM permissions).

I would not bake user into the system but look for an external way to manage them. This allows you to more easily remove users that leave your company or add new users that join.

If Azure doesn't provide a way I would look at setting up Active Directory or LDAP to manage user permissions to hosts. But I would be shocked if you needed to do this.

Note: Don't confuse infrastructure and data. Users are data, not infrastructure. Data (ie adding a user) should be able to change without changing the infrastructure. If you need to remove a user you do not want to rebuild your whole infrastructure.


Artifactory vs Git for Infrastructure Version Control / Configuration Management

This is a simple thumb rule one could follow

Use version control (git, svn, cvs) for the work product created by humans
Use artifact management tool (artifactory, nexus, apache archiva) for the software bundle (artifacts) created by the system thru build or packaging process

HUMAN           ==>            System
GIT/SVN  (build/packaging)     artifactory/archiva


Is it possible to build docker images using docker-compose concurrently?

Yes, it's possible. You can use --parallel option since docker-composer 1.23.2 version.

Version 1.23.2 also correct 1.23.0 bug:

  Reverted a 1.23.0 change that appended random strings to container
  names created by docker-compose up, causing addressability issues.
  Note: Containers created by docker-compose run will continue to use
  randomly generated names to avoid collisions during parallel runs.

https://github.com/docker/compose/releases/tag/1.23.2

You can use it simply doing:

docker-compose build --parallel


What is the future of DevOps in the age of serverless?

Also serverless needs some infrastructure and for that you also need software components to develop and rollout.

Beyond yet another website or application server I'd also think of energing advanced ecosystems related to:

Internet of things -  embedded systems and edge servers
Artificial intelligence and data engineering in distributed systems. Could be some ETL (extract, transform, load) stuff or training and logistics for machine learning models.
Gaming but also working in virtual environments.

So given the cloud market and these ecosystems will grow,  even if servetless would dominate, there will be a DevOps market, maybe smaller than now.

Otherwise it is in general very hard to predict how (IT) world and job market might look like in say 20 years.


You don't need to be a privileged user (in your local machine) in order to execute Ansible playbook.
When using become, Ansible allows you to ‘become’ another user, different from the user that logged into the machine (remote user).
For more details see Understanding Privilege Escalation
In your inventory of hosts /etc/ansible/host you have specified a group of IPs with root user while you are specifying a remote_user: ronenal in your playbook.
So you need to run ansible-playbook with --ask-become-pass or -K.


Can an in-memory filesystem be created from inside a docker container with no special permissions?

Kubernetes can mount a ram disk for you. The answer is right there in the standard RTFM guide.

https://kubernetes.io/docs/concepts/storage/volumes/#emptydir

Create an emptyDir volume and set emptyDir.medium to "Memory" to build, what I interpret from the documentation to be, a dynamically sized memory file system which counts against the containers memory limit.

If you're not running under kubernetes, whatever system that deploys the docker container would need to create the ram disk and mount that into the container, or give the container the special permissions discussed in the various reference articles in the question.


Continuous deployment of package to virtualenv

Using a shared virtualenv for automation while also expecting the virtualenv's content to be (automatically) updated without the automation's knowledge/control is not a good practice - opening up for all kinds of obscure/intermittent/hard to reproduce failures.

So I wouldn't spend too much time trying to figure out a solid way of updating your package in the shared virtualenv without hitting the automation jobs - sooner or later they'll be hit by other problems stemming from the same root cause - using a shared virtualenv. Think back at the very reason(s) for using a virtualenv in the first place.

For consistent results automation should ensure that the virtualenv content is updated as needed as a preliminary step and does not (unexpectedly) change while the job is performed. Which isn't really possible with a virtualenv shared across multiple independent automation jobs. It might be possible with coordinated jobs, all sharing a common step that performs the virtualenv updates in a controlled manner to ensure virtualenv's consistency during jobs, but IMHO it's just not worthy to build such complex system, it's much simpler to not share the virtualenv and keep the jobs independent.

If, regardless of these considerations, the request for a shared virtualenv still stands then don't update the virtualenv outside (well defined and announced) maintenance windows during which execution of the automation jobs should be suspended.

As a side note it's also not a good practice to not version your packages, unless maybe if you have a very clear and easily accessible indication of the exact code version being used in each particular case (the commit SHA for example) - when problems occur you'll most likely need that info when attempting to reproduce the problem, debug it and/or verify fixes with some degree of certainty.


I see a mismatch between the problem you describe and the solution you're asking for.  Your problem seems to be managing your environments.  You seem to think automated testing is the answer.

But why not automate managing your environments to prevent the manual effort that goes into fixing them?

It's very important to reset test environments to a known good state before running automated tests.  Without a reset, it takes effort to figure out if a test failure is due to code changes or environment changes.  It's about the same effort as manually fixing the environment in my experience.

There are many approaches for creating or resetting test environments.  Probably it's a too broad question and a matter of opinion.

Once you have a repeatable way to provide a known good test environment, there are many tools for automating regular test runs and emailing results.  Probably it's a too broad question and a matter of opinion.


How do I automate the process of pulling the latest code and restarting a service on git push?

There's no "easiest" way per se, there's the better way for you.
I'd recommend using a configuration management tool like Chef or Puppet (for a pull model) for which there's already resources to configure and handle logstash restarts.
That said logstash is able to watch its config file and reload it itself, quoting elastic.co documentation:

Starting with Logstash 2.3, you can set Logstash to detect and reload configuration changes automatically.
To enable automatic config reloading, start Logstash with the --config.reload.automatic (or -r) command-line option specified. For example:
bin/logstash –f apache.config --config.reload.automatic

So you may just set a crontab to git pull your repository periodically and have logstash reload itself.


I'm trying to run `vagrant provision` on PowerShell Window for Ansible playbook

You have 2 viable options to run ansible on windows 10:

Install a linux vm with your favorite virtualization tool and run ansible inside that vm.
Run ansible from WSL

With the first option, you will need to install vagrant inside the vm + all virtualization tools needed.

With the second option, you will then need to install vagrant in WSL as well and configure it to access your windows environment.


What is the optimal size of a Jenkins Pipeline Stage?

Single responsibility principle (SRP)

  Martin defines a responsibility as a reason to change, and concludes
  that a class or module should have one, and only one, reason to be
  changed (i.e. rewritten). As an example, consider a module that
  compiles and prints a report. Imagine such a module can be changed for
  two reasons. First, the content of the report could change. Second,
  the format of the report could change. These two things change for
  very different causes; one substantive, and one cosmetic. The single
  responsibility principle says that these two aspects of the problem
  are really two separate responsibilities, and should therefore be in
  separate classes or modules. It would be a bad design to couple two
  things that change for different reasons at different times.

  The reason it is important to keep a class focused on a single concern
  is that it makes the class more robust. Continuing with the foregoing
  example, if there is a change to the report compilation process, there
  is greater danger that the printing code will break if it is part of
  the same class.

5-15 lines

  Functions should normally be short, between 5-15 lines is my personal
  "rule of thumb" when coding in Java or C#. This is a good size for
  several reasons:

  It fits easily on your screen without scrolling
  It's about the conceptual size that you can hold in your head
  It's meaningful enough to require a function in its own right (as a standalone, meaningful chunk of logic)
  A function smaller than 5 lines is a hint that you are perhaps breaking the code up too much (which makes it harder to read /
  understand if you need to navigate between functions). Either that or
  your're forgetting your special cases / error handling!

Personal view

I have the SRP in mind when creating Jenkins stages. This implies that I create a separate stage for checkout, build and publish for example. If a stage becomes too large, i.e. longer than 15 lines, then I create a script and run the script in this stage. One of the benefits is readability, possible to apply unit testing on the script and CI agnostic, i.e. migration to another CI would be possible as well.

Example

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                echo 'Building..'
            }
        }
        stage('Test') {
            steps {
                echo 'Testing..'
            }
        }
        stage('Deploy') {
            steps {
                echo 'Deploying....'
            }
        }
    }
}


Unable to launch multiple EC2 instances in different availability zones using terraform

It looks like you're using the wrong brackets? I think you need to use a list:

variable "azs" {
  description = "Run the EC2 Instances in these Availability Zones"
  type = "list"
  default = ["us-east-1a", "us-east-1b", "us-east-1c"]
}

Source


Open source private cloud VM provisioning for container workload

"best suited" is the question. How do you measure this? what are the metrics and why do you choose them? I think you are looking for some kind of "tools combination", earlier tested on production by someone else's if preferred. What you want to do is try some opensource/free private cloud on-premises and run IaC on this private environment. You can test tools forever. How do you compare those tools? I believe all of them works fine as long as there is not any inconsistency problem. I think there is a missing/main part in your search when it comes to IaC. Because of few options for that missing angle as well. I think it is better to create a chart for all of us as you are going this process in order to benefit people here. Do you have a working environment? If so could you please detail all the tools you used to create this environment?

Some vendors run open source projects. How about them?

The Cloud Native Computing Foundation seeks to drive adoption of this paradigm by fostering and sustaining an ecosystem of open source, vendor-neutral projects.CNCF Cloud Native Definition v1.0

I started to wonder if this is cloud-native then what is it that is not cloud-native?

I think this is what you are looking for. The distinction between provider and provisioner is blurred. A workflow automation tool should be doing what cloud orchestrator with GUI does. Terraform makes a distinction between provider and provisioner but Cloudify removes them as I see it. For an architect designing the whole workflow with GUI might be useful to reach the desired state. Writing desired state for which you do DRY tests already beforehand or showing with graphs. There is something you know already where it goes since you already tested, seeing it flowing in graphics workflow makes sense? Then go for it. To me it is painting the history I do not see the benefit.

There are many ways to break down the types of automation, whether it’s imperative versus declarative, or orchestration versus desired configuration state.

Most orchestrators are fully CLI based, or offer very limited GUI operations.
A distinct advantage here is that Cloudify enables you to one-click your way through architectural relationship diagrams. See: Terraform vs. Cloudify.

Providers

A provider is responsible for understanding API interactions and exposing resources. Providers generally are an IaaS (e.g. AWS, GCP, Microsoft Azure, OpenStack), PaaS (e.g. Heroku), or SaaS services (e.g. Terraform Enterprise, DNSimple, CloudFlare).
See: Providers.

Provisioners

Provisioners are used to execute scripts on a local or remote machine as part of resource creation or destruction. Provisioners can be used to bootstrap a resource, cleanup before destroy, run configuration management, etc.
See: Provisioners.


Devops CICD run ReactJS application while testing with jest + puppeteer

I switched to using a production build for testing by use of a local webserver. I leveraging the [jest-puppeteer][1] library which allows you to start a webserver with your tests.
jest-puppeteer.config.js
/**
 * find all flags at the following site @jkr
 * https://jestjs.io/docs/en/cli
 */

module.exports = {
    launch: {
        devtools: true, // allows for use of 'debugger;' in tests
        // executablePath: '/usr/bin/chromium-browser',
        headless: true,
        defaultViewport: {
            width: 1024,
            height: 768,
            //isMobile: true,
            //hasTouch: true,
        },
        ignoreDefaultArgs: ['--disable-extensions'],
        args: [
            '--enable-font-antialiasing',
            '--font-render-hinting=medium',
            '--disable-gpu',
            '--disable-dev-shm-usage',
            '--disable-setuid-sandbox',
            '--no-first-run',
            '--no-sandbox', // GOOD
            '--no-zygote',
            '--single-process', // GOOD

            "--renderer",
            "--no-service-autorun",
            "--no-experiments",
            "--no-default-browser-check",
            "--disable-extensions",
        ]
    },
    server: { // launches webserver just for tests @jkr
        command: 'npm run test:webserver'
        // cd build && ../node_modules/local-web-server/bin/cli.js --port 3000 --spa index.html
    },
    browser: 'chromium',
    browserContext: 'default'
};

.gitlab-ci.yml
image: node:10.19.0 # https://hub.docker.com/_/node/
# image: node:latest

cache:
  # untracked: true
  key: my-project-name
  # key: ${CI_COMMIT_REF_SLUG} # per branch
  # key:
  #   files:
  #     - package-lock.json # only update cache when this file changes (not working) @jkr
  paths:
    - .npm/
    - node_modules
    - build

stages:
  - prepare # can install ci-deps here ? @jkr
  - test # uses test:build specifically @jkr
  - build
  - deploy

# before_install:

before_script:
  - npm ci --cache .npm --prefer-offline #
#   # - apt-get update && apt-get install -y lftp gconf-service libasound2 libatk1.0-0 libatk-bridge2.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget
#   - if [ ! -d "node_modules" ]; then set NODE_ENV=dev && npm install; fi # make sure dev dependencies are installed todo: 'if' needs to be verified working @jkr
#   # - npm install
#   # - if [ ! -d "build" ]; then npm run build; fi

prepare: # could this job be in a before_script for test ? @jkr
  stage: prepare
  script:
    - npm install
    - npm run build:test
  # cache:
  #   paths:
  #     - node_modules
  #   policy: push

test:
  stage: test
  script:
    - npm run test:ci-deps
    - npm run test:e2e # runs puppeteer tests @jkr

build:
  stage: build
  script:
    - npm run build
  # artifacts:
  #   paths:
  #     - build

deploy-ftp:
  stage: deploy
  script:
    - lftp -e "open ftp.my.domain.com; user $MJA_FTP_USER $MJA_FTP_PASS; mirror --reverse --verbose build/ /var/www/domains/dev/projects/my-project/build/; bye"
  environment:
    name: staging
    url: http://my.domain.com/my-project/build
  when: manual
  only:
    - dev


The very first thing to know about a container is:

It is, first and foremost, a process.

Once that is understood, one can start to understand how containers compare and contrast with virtual machines.  Containers and VMs both share isolation from their hosts.  The method of isolation is the critical difference.

Container processes use extensions to the OS kernel host on which they run to isolate themselves from other processes.  Other extensions also provide disk and resource isolation.  Containers share their kernel and memory with the host OS.

Virtual Machines use a hypervisor to isolate VMs from their hosts.  This is a layer of software that forwards requests for resources from "guests" (VMs) to the hardware.  Disk isolation is provided by disk virtualization.  VMs do not share a kernel with the host- they load their own kernels into memory space dedicated to the VM.

One important impact of this difference is that a container must be kernel-compatible with its host.  For example, it is not possible to run a Windows Nano Server-based container on a Linux host, or an Ubuntu container directly on a Windows host.  Virtual Machines, by contrast, can run any kernel regardless of host OS.  When running a Linux container on a Windows host, Docker runs the container in a Linux VM.

The operational differences are in agility: containers start and stop about as fast as a normal process.  VMs are "heavier," requiring dedicated resources set aside for them and take longer to start and shut down.

Containers offer a lot of flexibility to a DevOps operating model:

Containers isolate software component dependencies.  Developers can use containers to guarantee that an application module will function as well on their development machines as in QA/UA/Production
Containers use software-defined networking to communicate
Container definitions are declarative and can be source-controlled
Container management systems (Kubernetes, DC/OS, Swarm) can manage hardware resource (compute/RAM/storage) pools and dynamically scale containers


How to have Ansible move a microservice?

I have created a demo with a role that can install many springboot microservices on a fleet of VMs where you name a subset of the VMs where you want to place each service. The playbook can then run on all hosts, compute whether each service should be on each host, and will either run the install.yaml or uninstall.yml tasks.

To install two of the same microservices with different runtime args you play something like:

roles:
    - {
      role: "ansible-role-springboot",
      sb_app_name: "microservices-registration",
      sb_app_group_id: "org.springframework.samples.service.service",
      sb_app_artifact_id: "microservices-demo",
      sb_app_version: "2.0.0.RELEASE",
      sb_app_run_args: '"registration 8082"',
      sb_app_healthcheck_urls: [
        "http://localhost:8082/actuator/health"
      ],
      sb_hosts: [
        "my-test-vm"
      ]
    }
    - {
      role: "ansible-role-springboot",
      sb_app_name: "microservices-web",
      sb_app_group_id: "org.springframework.samples.service.service",
      sb_app_artifact_id: "microservices-demo",
      sb_app_version: "2.0.1.RELEASE",
      sb_app_run_args: '"web 8083"',
      sb_app_healthcheck_urls: [
        "http://localhost:8083/actuator/health"
      ],
      sb_hosts: [
        "my-test-vm"
      ]
    }

The role is based upon orachide/ansible-role-springboot which seems very comprehensive. The new bit is in bold which is simply a list of host that should run the microservice.

Normally we would expect to use different artefact ids and versions each time we apply the role. In the example above, it is running an official springboot microservices mega jar that takes different RUN_AS args to run as different services. That seems a bit odd and not something I would recommend yet the role is agnostic to such details.

What thing that the original role requires is that you use an executable jar file:

        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <executable>true</executable>
            </configuration>
        </plugin>

It role will create a symlink to that executable and create an environment files to run it and all that good stuff.

The modifications that I made were quite simple as the original role has logic to install or uninstall based on sb_app_state:

- import_tasks: install.yml
  when: >
        sb_app_state == 'present'

- import_tasks: uninstall.yml
  when: >
        sb_app_state == 'absent'

So it was simply a matter of adding some logic to check whether the current hostname is in the sb_hosts list then update the value of sb_app_state as appropriate. That is done with a single line change.

The demo codebase uses test kitchen ansible with testinfra to unit test that the playbook works. Getting that working was well worth the effort to do automated acceptance tests of the playbook logic.


What are known efforts to establish DevOps ontology model?

According to Wikipedia, the first reference you linked,

  In computer science and information science, an ontology is a formal naming and definition of the types, properties, and interrelationships of the entities that really or fundamentally exist for a particular domain of discourse. It is thus a practical application of philosophical ontology, with a taxonomy.

The problem with developing an Ontology Model to define the terms of DevOps is that DevOps encompasses multiple domains and these domains can often have overlapping or contradictory terminology.

In fact, sometimes even within a domain there will be conflicting terminology. So it is difficult enough to establish a standard for a single domain, let alone multiple domains.

As such, it is doubtful there will be any attempt (or at least successful ones) to establish formal ontology rules for DevOps any time soon. (And it would have to start with formally defining DevOps first, and so far we have had trouble even making that clear).


How to capture tools release to trigger upgrade?

From your list of tools:

Jenkins and Github have apt/yum repositories you can use to install and upgrade.

For Atlassian products, best up to date information about repositories I can found is This ShipIt experiment and it seems unlikely to change from this forum post
The workaround may be parsing the mailing list to update the deploy.

Now if you really want something automated to handle the installation and configuration of your tools, you can try a Configuration Management System like Chef/Puppet/Ansible/Salt.

For Chef I know better, there's cookbooks for Jira and Confluence maintained.
For the rest you'll be on your own writing the bits to deploy and configure.

This means having 4 CI/CD systems (at least), two 'groups' validating each other, as a pipeline won't be able to validate and upgrade itself properly (inception). That sounds overkill in my opinion.

At the end of the day, there's no silver bullet for all and every software you may use, each will have its own particularity and way to be installed and you'll have to workaround those bits.


There is a Quotas page in the GCP console.  This Google help doc will tell you more and how to go about identifying your limits and increasing your quotas: https://cloud.google.com/compute/quotas


Ansible authorized copy from remote source to remote destination

To append id_rsa.pub of a specific user from a remote ssh ServerA (no the controller machine ) to ServerB.

1) Fetch the public keys from ServerA

- host: ServerA
  vars:
    public_keys_dir: <PUB_KEYS_DIR>
    specific_user:
      - user1
      - user2
      - userN
  tasks:
    - name: Fetch pub keys
      fetch:
        src: "/home/{{ item }}/.ssh/id_rsa.pub"
        dest: "{{ public_keys_dir }}/{{ item }}-ServerA.id_rsa.pub"
        flat: yes
      loop: "{{ specific_user }}"

2) Configure authorized keys at ServerB

- host: ServerB
  vars:
    public_keys_dir: <PUB_KEYS_DIR>
    my_remote_user: admin
  tasks:
    - name: Set up authorized_keys
      authorized_key:
        user: "{{ my_remote_user }}"
        key: "{{ lookup('file', '{{ item }}')}}"
      with_fileglob:
        - "{{ public_keys_dir }}/*-ServerA.id_rsa.pub"

(not tested)


Service for hosting native JavaScript ES modules

Have you considered CDNjs.com:

It supports CORS headers, it is dedicated to JavaScript after all.
It supports HTTP/2 as well as SPDY.
The cache duration is 355 days, which is probably plenty long enough.
Cloudflare is used as the CDN, they provide it to cdnjs.org for free.

Adding your library is a bit more than a one-liner unfortunately as you need to submit a pull request to their GitHub repository.  You will also need to have a certain popularity requirement:

  For the new library request issue, please make sure it's not a personal project, we have a basic requirement for the popularity, like 200 stars on GitHub or 800 downloads/month on npm registry.


How to handle AWS Offsite or cross-account RDS (mysql) backups?

On top of protecting your root account as best as you can, you should be able to reduce the risk of such resource deletion if you have more than 1 resource to protect.

For example if all AWS resources you had to protect were 2 RDS database servers, you could create 2 other accounts that have access to only copy the snapshots of one of your database servers each - and no other access to any other resource. This setup would then require an intruder to hack both root accounts of your main and one backup account each, which should be significantly more difficult.

To copy snapshots from one account A (your current RDS account) to account B (your new account) you should need the following parts  (untested)

Create a new IAM role in Account A, for access from account B:

Create a new policy for reading RDS snapshots from account A

{
    "Version": "2012-10-17",
    "Statement": [
        {
        "Effect": "Allow",
        "Action":
            [
                "rds:CopyDbSnapshot",
                "rds:DescribeDbSnapshots"

            ],
        "Resource": "arn:aws:rds:::"
        }
   ]
}

and assign it to the IAM role

Check that the "trust policy" is enabled as described in this walk through for another cross account action: https://aws.amazon.com/blogs/database/setting-up-for-cross-account-native-backup-and-restore-in-amazon-rds-for-microsoft-sql-server/
Then in account B, you should be able to run copy-db-snapshot from account B: https://docs.aws.amazon.com/cli/latest/reference/rds/copy-db-snapshot.html
To automate, I prefer to use Lambda functions, which can simply call AWS API calls, you can trigger them with a Cloudwatch Event


azure activity log, how to find releases

Activity Logs can only able to show the resource level logs like creating a resources,deleting a resources modify the SKU of the resources etc,

Assuming from your question you are saying web app deployment from azure devops,which is more like a deployment of code to an existing webapp which will not be covered by activity logs. You need to go to that azure app service then you can that deployment details in Deployment Center


Should I use release branch to push my changes?

What is the recommended practice?

The book ”Accelerate” by Forsgen, Humble and Kim documents their research that teams that use fewer long-lived branches are more successful.

The question is then what is the best minimum set of branches for a given team. The answer to that, like many things, is ”it depends”. A team that pushes into production a dozen times a day will prefer tag then release from master. A team that releases once a sprint into an integration test environment for a week before it goes live will generally prefer two branches.

  Should I use a release branch to push changes out to production or release it off master branch

My personal experience is that adding branches later if you need them is easy but removing branches is very hard. So given that we want to minimise the number of branches I recommend that small teams who release often always release from a tag applied to master. It's very easy to create a branch from the tag that was last put live if you do need to create a short-live patch release branch. The point is that you want that to be the exception not the rule give the research in the book named above.

I have seen many teams use a two branch approach. To common ones are:

Integrate code into a ”develop” branch and deploy to an integration test environment. Then cherry-pick signed-off work down to master where it is tagged to release.
Integrate code into ”master” and deploy into a test environment. Then cherry-pick signed-off onto a long-lived ”release”  branch where it is tagged to released.

These approaches are actually identical. The reason to take this “two branches” approach is so that features can be released independently and reordered.

  Not to mention, there is still some amount of manual testing and that happens on the master branch after developer has completed the changes in feature branch and automation testing, code review is completed and changes are merged to master.

There isn’t really enough information in your question about how your team actually works to know whether a one or two branch strategy would be a good fit. Your actual release, testing and support ways-of-working dictate the best strategy for your team.


How to develop a docker container for laravel without laradock or docker-compose

Yes.  You could create each component of your development environment using containers and manually network them together.  This approach would require you to manually start each container and specify the network and volumes they use at runtime.

However, you are adding un-needed complexity by avoiding docker-compose to network your containers together.  By using a compose file you can start your environment with a single command: docker compose up.  In the approach outlined above, you would need to manually re-create the containers every time you wished to recreate the environment.

Laradock's website has some simple getting started guides that can get you up and running without a full understanding of Docker.  While the learning curve may be steep, it can be beneficial to avoid re-implementing a viable solution.


Unregister a VM within VMware Fusion from command line

There doesn't seem to be a "proper" way of unregistering a virtual machine sadly.

I went around this by stopping the virtual machine using vmrun in Fusion, deleting the source folder of the VM, and restarting Fusion so that the application registers that the VM is not there anymore.


Can we use Ansible for monitoring configuration?

The simple answer is "yes" you can use Ansible for monitoring configuration, but you will have to do some extra work. As Vasily stated in their answer, Ansible does not have a built in triggering mechanism, so you need something to trigger the convergence of state. This can be done in several ways, the easiest being probably ansible-pull. As the docs state, ansible-pull

... inverts the default push architecture of ansible into a pull architecture, which has near-limitless scaling potential.
The setup playbook can be tuned to change the cron frequency, logging locations, and parameters to ansible-pull. This is useful both for extreme scale-out as well as periodic remediation.

emphasis added.
Ansible is idempotent, so it does know about the state of target machines, contrary to what Vasily's answer states - it just doesn't persist it in the same way as Terraform does.
Your real problem does not sound like the question you are posing ("Can Ansible be used to ensure the state of a machine?"), but rather "how can I detect configuration drift and trigger a remediation?"
If you think of this as a monitoring problem, you can reframe the question as "how should I monitor my services in production?". Monitoring implies alarms on changes in state, which trigger actions to remediate. In your case, you would define an alarm on the health check of the service, when that is triggered, execute the playbook which converges to the desired state.
Since you have already invested time in writing the Ansible playbook, it would make sense to re-use it. The simplest would be to use that same playbook to invoke a cron which runs ansible-pull every 5 minutes or so, depending on your particular case.


How can a Windows server be a slave to Jenkins running on Linux when there in an error installing the slave-agent.jnlp file?

You have two arguments that are empty:

<application-desc main-class="hudson.remoting.jnlp.Main">
  <argument>32ba31ca5f150c2b3491802b0b60e56574d970a9e601cebad656a113fe325a85</argument>
  <argument>FQDNofWindowsSlave</argument>
  <argument>-workDir</argument>
  <argument/>
  <argument>-internalDir</argument>
  <argument/>
  <argument>-url</argument>
  <argument>http://FQDNofJenkinsServer:8080/</argument>
</application-desc>

Your error message has a comma in it:

  BadFieldException[ The field  has an
  invalid value: ,]

Other bad argument error messages on the internet have comma separated lists of bad arguments:

  BadFieldException[ The field codebase has an invalid value:
  $$codebase,$$codebase]

So I'd guess those two empty arguments are the problem.


How do I install Terraform libvrit_cloudinit?

Try to use libvirt_cloudinit_disk instead of libvirt_cloudinit. I think it is deprecated.


Find most popular images with `zip` and `git` on Docker Hub

I can answer half of your question: If you have a set of images you're trying to investigate, the best way would be to use which in a new container using the image in question. This way you can quickly see if a particular image has the binaries your are looking for already on PATH:

docker run --rm ubuntu:latest which zip git
# no result

docker run --rm ubuntu:latest which bash sh
/bin/bash
/bin/sh
# ^-- both bash and sh are in the image

I don't know of a way to discover the set of images in question, as there is no manifest of files that a registry will provide. That is, yes, an image is a set of tar files, which you can extract a set of files/directory names... however, you'd still need to pull the entire image to get this information, so it would be easier to run the which command above.

There are tools for exploring information that a registry exposes (skopeo, doocker-ls, reg, manifest-tool, etc) but none of them will do exactly what you're looking for, which is "find a repository within a registry which contains an image that has a particular binary in it".


How much memory/cpu to allocate per pod?

It's a severe problem to solve if you don't know the performance characteristics of the process you are containerising.  There are a couple of approaches you could take that will get you an answer, although you will need to monitor it carefully in production and an adjust the resource limits as required.

Approach #1: Educated Guess - take a look around at what other people have done to host a specific process, GitHub is an excellent resource for finding Dockerfiles and their associated Helm Charts.  Equally, if someone has done some tests for Virtual Machine sizing, you may be able to derive an answer that is acceptable in the short term.
Approach #2: Testing - my personal preference is to test the component in question:

The Apache Bench is excellent for quick performance tests against HTTP(S) endpoints
Tools such as the MySQL Benchmark tool allow you to test MySQL, many applications have dedicated benchmarking tools.
If the software is more complicated you can use tools such as Artillery or Gattling to create a performance test suite that you can use to slam the container and find out how it performs.

Whichever approach you take, you will need to make sure that you have a proper monitoring and dashboarding solution working so that you can actually analyse the behaviour of the containers under load and adjust accordingly.


Programmatically scrape the latest version of Tomcat for an installation script

I've created a couple crude methods of grabbing the latest major versions of releases, as well as absolute latest.

# Grab Latest Tomcat 7
curl -i https://www-us.apache.org/dist/tomcat/tomcat-7/ | grep -Po '(?<=(v)'

# Grab Latest Tomcat 8
curl -i https://www-us.apache.org/dist/tomcat/tomcat-8/ | grep -Po '(?<=(v)'

# Grab Latest Tomcat 9
curl -i https://www-us.apache.org/dist/tomcat/tomcat-9/ | grep -Po '(?<=(v)'

# Grab Latest Tomcat
curl -i https://api.github.com/repos/apache/tomcat/tags | grep '"name"' | head -1 | egrep -o "([0-9]{1,}\.)+[0-9]{1,}"

It's a bit of a hack where I'm looking for text in-between two values on a web page to grab the version number. It's crude and I'm sure there's a more elegant way to grab this, but this what I was able to figure out with my skillset! Maybe it can help someone in the future, but if anyone has better ideas I'm all ears.


How to parse command output (docker log) through goaccess?

What do you mean by "it doesn't work"? I got an error suggesting that the log format wasn't correct:

Fatal error has occurred
Error occured at: src/goaccess.c - set_curses - 1394
No time format was found on your conf file.

When I edited /etc/goaccess.conf (i.e. uncommented/selected time-format, date-format and log-format) the docker logs mycontainer | goaccess - command works as expected.

As an aside, for my nginx proxy inside my docker container, I had to set my log_format as follows:

log-format %v %h %^ %^ [%d:%t %^] "%r" %s %b "%R" "%u"


Best practices for app and infrastructure code repositories

The correct answer, like almost everything in IT, is, "it depends." It depends on the way you work, the type of company you are working for, your requirements, your non-functional requirements, and possibly a lot of other factors.
tl;dr -- read the final section, it's the most important.
Layers
In this, admittedly long answer, I'll talk about the 3 layers of an organisation's IT operations -- infrastructure, platform, and application. These 3 layers are blurred at the boundaries and there is a continual debate about their delineations, but if you're not familiar with this model, roughly:

Infra: machines and VMs, security and resource groups, auto-scaling groups and elastic load-balancers -- stuff you typically provision with Terraform
Platform is Kubernetes, OpenShift, IIS, etc. -- stuff you typically provision with Packer, kubectl, or helm (and, this is the first blurring, because EKS, AKS, GKE, are often provisioned with terraform too)
Application is the business logic and software that runs your business, confusingly this is also often provisioned with kubectl or helm, and possibly packer if you're into the wonderful immutability model

Monorepos
I think the question you're asking relates to the concept of 'monorepo', where all the code needed to build and deploy your application is contained in a single repo and versioned together. In this answer, I'll mainly address the benefits, techniques, and drawbacks of monorepos, though you don't have to go deep into monorepo culture for this to apply, simply maintaining a single version for all your application, infra, and platform will have the same effect.
When making your decision you need to factor in whether you are working with an app per cluster, as is becoming more common in modern K8S systems, or a shared cluster. Another factor is which team owns the various layers of the architecture and how they will distribute their output.
Teams & Architecture
My experience comes mainly from large banks. In these organisations, we have hundreds (even thousands) of development teams and it is impractical and inefficient to expect each team to develop its own infrastructure and platform layers as well as their application. Distributing this effort to each team would be a governance and compliance nightmare and hiring that many people with the right skills would be impossible.
Instead, we have centralised teams for infra and platform, and they distribute their output to the development teams and we typically work with the cluster-per-app model. In modern orgs we work with a cross-functional team that has some skills in each of the areas we need, including DevOps, and each team member is also a member of a group that is focused on their speciality where they receive groupwide instruction.
We have 2 main models to provide access to the output of the centralised infra and platform teams:

The infra and platform teams can provision clusters on behalf of a dev team and provide the pipelines needed to deploy applications to it. This works well when a team has little or no DevOps capability, but it is far from being the best solution as it creates a dependency from the dev team to the infra and platform teams which usually causes impedance and added complexity.

The infra and platform teams can provide access to their git repos, and the dev teams can fork them into git submodules within their own mono-repos. This model is by far the most common and currently represents the best solution for highly-regulated industries. One of the biggest benefits here is that a dev team can make any changes they need to make to the infra and platform and issue pull requests for the respective teams to manage, without having to coordinate the schedules of the teams and thus reducing impedance.

Both solutions have their problems and complexities, but both are manageable given good engineering leadership and tool support.
Solution 1 would require separate repos for infra, platform, and app, and this usually results in a need to synchronise the backlogs of the respective teams, which quickly becomes a logistical nightmare as the number of teams increases. Solution 2 would require the implementation of 'initial trust' base infra with something like Open Policy Agent (OPA) rules to ensure that dev teams are complying with organisational governance requirements (e.g. verifying that a dev team isn't running a bitcoin mining operation, or publishing pro-trump/fascist/racist propaganda to our public-facing websites). OPA is an amazing tool when decentralising responsibility for the lower layers of an app while maintaining central control and I can't recommend it highly enough.
The app per cluster model allows you to use a monorepo that can completely rebuild your app from the ground up with minimal human interaction. The alternative architecture, multi-tenanted, completely disallows the monorepo approach and you must have separate repos for each of the layers.
Versioning & Configuration Management
The benefits of a monorepo are manifold, but one of the major benefits is having a single version for all layers of your application. One common problem in IT is called Configuration Management -- I refer here to the ITIL meaning, where we talk about which version of what software/hardware work together, rather than the folk-meaning which relates to configuration files.
This is such a hard problem to solve that many books have been written on the subject and ITIL has an entire discipline dedicated to it. Many of the larger banks I have worked for have entire departments dedicated to this discipline and to do it right usually requires the Enterprise Architecture department to keep continually updated models of every component and relationship in an organisation's entire IT estate.
The configuration management problem is largely solved with a monorepo. You'll never hear anyone say "I tried to deploy your software but you've written a helm 3 chart and our cluster only has helm 2 installed," or, "we patched the OS with the latest security updates and your application crashed." With a monorepo, as long as you have sufficient testing in place, your helm version will always be in sync with your helm files and your software will have always been tested with the latest security patches.
Configuration files
I think the OP mentioned config files in one of the comments so I'll address that briefly here too.
If you are building software that a client will run, then configuration files per client or installation are often necessary. In all other cases, they are not needed and should be avoided. Service discovery should be the responsibility of a service-mesh (my preference is Consul), not a configuration file. Secrets should be provided via dynamically generated properties files housed in an in-memory file-system only accessible to a single instance of your service. All other 'configuration' data should be managed by the platform, and it should be exactly the same for every environment. The days of placing the database name and port, and the database credentials, in your database.properties file were over a long time ago and you should move on now.
It isn't always possible to completely avoid configuration files. Where this is the case the files should preferably be 'owned' by the environment layer, not the application layer. These can be used to enable/disable platform services and control feature flags so as to customise a platform for your team's needs. These should mostly be interpreted by the deployment mechanism to ensure that only the things you actually use are deployed, rather than having things enabled/disabled at runtime, which is a big security no-no. You could use these configurations to down-scale a test environment so that its not as large as a prod environment, or to scale one up for load testing, or even to deploy to a less than six-sigma HA configuration for basic dev work.
Application-specific configuration is considered by many to be a code smell. It is often used to reference database names, ports, and the like. Your app should run in a container and should always run on port 80, so that doesn't need to be configured. Your database should always have a meaningful name and service discovery (DNS) should route you to the appropriate instance for your environment. Your memory and CPU constraints belong to the container, which is in the platform layer, not the app layer. You may have some truly app-level configuration points but that normally only true where you are deploying many instances of your apps for different clients (even if they are in your own organisation), in which case these are probably ok, but even then you should work on deriving them from the context in which you app runs, rather than hard-coding them in a config file unless absolutely necessary.
Environments
Another major benefit from the monorepo approach is that you gain the ability to 'print' new environments. With an application that is designed to take advantage of this (autoscaling, auto-healing, service-mesh, etc.) this will allow you to have a test environment that is 100% aligned with your production environment. Further, if time-to-market is a prominent enough factor of your business plan, you can spin up multiple test-environments and run your tests in parallel rather than sequentially.
This also means that developers can have a production-like environment to experiment with whenever they need one. They simply have to run the provisioning scripts for the app and away they go.
Of course, there is a cost to 'printing' environments and not everyone has the unlimited resources of a major bank to fall back on, so this capability must be managed, but if you engineer your environments to be automatically torn down when they're not being actively used then you will go a long way towards reducing these costs. OPA rules can also be used to ensure that boundaries are not overstepped and costs are managed efficiently without human interaction.
Team Dependencies
Personally, I believe that the major factor in the productivity of individual teams is the relationships they necessarily have with their peers in different layers. If there are 300 dev teams, an infrastructure team will be continually inundated with requests for changes that must be understood, managed, prioritised, and scheduled -- this is a major effort in large orgs and can leave a team waiting months, or longer, for changes that support their needs, leading to project delays.
There are no winners here -- if the centralised team is working on your problem then they're not working on someone else's, so either you are delayed or the other 300 teams are. It is a lose/lose situation and it simply does not work well at all. Monorepos with git's submodules (or similar structures) help fix this problem. Dev teams can make their own changes to their forked codebase and simply have it reviewed by an authorised representative of the centralised team, and pull requests can be used to manage this process.
Feature Flags
Of course, nothing is perfect. We don't yet have a silver bullet in software engineering and monorepos are no exception -- here be dragons. One fatal but unfortunately common misconception centres around the concept of feature-flags. These flags show what is finished, production-ready, and can be released, and what is a work in progress and should not yet be released to production. Many articles written by engineers suffering from the Dunning-Kruger effect suggest that these flags should be used to ensure that unfinished code should not be executable in a production environment. In reality, these flags should stop code being released to production at all if it is not yet ready. Non-production code should not be in production -- it is a huge security hole if it is released and this must be avoided.
No choice really
As far as I understand it though, the structure of your repos and software architecture tends to follow the structure of the organisation you work for. Ultimately, the deciding factor may not be related to software at all, but instead is related to your organisation's politics and maturity/sophistication/nature. You may experiment with counter-structures, but usually, these experiments fail to gain traction and are destined for the scrapheap.
If your organisation is split into separate teams with separate responsibilities then your repos will be split the same way. If you go for a cross-functional team approach then your repos will tend to be merged. If you just have one big team that's responsible for the success of the organisation, even if it has specialities then you will naturally end up with a monorepo and life will be good.
If your organisation is poorly structured, following the Harvard method espoused by various MBAs, of splitting the organisation into departments and assigning each of them a vice-president and then grouping them whenever there are more than 7 under a senior VP, then your path to working software will be fraught with problems and progress will be slow. I'm not trying to bash MBAs here, it's just that their models conflict with the primary activity of a lot of modern organisations, which is software development, and I feel that they need to modernise their approaches to take into account the opportunities provided by modern technology and big-data, rather than continuing a model that was developed by candlelight.
Wow, this has turned into a bit of a lecture. Sorry, I don't have time to make it shorter, but as I said up-front, this is a complex subject with a lot of variables. The last section is the most important though, so read that first -- it could save you a lot of pain.


What is good and/or bad about Accenture's Multi-speed IT approach to DevOps?

There are reasons different parts of the environment might change at different frequencies.  One example might be a calendaring service, most large organizations have one, they provide information about the current day, if it is a holiday etc.   The calendaring service does not need to change frequently because it provides a stable function.  This calendaring service may be used by many different kinds of apps that also move at different speeds.

Multi speed exists because you need to deal with making changes that deliver value.  Many people indicate multi speed is to deal with the font end system of engagements and the systems of record.  Yes, generally user facing systems change more often because of the desire to update for the end users and experiment with different ways of presenting data to get the best value.  However, the systems of record may need to be changed as fast, in order to satisfy a new business requirement.

If all parts of the application are built using a pipeline with appropriate automated testing, and deployment, and their are ways to test independently but also test together, then any part can move as needed.  It is similar to the gears thought that the different parts move but need to be integrated such they you know they work together as they are deployed.


How to bind ports for docker container in bitbucket pipelines?

Try running with -d detached flag

docker run -td -p 3000:3000 -p 6379:6379 -p 8983:8983 my_dockerhub/image
 #       here ^

Containers started in detached mode exit when the root process used to run the container exits. This will prevent the step to freeze at docker run stage.

Docker docs -d flag


How to copy a file locally to remote pod before it starts?

Ok. Maybe you're not gonna like it but there are some things you can do.

One and most simple is to use a volume mount, eventually on a persistent storage but I think an emptyDir can work as well (or even better depending on the nature of the file you want to copy) and use an init container  to copy the file to the volume before the app container start. I don't know how you generate that file and I can't speculate about the security implications but the file needs to be in the docker image used for the init container. So, for your init container, you will have a Docker file  like

FROM ubuntu
COPY localfile /container/file
CMD cp /container/file /mnt/kube-volume

replacing localfile, container/file and /mnt/kube-volume with appropriate values; you build the container image locally -on your machine, so it can contain the file-  and upload it to the (secure) docker repo along with the app container image.

Another method is to upload the file to a (secure) location and have an init container or a bootstrap process that download the file when you start your main application container  in the pod.

The third option is to create a docker image that contains that file and use it for the app container in your pod.


What is a minimal viable number of hosts for an experimental Kubernetes cluster?

I'd say the minimal viable configuration to test and get a good overview of pod placement would be 5 machines, 2 masters and 3 nodes.
This allows you to play with a master failure, placement of multiple pods "stretched" across the cluster, etc.


Any site to host my little utility script?

Have you considered running this on AWS Lambda. It will probably forever free under free tier. There may be a couple of cents cost on API Gateway.
Otherwise you can rent outdated servers for cents per month,  but I am unsure what the best search term is for that.
Finally,  email addresses are free to generate and you can invest the time to set up a fresh AWS account once per year and run on free tier.


At first, I misread your question, thinking you wanted to run more than one service together, so I had recommended Docker Compose which makes it easy to run multiple services together, with networking, and can even specify the start up order.
But now I see you are just trying to run MySQL, and wondering do you need separate containers for the OS and MySQL: in short, no you don't need two containers. Instead, just get the MySQL image from DockerHub at https://hub.docker.com/_/mysql?tab=description
The reason you can just use that MySQL Docker image by itself is because it already is installed on a Debian image, which you can see in the Dockerfile at https://github.com/docker-library/mysql/blob/master/8.0/Dockerfile where it shows:
FROM debian:buster-slim

So, to solve the problem, do:

docker pull mysql
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag as mentioned in the instructions on the Docker Hub page. Additional documentation at https://github.com/docker-library/docs/tree/master/mysql

I do strongly recommend using Docker Compose (docker-compose command) to run containers, as it makes it easier to organise and run them.


GKE: Sharing the same filesystem across pods

I think it's a pretty n00b question :(

I suppose you'd need a pod which manages the filesystem,
and make it available to the other pods which need the functionality to store data on it...

Br,

S.


Amazon Web Service (AWS): Spot request active followed by cancelled terminating

Seems like the initial limit for instances is set to 1. Solution is to request a limit increase which is not intuitive by the provided instance cancellation.

AWS Service Limits

  You can take the following steps to request an increase for limits.
  These increases are not granted immediately, so it may take a couple
  of days for your increase to become effective.

  To request a limit increase

  Open the AWS Support Center page, sign in if necessary, and choose
  Create Case.

  For Regarding, choose Service Limit Increase.

  Complete Limit Type, Use Case Description, and Contact method. If this
  request is urgent, choose Phone as the method of contact instead of
  Web.

  Choose Submit.


How to avoid an avalanche of images in Openshift when security patches keep coming in?

Get newest tag

How I mitigated it was by creating several bots. The first one uses dip to get the latest version of a specific docker image. E.g.:

go run main.go -image ubuntu -latest "xenial-\d.*"

to get the latest tag of Ubuntu Xenial. If the docker image does not exist in your local docker registry, then it will be pushed.

Update tag in several Dockerfiles

The second bot, updates the tags in the Dockerfiles. If the build is successful then it is merged. Currently an approval is always required, but if it works for a couple of months and the team has enough confidence then an auto merge can be done.

Update orchestration

The third bot updates the docker-compose.yml files, k8s files or whatever orchestration is used. If an approval is done then it will be merged into master. Again if there is enough confidence then this could be automated as well, but I always prefer some manual intervention if production is applicable. Then the team is aware that there was an update and could revert if needed. On the other hand if the monitoring works well then the team will be notified right a way and if updates are done frequently, i.e. at least once every two weeks then the team is trained and knows how to deal with this.


Slave restarts the agent itself after each build? You can use Conditional BuildStep plugin to restart it on a defined condition.


Who is this Chaos Monkey and why did he crash my server?

TL;DR: Chaos Monkey was developed in 2010 at Netflix and released into wild in 2012 is part of the Simian Army, wildly popular among devoted followers. Built on principles of chaos engineering, the army increases resiliency to failure by injecting constant failure to the system.

Concept

Chaos Monkey was developed specifically for AWS where it will randomly kill instances within an Auto Scaling Group. It is meant to run during the business hours when engineers are alert and can quickly react to discovered failures.

Simian Army

Members of the army would sow chaos through other means:

Latency Monkey will introduce random delays to services.
Chaos Gorilla (Kong) will simulate outage of entire availability zone.

Other Monkeys are helpful and remove the weak members of the herd:

Conformity Monkey shuts down instances not following best practices.
Security Monkey looks for known security vulnerabilities in configuration and services.
Doctor Monkey shuts down unhealthy instances not conforming to certain metrics.
Janitor Monkey looks for unused resources to reclaim.

Failure is Inevitable

Failure in the System is inevitable, something will always go wrong. You might not be able to choose what, but you can try to choose when. By introducing small errors throughout the day, you ensure that your engineers are present. By killing non-conforming services quickly, you ensure that failures happen often before deployment. By making the environment more adversarial, you ensure that it will be the developers who run into issues long before any service makes its way into production. Failures will be quickly apparent in integration phase of new services with the old ones, but that is ok, because the old production services are already resilient.

Cattle not Pets

Everyone will tell you lately: Do not treat your servers as pets. There is a power in numbers and any single point of failure will bring down the system. No matter how well you can tune and optimize your server, no matter how beefy hardware you can get, how much it can handle, it will never be a match for herd of small scalable instances. Chaos Monkey encourages you to think about removing all points of failure, because sooner or later, the Monkey will come! Everyone fails and even the Amazon S3 had an unpredictable outage.

Anti-Fragile

So what is the theory and why does it work? Nassim Nicholas Taleb in his book Antifragile describes a concept where living self-aware systems, will benefit from a small levels of randomness and actually become better in face of adversity. This is similar to annealing.

He does also describe an evolutionary way, where fragility of parts in a system is transferring into antifragility of the whole. The transfer occurs on two levels:

By a small random variations - developers making changes - the most fit for the environment will survive and propagate - pass tests and get deployed. Standard Development Life Cycle.
By failure of parts not capable to withstand a larger level of randomness in the environment, the remaining parts that were able to withstand it compose a system that is as a whole better able to deal with changing environment than before. This is essentially Chaos Monkey.

Larger levels of randomness can be withstood using the second approach.


How to add a static slave to Jenkins running in Kubernetes?

Since I'm using Jenkins official helm chart which contains JCasC plugin (Jenkins Configuration as Code), I was able to configure the static slave attachment using it including the creation of relevant credentials.
Here's the relevant section of the values.yaml file I use to install/upgrade the Jenkins helm chart:
JCasC:
    defaultConfig: true
    configScripts:
      credentials: |
        credentials:
          system:
            domainCredentials:
              - credentials:
                  - usernamePassword:
                      scope: GLOBAL
                      id: "CentOS_7.1_k4.14.11_ssh_password"
                      username: 'jenkins'
                      password: ${decodeBase64:BASE64ENCODEDPASSWD}
                      description: "Username/Password Credentials for CentOS_7.1_k4.14.11"
      permanent-nodes: |
        jenkins:
          nodes:
            - permanent:
                name: "CentOS 7.1 k4.14.11"
                remoteFS: "/home/jenkins"
                numExecutors: 2
                labelString: "CentOS_7.1_k4.14.11"
                mode: EXCLUSIVE
                retentionStrategy: "always"
                launcher:
                  SSH:
                    jvmOptions: "-Xms256m -Xmx1024m -XX:MaxPermSize=1024m"
                    credentialsId: "CentOS_7.1_k4.14.11_ssh_password"
                    host: "10.1.66.120"
                    port: 22
                    sshHostKeyVerificationStrategy:
                      manuallyTrustedKeyVerificationStrategy:
                        requireInitialManualTrust: false

Now whenever I re-deploy or upgrade Jenkins helm chart, it automatically configures these credentials and add the static slave.


Run docker inside a VirtualBox of Windows Server 2016 (GUI) on Mac OS

According to me this is not possible as the hyper-v should be enabled on the host system. If this is enabled in a VirtualBox, but not on the host system, then this will not work according to what I have experienced.


What 'ChatOps' books and resources are available?

One of the people active in ChatOps community is Jason Hand from VictorOps, who wrote a book published by O'Reilly called Managing Operations in Group Chat. This book is available for free as part of their content marketing campaign. The previous ChatOps for Dummies is no longer available and is replaced by the above book.

You should definitely take a look at Slack Apps, especially the Developer Tools. There is article by SlackStorm on how to integrate Ansible and Slack.

You might also monitor the subreddit on chatops. There is a long sidebar of resources including the video from GitHub ChatOps presentation and many more.

I would also recommend to look at Cog from operable.io and the Cog Book.


There was an error in Kubernetes that causes failure when using kubectl describe with the cronjob resource. It was fixed at some point between the v1.10.x and v1.12.x versions (more info in this issue #45418).

You said:

  According to my cron pattern, it should have started on the first
  hour.

But your schedule is * */11 * * *, and it means: “At every minute past every 11th hour.”

I did not understand what you exactly meant with "on the first hour", but if you are talking about running the job on every new hour, the schedule should look like this: 0 * * * *


What is the difference between continuous deployment to continuous delivery?

Long story short:

Continuous delivery is the capability to deploy the software to any given environment at a given point of time.  The objective is to perform push-button deployments of any version of the software to any environment on demand.

Continuous Delivery is often conflicted with Continuous Deployment.  Any change the developer makes gets deployed all the way up to Production is Continuous Deployment

The referenced article will give some info:
DevOps in nutshell


SqlPackage.exe: Error SQL0: Required contributor with id 'id' could not be loaded

I have figured the answer on my own and wanted to help someone like me.

So, the problem is I was referencing sqlpackage.exe from C:\Program Files (x86)\Microsoft SQL Server\150\DAC\bin directory, that is why it was looking for the contributor in it's sub-directory \Extensions.

I was looking around in Visual Studio installation directory and found the sqlpackage.exe in C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\150 directory, updated the path in environment variables and it worked.


How to deploy static website from public repo via Github Actions to private web server

By coincidence, I have found a possible solution via Github Secrets.


Does a DB connection prevent AWS Aurora Serverless from pausing its compute capacity?

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

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

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

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

Which begs the question: "does an idle connection count as activity?"
I think the best hint that an idle connection counts as "activity" is that the moment a connection is needed, Aurora Serverless resumes:

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


Getting error while trying to communicate with apiserver in kube-state-metrics pod

This doesn't look like kube-state-metrics but your node configuration/networking issue. You will need to debug node to node communication. I would start by checking on which nodes the kube-state-metrics is scheduled and launch a temporary pod on that node to see if you can access the API Server pod correctly. The error could be in subnet, security groups/ firewalls, or other networking and security-related components.


Remote starting/stopping Tomcat from Jenkins

If you install the manager webapp with a default set up of tomcat then it is possible to use this to install and restart applications, see

https://tomcat.apache.org/tomcat-7.0-doc/manager-howto.html#Reload_An_Existing_Application

I feel that you are asking the wrong question however.  The problem is not how to restart Tomcat but how to be sure that it has restarted

Set a host, tomcat_port and check path then use shell code like this

while [ "$response_code" != "200" ]
do
        echo "Checking whether tomcat (${host}:${tomcat_port}/$check) is alive..."
        response_code=`curl -sL -w "%{http_code}" "http://${host}:${tomcat_port}/${check}" -o /dev/null`
        echo "Received response code $response_code"
        if [ "$response_code" != "200" ]
        then
                echo "Waiting for a bit..."
                sleep 15s
        fi;
done;
echo "Tomcat is alive!"

This will wait until the Tomcat comes back - or the containing Jenkins job will time out eventually


How to set ping response of AWS ec2 instance?

When we created a new instance in aws ec2, by default aws security group block all protocol and port.

AWS security groups block ICMP (including ping, traceroute, etc.) by default. You need to explicitly enable it.

So, enable ICMP protocol (ping response) follow below steps.

Go to EC2 Dashboard and click "Running Instances"

on "Security Groups", select the group of your instance which you need to add security.

click on the "Inbound" tab

Click "Edit" Button (It will open a popup window)

click "Add Rule"

Select the "Custom ICMP rule - IPv4" as Type

Select "Echo Request" as the Protocol (Port Range by default show as "N/A)

Enter the "0.0.0.0/0" as Source

Click "Save"


For the whole points and to try things there's https://learn.chef.io which allow you to test automate also.

Mainly chef automate is the next iteration bringing together 4 commercial products from Chef: chef manage (UI), chef reporting, chef compliance and delivery (CI/CD) with the addition of push jobs which was open sourced a little before.

Inspec is another new tool for compliance, it is based on serverspec but not extending it not using its code base.

Automate is not mandatory to author cookbooks at all, it is just a convenient way to display back status of nodes either on configuration point of view or compliance point of view (see the audit cookbook for inspec usage within a run), you can still does everything on your nodes on the free open source model, you'll have to handle the feedback loop yourself, either through a handler or any other way of your choice as it was already the case.

The CI/CD part of Automate doesn't replace any tool, it's more another approach to CI/CD pipelines, so you may use it to do the usual linting (foodcritic/cookstyle), test (chefspec), and then upload to your chef-server for use. It can handle deploys through the push jobs feature and after review and approval of changes.

Presentation of automate and the related documentation (workflow is the first concept, others are accessible from the menu on the left)


There was used wrong type for variable, should be:

variable "ssh_keys" {
  type = "map"
  default = {
    "atolkachev" = "ssh-rsa my_key atolkachev"
  }
}


Possibility of container breakout compared to VM (virtual machines)

Containers isolate an application on a shared OS, VM's isolate an OS on shared hardware. With those different levels of abstraction, you have different exploits and protections.

A successful kernel level exploit on a container will affect the shared kernel, and therefore breakout of the container isolation. Think meltdown and spectre.

A successful VM driver exploit could break out of the VM to the hypervisor running the VM's. I've heard of exploits on things like the floppy driver in VMs. These are much more rare than kernel exploits, so I'd give the advantage to VM's here.

It is possible to change the container runtime to spin up containers in small VM's. Projects like Kata Containers are working on this. So you could get the security of VM's while still getting some of the features of containers.

Containers do have a huge different advantage over VM's. They run in a minimal environment with reduced capabilities, seccomp, and optionally selinux/apparmor configured. You can lock down that environment in ways you couldn't easily lock down a VM, with a read-only filesystem, and not including any of the tools like shells, interpreters, and libraries that an attacker may need to exploit your system to try attacking the kernel or horizontally pivot their attack.

As a result, there's no clear winner. The best answer is likely a combination of both, running a handful of containers with similar security requirements on their own VM.


Cloud agnostic infrastructure automation better than terraform?

There are no "agnostic" products due to the dramatic differences of the design of the Cloud Services provided by different companies.

My best recommendation is to write your code to support the different cloud providers. Whether you choose Ansible or Terraform this can be done with Ansible Roles or Terraform Modules that are specific to the cloud provider. Just the same as you would write Ansible roles specific to Operating Systems or different scenarios.