title: Ansible Find Module

text:
# Question
Title: Ansible Find Module
I am trying to use the Ansible `find` module to create a list of files to pass to the `file` module to change file permissions on files owned by a specific user in a directory that contains files owned my various users. The Ansible `find` module does not appear to allow me to use owner or group as search criteria. There are no other distinguishing factors about the files other than the owner. Is it possible or would I have to use the `shell` module instead?

# Answer
> 2 votes
You might want to loop stat module with the list of files from the 'find' module. The 'stat' module will provide you with 'pw\_name' key which can be used to conditionally run the 'file' module.

# Answer
> 1 votes
If the target is a directory, setting this to yes will make it the default `acl` for entities created inside the directory.

Select if and when to recalculate the effective right masks of the files, see `setfacl` documentation for more info. Incompatible with state=query.

See: acl - Sets and retrieves file ACL information.

# Answer
> 1 votes
I ended up using the command module to run a find to ascertain which files were owned by the required user, put them in a register and pass that register to the file module using with\_items.

---
Tags: ansible
---


# Question
Title: What are the best logging/metrics reporting tools for use with OpenShift?
OpenShift includes EFK and I'm looking into using that or ELK, but there are so many options (found a link with 50+ options) that I'm trying to narrow down. Ideally something free/cheap. What is the best logging and metrics reporting tool?

We are running a handful of microservices within OpenShift.

Some simple use cases of what we are looking to do:

* As an admin, I need a report showing how many times a service was called in a given time frame.
* As an admin, I need a report showing how many times a service was called successfully in a given time frame.
* As an admin, I need a report showing the average time a service takes to process requests.
* As an admin, I need a report showing the lifecyle of a specific message (UUID). The lifecycle will show each service called.

# Answer
> 3 votes
The question hasn't had an answer in seven months so I will promote my upvoted comment to an answer:

Finding the lifecycle of a specific message across services is known as "distributed tracing". Distributed tracing requires more than just capturing logs. OpenShift uses Kubernetes which is part of cncf.io/projects which governs opentracing.io and has one tracing solution jaegertracing.io. As Jaeger is a sister project to Kubernetes you are likely to find it widely supported. Here is an openshift commons video about it.

I should mention that the question is likely to gather a lot of answers of the type "the only tool I have used is the best tool ever!". Experts will avoid answering such questions. On many sister StackExchange sites, often questions that get such answers get put on hold by moderators as been unhelpful.

I recommend that you don't look at new tools before fully exploring the tools that are near to hand or "most obviously stable and well supported". As EFK (sometimes more amusingly know as FEK as it sounds naughty) ships with OpenShift its worth really digging into what it can do. Then ask questions about how to do the things that it appears it cannot do. That is the style of question that helps everyone and that experts will gladly answer and you may then find that the most stable and widely support tool meets your needs. That is the best outcomes as it is going to be the easiest to get running, the least likely to break on upgrades, and the least likely to itself go down causing you late nights fixing it.

---
Tags: logging, metrics, openshift
---


# Question
Title: Where is the git submodule revision actually stored?
I understand how to use git submodule to reference a specific commit in another repo, but where is that reference actually stored? It doesn't seem to be in `.gitmodules` as plain text?

# Answer
The `.gitmodules` file just records the path and remote URL to the submodule repository. The commit itself is stored in the tree object. You can query it like this:

```
git ls-tree <ref> <path>

```

where `<ref>` is a reference to some commit (e.g. `HEAD`, `master`, a commit SHA sum) and `<path>` is a path to a submodule.

The output looks something like this:

```
160000 commit <sha> <path>

```

where `<sha>` is the commit in the submodule. The number in front has the following meaning, according to the Git book:

> Notice the `160000` mode for the `DbConnector` *(submodule path of the example used in the book)* entry. That is a special mode in Git that basically means you’re recording a commit as a directory entry rather than a subdirectory or a file.

See also this question on StackOverflow.
> 10 votes

---
Tags: git, cicd
---


# Question
Title: AWS or Azure with usage auto shutdown occasional usage
I'm looking for recommendations on which cloud service provider we should be looking at.

The situation:

I'm part of a small team looking to leverage more powerful analytics. Most of our day to day can be done on local machines but we want to explore using more powerful hardware through a cloud platform before committing to anything in house. As far as software we use Excel, MSSQL, and R, although these cloud instances only need to run R.

Our ideal use case would be uploading data to the cloud, spinning up an instance to run whatever we need to run, then shutting down the instance while keeping the data and software (eg R packages) stored. This way (I think) we would only be charged for the storage while we aren't actively running a project.

Additionally we'd like an auto shutdown feature where the computing instances are automatically shut down if they aren't used for a certain period of time or if that isn't possible, at a given time each day.

We're really outside of our area of expertise here so user friendly is a big plus.

Any advice?

# Answer
> 2 votes
I can think of a few different ways to achieve this.

1. First and easiest way is to create a new **CloudWatch Events Rule** , set its "Event Source" to run on a schedule and "Target" to EC2 StopInstances API call with Instance IDs provided. Look at this screenshot for clarity:

With this example, An event will start at every night at midnight and it will stop Instances by their IDs. You can change the schedule with cron expressions. See: https://crontab.guru

2. You can implement any kind of custom logic with AWS Lambda functions and schedule them to be run with a variety of AWS services (including CloudWatch Events).

For example, with a Lambda function you can implement logic to find instances by a tag, like *"GoodBefore=2018-08-10"*, and stop these instances. In fact you could even make use of API Gateway to expose an API for requesting instances, only to be terminated after a few days by their *"GoodBefore*" tag.

Of course, while this way is much more customizable and sophisticated, it may prove hard especially if you don't have experience in programming.

3. If you don't want to implement custom logic with Lambda, but also need more than what CloudWatch Events can provide, you can make use of Instance Scheduler solution provided by AWS. It's a similar solution to what I described in previous method, but this time AWS already did the hard work for you.

URL for us-east-1 region: https://console.aws.amazon.com/cloudwatch/home?region=us-east-1#rules:action=create

Note: While I haven't used Instance Scheduler myself, I'm pretty sure it wouldn't decide on such things, and I think it only makes sense if it wouldn't do much more than simply making a stop call for the instance. So, on any stop event, either made by an automated solution or you, if your instances' root volume was created "EBS-backed", it will retain the data. If it is "instance store backed", it will lose the data. You can find this information from AWS EC2 console. If you want to retain data after stopping instances, make sure all volumes are EBS-backed when creating a new instance.

# Answer
> 2 votes
This feature has been available in Azure for a couple of years now, it's as simple as ticking a box and setting a time for shutdown. You can also have it fire a webhook if you need any notifications, or scripts run, or anything else when it shuts down.

Also on Azure there are pre-configured data science VMs and deep learning VMs with all the tools you need including  already installed, you just pick a size and spin one up. You can go small just to try the software, or go for one with multiple GPUs, all already set up with the tools and usable straight away. You can even reboot the same box in different sizes depending on what you need that day!

You are correct that while a VM is not running, you will be charged only for the storage used.

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


title: Storing my Lambda Functions on GitHub

text:
# Question
Title: Storing my Lambda Functions on GitHub
Will it be practically possible to build some pipeline;

1. starting from rapid AWS Lambda function development using blueprints,
2. to store them later on a new GitHub repo,
3. that is linked to some CICD such as Travis,
4. that will in turn deploy successful builds back in AWS Lambda?

# Answer
> 2 votes
Your idea will work. The organization I work for maintains some open source examples how to do deploy to AWS using a pipeline. In comparison we use GitLab for the purpose. Instead of Travis we use GitLab Runner. You configure it using the file `.gitlab-ci.yml` which runs the tests and deploy the AWS Lambda to dev, test and production environment every time a commit is done. You store your secret account variables in the CI/CD settings of the repository.

There are the usual drawbacks of AWS Lambda such as difficult or impossible to test and run locally and waiting for deployments takes time, but your deployment process will be good practice.

---
Tags: amazon-web-services, github, aws-lambda, travis-ci
---


# Question
Title: Running consul in the background using Chef
I am trying to create a Chef cookbook that will run Hashicorp Consul in the background and will continue with the rest of the recipe and not get hung on starting Consul.

I have tried the `&` method at the end of the command but when chef-client exits it kills the process and will not let me run any checks / testing against Consul.

Anyone have a suggestion on how to resolve this? I know I have seen a few implementations where they use ruby scripts but I would like to avoid that as I suck at ruby. Also do not want to use another cookbook from online, rather make my own to learn how as this is a learning project.

# Answer
The usual way to do that is to use a service manager (systemd or supervisord) to handle the service lifecycle (keeping the consul program running and restarting it if it fails for exemple) there's cookbooks existing to help creating those service units.

The cheap alternative if you count on chef running periodically and handling that is to use nohup which is a linux program made exactly for this.
> 1 votes

---
Tags: chef, process, bash, consul
---


# Question
Title: How to test whether a variable exists in the declarative pipeline
I am using the Build User Vars Plugin which sets various variables in the pipeline. Here is what I am currently trying:

```
wrap([$class: 'BuildUser']) {
    def safeBuildUser = binding.hasVariable('BUILD_USER') ? BUILD_USER : "unknown"
    echo "${safeBuildUser}"
}

```

There are times when the plugin does not set the variable. For instance, when the build was launched by an SCM branch scan. When that happens, I receive:

```
groovy.lang.MissingPropertyException: No such property: BUILD_USER for class: groovy.lang.Binding

```

Using `binding.hasVariable` does not appear to work because all of the builds now show "unknown".

In addition to the above, I also tried the following with no luck:

```
def safeBuildUser = BUILD_USER?: "unknown"
def safeBuildUser = binding['BUILD_USER']?: "unknown"
def safeBuildUser = binding.variables['BUILD_USER']?: "unknown"

```

# Answer
> 4 votes
use try/catch

```
def safeBuildUser = "unknown"
wrap([$class: 'BuildUser']) {
  try {
     safeBuildUser = BUILD_USER
  } catch (e) {
     echo "User not in scope, probably triggered from another job"
  }
}
echo "Builduser is: ${safeBuildUser}"

```

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


# Question
Title: How do I automate population of known_hosts and authorized_keys?
This is a question that may be easier answered on askubuntu or, perhaps, serverfault, but it arises in the context of automated provisioning, so I figured that it's more appropriate here.

I am spinning up a multi-machine environment in vagrant, e.g. `n+1` ubuntu-18.04 boxes, namely

* term (short for terminal)
* node1
* ...
* nodeN

They can all resolve each other by the above hostnames. It's necessary, that `term` can SSH into each of the nodes using its public key.

Manually I can do this with the following script:

```
#!/bin/bash

head='node'

ssh-keygen -N '' -f ~/.ssh/id_rsa

for ((i=1; i<=$1; i++)); do
  name=$head
  name+=$i
  ssh-copy-id $name
done

```

running, e.g., `./copyid.sh 3`. But then I have to type `yes` (to confirm the fingerprint of the node) and `vagrant` (the password) three times.

I want to move this procedure to the provisioning of the VMs in the Vagrantfile. So I have two questions:

* How can this be automated without demanding manual input from myself?
* When I transfer over from virtual machines to bare metal servers, what best practices should I follow to prevent infosec guys from screaming "man in the middle" at me?

# Answer
> 4 votes
You have to execute `ssh-keyscan`. For example to ssh to a host (github.com here ) you have to run below script

```
# Add ssh key to help cloning private github repo

ssh-keygen -t rsa -N "" -f secrets/ssh/github_rsa
PUB_KEY=$(cat secrets/ssh/github_rsa.pub)
PRV_KEY=$(cat secrets/ssh/github_rsa)

echo "${PRV_KEY}" >> ~/.ssh/github_rsa
chmod 600 ~/.ssh/github_rsa
eval $(ssh-agent)
ssh-add ~/.ssh/github_rsa

ssh-keyscan github.com >> ~/.ssh/known_hosts
echo IdentityFile ~/.ssh/github_rsa >> ~/.ssh/config

echo "Paste the following public key to your host machine ".${PUB_KEY}

```

---
Tags: vagrant, provisioning, key-management
---


title: Autoscaling with Kubernetes daemonset

text:
# Question
Title: Autoscaling with Kubernetes daemonset
I have a Kubernetes cluster running on Google Compute Engine. My program uses stateful connections, so I do not want my pods being moved between nodes. Because of this, I am running my workload as daemonsets, and giving each node the amount of compute power that one pod needs.

This system is working, but I would like a way to autoscale. Normally, the high workload would produce more pods, which would then trigger the creation of more nodes. But since I am only using daemon sets, this normal solution will not work.

I can use commands to increase or decrease the number of nodes in the server, but I would like this to happen automatically. Ideally, when the workload is high, the cluster would spawn another node in its node pool. Even better, if there is a solution to autoscale down the number of nodes, while minimizing closed connections.

I haven't found much information on ways to do this. I am not very experienced with dev ops, kubernetes, google cloud, docker, etc. so I would appreciate explanatory answers.

Thank you.

# Answer
> 1 votes
I think you can do this by Nodeselector. Firstly add a label for node selector in your daemonset config. Then label your nodes with the attached label. Now if you can set the autoscaling thresholds, it will be deployed on that node automatically on nodes that matches the label. Maybe you can tweak somehow to attach a label to your node when it is added to your pool.

Also, with Kubernetes 1.6+, we have the feature of rolling update strategy which is far better than onDelete.

Cheers

---
Tags: kubernetes, google-cloud-platform, autoscaling, google-compute-engine
---


title: Tfs octopus migration to k8s and docker

text:
# Question
Title: Tfs octopus migration to k8s and docker
My current client uses .net and .net core, tfs and deploys via octopus. They want to use helm, k8s and docker. With all of the environments, env variables are already in octopus.

I am thinking to restore the nuget packages in the dockerfile, build the image, push to our local registry. Add our docker registry as a feed, add helm as a feed then creating a lifecycle for dev and prod. Then modify the octopus jobs to point to the local registry to pull the images.

Anyone see any issues here? Should I strip out the env variables from octopus and just get rid of octopus?

# Answer
> 2 votes
Helm is a Kubernetes tool so this answer assumes you are deploying to Kubernetes or OpenShift not Docker Swarm.

If you are using Helm well then I don't think it is particularly important what build pipeline tech you are using to invoke it. I think what is more important is how you manage all your configuration within Git and how you structure the Helm deployments.

There are two different paradigms you can follow:

1. Build the app container image with the correct environment variables baked within it for each environment.
2. Build only one app container image that picks up environment variables from within the environment it has been deployed.

If you follow 12factor.net best practices then you go for Option 2. IMHO it feels far cleaner and less error-prone to move the exact same image between kubernetes namespaces that represent different environments. We store environment variables inside of Kubernetes as `secrets` or `configmaps`. We then get to two more questions:

1. How do you load `secrets` and `configmaps` as environment variables into your .Net Core runtime images when the container starts up?
2. How to you manage the `secrets` and `configmaps` in each environment?

With respect to the first question, Kubernetes has this covered. Any deployment can name a bunch of different secrets that should be loaded as environment variables. Ditto for configmaps. You just need each environment to be a different namespace so that the same logical secret can have the same name in each environment. Your database credentials can then be a secret called `main-database-credentials` that holds different credentials in different environments.

To deal with the second question we use Helm to manage both secrets and configmaps. We have one generic Helm chart that deploys all our different secrets in all our different environment:

`helm upgrade --install -f $NAME.yaml $NAME secret-1.1.tar.gz`

So to upgrade our `main-database-credentials` secret we would change the settings in `main-database-credentials.yaml` then tell the chart to recreate the `main-database-credentials` deployment using that command. The chart simply uses the Helm templating language to build yaml that defines the secret using the name set in the yaml file. Likewise, we have a generic chart that updates `configmaps` that is invoked with a very simlar command as above. Helm uses a standard Golang templating library so it is very straight-forward to create those generic charts.

At first, it may seem a bit heavyweight to use Helm to update something like a database password secret. Yet helm gives you a deployment history and lets you diff the history of deployments. It also lets you easily roll-back to a previous deployment. That is really powerful as an audit trail of config changes that is really helpful when managing a complex microservices deployment. Since we also use Helm to deploy all our apps it makes perfect sense to use the same power tool to manage the deployment of configuration into our environments.

As we can use a generic helm chart to deploy many secrets into many environments why not use a generic helm chart to deploy all our microservices? We do:

`helm upgrade --install -f $NAME.yaml $NAME deployer-1.3.tar.gz`

This means that `NAME=my-microservice` and `NAME=my-admin-webapp` or anything else can be deployed using one generic `deployer` chart. The path and tag of the application container image to deploy is in the yaml file. The container path is different for different apps and the container tag can be different between environments.

That might sound strange as normally Helm packages a particular app so you would expect a one-to-one relationship between charts and apps. Yet if all your microservices are containers following 12factor.net best practices shouldn't they all "look the same" from the perspective of deploying them; it is just the container and the environment variables you deploy into the one generic chart. I see it that the app is the pure container with none of the configurations to run it and the Kubernetes configuration to run it is "application infrastructure". So I have a Helm chart for each type of application infrastructure. I don't want each bit of application infrastructure to be hand-rolled I want to cookie cutter create it using Helm.

Now we have covered all the Helm mechanics we are left with the question "how do we manage all our configuration within git?". We use different repo for different purposes:

1. Each microservice has its own repo. We use CircleCI to build the code into an image that is configured via environment variables. We don't store any Helm or Kubernetes config in this repo. We do have a properties file that names the latest version of the `deployer` chart this code is compatible with.
2. We have a GitHub repo that holds the source of the generic Helm charts that are used to deploy all our apps and secrets. These don't actually change very often now they are fairly stable. CircleCI builds and releases the charts as tar.gz onto the GitHub releases page for this repo.
3. We have a git repo per environment. This has a folder per deployed microservice within that environment. Each contains the `yaml` file to pass to the helm deploy encrypted with `git secret`. It has a folder per deployed `secret` within that environment. Each contains a `yaml` file that is `git secret` encrypted. Ditto for `configmaps`.

Why a repo per environment? A branch per environment sounds more normal. Only a database credential for the live environment never moves between environments. As we use a separate repo for live we can give it separate permissions. We might let all developers go wild in the `dev-environment` repo we have a bit more discipline with the `live-environment` repo.

We then have CircleCI do automated deployments of configuration. This works as Helm data detects changes and doesn't deploy a change to any Kubrernetes object if the latest yaml it generates is already deployed. To change a password in live you change it in the `git secret` encrypted yaml in the live repo and apply a release tag. CircleCI pattern matches on the tag name to see that its a release tag and it runs the deploy step. That uses a container with the helm client to run a bash script that loops over all app folders, secret folders and configmap folders running Helm for the right chart and correct yaml. Helm will only apply updates where there are changes within git.

---
Tags: docker, kubernetes, helm, octopus-deploy
---


# Question
Title: What is the exact use of DETACHED HEAD state in Git?
When I checkout a specific commit hash, it goes to detached mode where HEAD POINTER can't point to a recent commit.

What are the things we can do and what is the use of going detached head state in Git?

# Answer
The "normal" way of working with GIT is by checking out branches. HEAD is a "pointer" to the latest commit in that branch, and GIT will allow you to commit new changes after that pointer.

However, as you figured out, it is possible to check out a specific commit hash, if you want to. In this situation, if you make changes and try to commit them, you will be unable to do so, since you are not at HEAD, and GIT will not allow you to commit your changes.

Most of the time, detached HEAD (checking out an older commit) is used if you want to test how your project ran at a certain point in time.

If you need to make changes to the code or need to build it using Jenkins MultiBranch Pipelines, for example, it is also possible to create a new branch from that specific commit by running:

`git branch my_new_fancy_branch 7y8u33ii`

or

`git checkout -b my_new_fancy_branch 7y8u33ii`

... where `7y8u33ii` is the hash you provided in the question. For this new branch, `7y8u33ii` will be HEAD, so you will be able to commit new changes. If you need to get your code into the branch from which you created this new branch from, you will need to do a merge, but this is another discussion altogether.
> 8 votes

# Answer
`HEAD` is a special reference in Git that always points to "the thing" you have currently checked out. This "thing" can either be a local branch (`HEAD` is in attached mode) or a specific commit (`HEAD` is in detached mode).

In attached mode `HEAD` is tied to the branch it references. The current commit is determined by the position of this branch. If you move your `HEAD` around (e.g. by committing or resetting), in reality `HEAD` is unmodified and still just pointing to the branch and the branch is moved instead.

If you switch to detached mode (e.g. by `git checkout --detach` or checking out a specific commit, tag or remote branch), `HEAD` is pointing directly to the commit hash. You can continue to use Git as you did before but no branch is modified when you move your `HEAD` around. This time `HEAD` is modified directly on each such operation.

So to answer your specific question "*what are the things we can do*": In detached mode we can do anything we could do in attached mode (commit, merge, reset, push…) but without the need to first create a branch. We need to be careful though: When checking out another commit, nothing references the original commit anymore and it is lost\*.

The more difficult question to answer is "*what is the use of it*". As rasebo already stated in his answer, often to quickly check out an older commit to see how the project looked like at this time. But there are more use cases. Detached mode is used during an interactive rebase, for example. Also I use it often in my personal workflow to quickly create throwaway snapshots during prototyping or experiments. I could also use temporary branches for this, but I guess it comes down to personal taste and habits.

To get a better feeling for this whole topic it can help to play around and observe how `.git/HEAD` and the branches in `.git/refs/heads/` are modified after executing different Git commands.

---

* Well, not really lost, just inaccessible. It could be restored e.g. by looking up the hash in the reflog and then checking it out. It is only irreversibly deleted after a (manual or automatic) garbage collection 90 days (default) in the future.
> 4 votes

---
Tags: git
---


# Question
Title: How to exclude a certain linenumber of an Ansible playbook when testing it using Molecule?
The aim is to exclude a certain line that contains a checksum and cannot be smaller than 80 characters.

```
--> Scenario: 'default'
--> Action: 'lint'
--> Executing Yamllint on files found in /tmp/ansible-firefox/...
    /tmp/ansible-firefox/defaults/main.yml
      2:81      error    line too long (153 > 80 characters)  (line-length)

```

defaults/main.yml

```
firefox_checksum: sha512:49d776cfb5f42c6e5ea1a55a80d9f6bad223080b16baa0d39de63534c25e68340091b4e16be5355d565f81291cb94fb996f03ae7e3e4c7a28021b0a0929daf58

```

# Answer
> 3 votes
According to the yamllint documentation you need to add a special comment to the line -- `<string-to-be-excluded> # yamllint disable-line rule:line-length`

```
---
#defaults/main
firefox_checksum: sha512:49d776cfb5f42c6e5ea1a55a80d9f6bad223080b16baa0d39de63534c25e68340091b4e16be5355d565f81291cb94fb996f03ae7e3e4c7a28021b0a0929daf58 #yamllint disable-line rule:line-length

```

---
Tags: ansible, yaml, molecule, linting
---


title: Pod & pod's health

text:
# Question
Title: Pod & pod's health
Few questions here:

1. What does the concept of object Pod satisfy? A paused container containing the namespace for the actual app area (s) will be added later and use that namespace. So what activities in real life qualify to have more than one container running in a pod? Can you give examples of points? What is considered sidecar operation after all?
2. What is the threshold, for example: N container in the Pod that the master will be able to say that Pod is not healthy? So basically, how many containers in a pod need to down to the POD mark down?

# Answer
A legitimate example of multiple containers in a POD is hinted at in the official docs:

> These co-located containers might form a single cohesive unit of service–one container serving files from a shared volume to the public, while a separate “sidecar” container refreshes or updates those files.

So you can use an nginx container that serves content out of the pod disk and another container that runs “git pull” in a loop with a short pause to refresh the html content on the pod disk.

Of course people would typically build an image containing the latest html using “FROM nginx” at the top of the dockerfile so they wouldn’t normally do things the way I described.

So the real answer is that most folks can and should avoid running multiple containers in a pod. If your starting from scratch building a typical new system you can keep things clean.

Yet more and more people are moving legacy workloads onto kubernetes. Then you don’t have a choice about the actual application architecture. In which case you may find you need to run two or more processes that share resources wiring a pod. That’s a total anti-pattern for modern “share nothing” microservices but legacy code doesn’t follow modern best practices.
> 1 votes

# Answer
All of them would have to be up for the pod to be completely up. Instead of running multiple processes within the same container, use sidecar containers. For now they share network namespace and emptyDir filesystem, but not pid namespace (pid namespace sharing is available in beta, https://kubernetes.io/docs/tasks/configure-pod-container/share-process-namespace/).

A typical sidecar use case is utility containers. What I commonly see it one for logging, such as a splunk forwarder or syslog daemon.

There's also those that setup an app stack as a Deployment (which materializes in one or more replicas of a pod), instead of multiple deployments.
> 0 votes

---
Tags: kubernetes
---


title: What is a "mesh"?

text:
# Question
Title: What is a "mesh"?
In this context and cloud computing, I read about "service mesh" and/or "serverless mesh" but I don't fully understand what it is. Can you explain?

# Answer
The metaphor of "mesh" is "many interconnected things". We might describe TCP/IP as a "mesh technology" as it is the technology that connects many things and performs useful services like resending lost packets and adapting to changes in available bandwidth.

Modern "service mesh" technologies let you write basic code then wrap it in something readymade that plugs-in discovery (locating. resources), mutual TSL, protocol upgrade (newest HTTP or better), applies security policies, fault tolerance (such as retry on error), load shedding, circuit breakers, distributed tracing (header setting and traffic sampling), advanced load balancing, and much more.

Imagine that the internet only had UDP protocol. You can send a packet but you didn't know it got there. You might in your application have to write a bunch of code to detect lost messages and request a resend. You might write a library to do that. You might compile all your apps against such libraries written in different languages (PHP, Java, C, Perl, ...). That would be terrible. You would want someone to invent TCP/IP that just does it for you. Then you can write simple code that "just connects and sends" and the "TCP/IP service mesh" will do its magic and make sure that the data gets `A->B` as fast as possible dealing with dropped messages and varying bandwidth conditions.

Today developers writing microservices are having to use libraries for discovery, mutual TSL, protocol upgrade (older HTTP over newer HTTP or better), security policy, fault tolerance, load shedding, circuit breakers, distributing tracking, advanced load balancing, ... That's terrible, right? Shouldn't we just be able to deploy some new technology that sits between `A` and `B` and ensures that all the traffic `A->B` had all those features? You need a Service Mesh.

In the kubernetes world things such Linkerd and Envoy provide the base technologies. They are smart proxies. You don't go `A->B` you go `A->P=>P->B` where `->` are local connection. A service has a data plane (move the data) provided by the smart proxies and an administration control plane (apply the desired policies by pushing configuration out to the smart proxies).

With Linkerd you run it as a demon set (one per container host). With Envoy it's small enough to deploy it as a sidecar container. So you keep the "local dumb connections" within the VM host. All traffic between VM hosts is smart proxy traffic with all the new features you want applied by policy.

Discovery (locating resources) is something a service mesh does. All containers just connect to a smart local proxy. The smart proxy looks at the header of the connection to see the logical name of the service you are connecting to. It then uses its own dynamic configuration distributed across its control plane to decide what physical location to proxy the traffic towards. What is more interesting is all the very smart things it can do to the traffic that it sends over the wire. These are additional technical services. All the interconnections are a mesh. The advanced services are applied to traffic in the mesh. It is therefore a Service Mesh.

If you want to look at something in this space look at istio.io
> 4 votes

# Answer
The concept of *service discovery* works like this:

1. When a server, such as a database, starts up, it contacts a central registry and says *Hi, I am a database, and these are my connection details*.
2. Then when a client starts up, it contacts the registry and says *Hi, I need a database* and the registry replies *Here are the connection details* and the client connects to the database directly.

The only config anyone needs is the location of the registry. The concept of *mesh* applies a layer of abstraction to this. Every host runs an agent of the mesh, there is no central registry. Now the scenario looks like this:

1. The database server starts up and tells its local mesh agent that it is ready. That local agent then replicates this information around the mesh. Agents are in continual communication with each other.
2. The client starts up and tells its local mesh agent that it needs a database
3. The client then connects *to its local mesh agent* which forwards the traffic to the mesh agent on the database server, which simply sees a local connection. Neither the client nor the server are really aware of each other, just of their local connections.

The advantages are decentralisation and scalability - you could add a new database server for example and let the mesh transparently handle routing and load balancing. There is no central registry to worry about. In our scenario of one client and one server that doesn't matter so much but if you go wild and have 10,000 microservices then it becomes very relevant.

The disadvantage is one of "all your eggs in one basket", the mesh itself must be more robust etc than making a traditional connection, which has been proven to work for 30 years. It can also be difficult to use traditional troubleshooting tools such as tracing connections, because the mesh is something of a "black box", it can be difficult to reason about all the connections as all the traffic on your network now will be inside the mesh, e.g. you can't just look for connections on port X and know that's the database.
> 6 votes

---
Tags: terminology, microservices, cloud
---


# Question
Title: zip: command not found after installing zip on NODE docker image, even after installing p7zip?
I'm trying to zip my dist folder and post to it Azure's kudu zipdeploy endpoint but I keep getting this error regardless of the fact that I have installed a zipping package myself.

My docker image: weltn24/up-docker-node-chrome-headless on tag: chrome-66\_node-10.0\_yarn-1.6.0

The part that fails in my yml file:

```
build:
  stage: build
  script:
    - apt-get install p7zip p7zip-full
    - yarn install
    - ./node_modules/@angular/cli/bin/ng build --prod
    - cd dist/AngularTemplate; zip -r ../dist.zip *; cd ..; cd..
  artifacts:
    paths:
      - dist.zip

```

The commands on the 4'th line is failing with zip: command not found.

# Answer
> 1 votes
Correct script below:

```
build:
  stage: build
  script:
    - apt-get install zip unzip
    - yarn install
    - ./node_modules/@angular/cli/bin/ng build --prod
    - cd dist/AngularTemplate; zip -r ../../dist.zip *; cd ..; cd..
  artifacts:
    paths:
      - dist.zip

```

Was installing the wrong Zip package and then puttin my archive in the wrong folder.

---
Tags: docker, gitlab, node.js, cicd
---


# Question
Title: nodes in a kubernetes cluster in azure unable to communicate with one another
I'll start off by saying I'm not really an infrastructure person, but am being required to maintain it until we hire someone more suited to it, so apologies if I have any terminology wrong.

We have a kubernetes cluster (AKS)in azure. Currently we are running only 1 server in the cluster, with 4 namespaces configured within it, representing each environment. To properly support our production environment, we ideally want at least 3 servers, with the ability to scale appropriately. However, whenever we try to scale it up, services deployed to different server nodes cannot communicate with one another.

The unfortunate thing is I have no idea even how to start begin debugging this. I know we have some custom nginx rules that microsoft gave us, but even setting allow everything as the first rule does not seem to resolve this issue. How do I begin debugging this? What information would even be helpful for this issue?

# Answer
With help from a Microsoft Engineer, we were able to resolve our issue.

The trick to it was that the node that could communicate with the outside world was always the one that the kubernetes tunnel pod was running on. This indicated a problem with communication between nodes. The traceroute indicated that this, with no network security group traffic restrictions, was bouncing between the node1 ip, to the load balancer ip, back to the node2 ip.

we had a security rule that restricted all traffic that was not on our specifically approved list.

One of the debug steps I had taken was to open all traffic between the load balancer ip to the load balancer ip. However, this failed to consider the fact that the traffic was not from the load balancer to the load balancer, but from nodex to the load balancer then from the load balancer to nodey.

We added an inbound and outbound traffic rule that allowed traffic from the subnet ips that nodes can possibly be on to the load balancer, as well as within the same subnet for good meansure. This resolved the issue.

If that's confusing, I can provide images that show the new rules and explain it a little clearer, but I'm hoping that is clear enough for anyone who experiences a similar issue.
> 1 votes

# Answer
What about creating a new managed k8s cluster and start from scratch? This is what I do if the architecture is a maze. Managed k8s on azure and gcp is a couple of clicks away.
> 0 votes

---
Tags: kubernetes, azure, azure-kubernetes-service
---


# Question
Title: How does Vagrant differ from Ansible and Docker?
I understand that *Ansible* is a Configuration Management (CM) tool for orchestrating, deploying (and continuously upgrading) software and conf via a special YAML format created for that software, and that Ansible actions can be done on the local machine via a locally executed Ansible playbook, or remotely for 1 or more machines by listing IP addresses for an Ansible playbook in an Ansible storage file and executing both the storage and associated playbook (without needing to install Ansible on the one or more remote machines).

I also understand that Operating-System-Level-Virtualization ("Containerization") software like *Docker* (also utilizing YAML in a unique format) allows us to "copy away" containers of "frozen; just-bake" data, from one machine to 1 or more other machines to have a pre-processed data to work with and to change minorally per specific nneds to save time of repeatitive creation of that data in the container time and again.

Sometimes when I read about either Ansible or Docker I come across mentions of *Vagrant* which is another software.

I understand Vagrant to be a what I can call "All-Level-Virtualization" (operating-system and possibly also some stack above it), yet I'm not sure if that's correct.

How does Vagrant is different than these two in principle (and also the term "Vagrant box" makes me to wonder if Vagrant is an actual "competitor" for Docker, is it?)

# Answer
> 9 votes
Vagrant can complement Ansible and Docker. It is used to spin virtual machines inside which you install Docker and test your Ansible playbooks. You describe desired VM configuration with `Vagrantfile` and then spawn them with `vagrant up` command. Then Vagrant software downloads one of shared *boxes* (VM templates, like bare *ubuntu* or *centos*, or with preinstalled software like *laravel*), and provisions it (executes setup instructions). There are several provisioners, like simple shell, or Ansible.

One of possible scenarios: you want to test `mysql:5.7.24` image inside `Docker 18.06.1-ce` on `Ubuntu 18.04`. So you:

* Spin up `ubuntu/bionic64` box with Vagrant
* Provision it with Ansible playbook that installs Docker `18.06.1-ce`
* Start Docker container based on `mysql:5.7.24` image

---
Tags: docker, ansible, terminology, vagrant
---


# Question
Title: packge.json not found while executing on Jenkins
My Dockerfile looks something like this.

```
FROM mhart/alpine-node:8.11.3

RUN mkdir -p /app
COPY ./ /app

WORKDIR /app/build

RUN yarn global add serve
CMD ["serve", "-l", "3000"]

EXPOSE 3000

```

And then JenkinsFile looks something like this.

```
 node {
  try {

    stage('Checkout source code') {
        checkout scm
    }

    stage('Install packages') {
      sh("docker run --rm -v `pwd`:/app -w /app node yarn install")
      //sh("sudo chown -R jenkins: ./node_modules")
    }

    stage('Set the enviroment variables') {
      sh("echo set-env-variables")
      }

    stage('Build static assets') {

      sh("docker run --rm -v `pwd`:/app -w /app node yarn build")
    }
  }}

```

When I do run it on Jenkins,the console output says error Couldn't find a `package.json` file in "/app" and also it gives an `error sudo not found` even though I have added Jenkins `ALL=(ALL) NOPASSWD: ALL` to `/etc/sudoers` file.

I run the commands listed in my Jenkinsfile on my terminal and they all work fine but when i run them on Jenkins , they dont work.

# Answer
Because you are setting the container's `WORKDIR` to `/app/build` so your package.json is not in the working directory, but in the parent of the working directory.
> 1 votes

---
Tags: docker, jenkins, jenkins-pipeline, dockerfile, jenkinsfile
---


# Question
Title: Jenkins shows the job as failed if there is nothing to commit to gitlab
I have been using one Jenkins job, that will pull repository from gitlab. Then it will modify the files and push it into gitlab (only if any user added any new files/modify contents in gitlab). Otherwise, it simply does empty commit. When empty commits & push happens, Jenkins job shows me like the job is failed. For only this case, I want to make Jenkins should show as successful. Is there any way to do it?

**UPDATE:** Here is the log I got from the job. I am expecting SUCCESS even if the Jenkins git pushes the empty repository (as shown as the below).

```
[1. Extract simplified configuration] $ /bin/sh -xe
/tmp/jenkins2112147489595430303.sh
+ chmod +x script.sh
+ ./script.sh
+ git add .
+ git commit -a -m 'Changes pushed by Jenkins'
HEAD detached at ee35229
nothing to commit, working directory clean
Build step 'Execute shell' marked build as failure
Triggering a new build of 2. Erase Answers
Finished: FAILURE

```

# Answer
> 6 votes
In order to get a success, you need to avoid non-zero exit codes. A simple solution would be to change the last line of your script to `git commit -a -m 'Changes pushed by Jenkins' || true`, but better solutions would parse the output of git-add and only run git-commit when there is something to commit.

# Answer
> 11 votes
In my automatic jenkins job, launched daily, if there are no changes the git commit command returns 1. That will mark the build as failed. To solve this problem I use these two commands in my shell build step:

```
git add -A
git diff-index --quiet HEAD || git commit -m "Jenkins automatic update commit"

```
* the first will eventually add all unstaged files in the whole working tree (equivalent to `git add --all`);
* the second will perform the commit if and only if there are differences against the HEAD version of the working directory. If the `git diff` command has exit code zero then the `git commit` command is executed.

# Answer
> 2 votes
I'm going to assume that you have a way to know if the commit is empty or not.

You can use the following code to mark the job as a success instead of relying on error codes.

```
if( some use case ) {
    currentBuild.result = 'SUCCESS'
    echo "Job succeeded."
    return
}

```

You have two options for placement. Putting this inside a stage will exit only that stage as a success. Putting it outside a stage (but inside the node) will end the whole job as a success.

I can't be more specific without knowing your code, but I'd expect something like "make commit, if full continue as normal, if empty build result is success".

---
Tags: jenkins, git, jenkins-pipeline, gitlab, jenkins2
---


# Question
Title: How to trigger Jenkins job by deploying git pipline using webhook?
I have a Jenkins job which I want to trigger after deploying pipeline in Gitlab, Is this possible with webhooks or some other way?

# Answer
I just played with it locally on a "safe network", but it may give you an idea.

I put in `.git/hooks/post-commit` something like:

```
wget --auth-no-challenge --http-user=$USER --http-password=$APITOKEN --secure-protocol=TLSv1 $JENKINS/job/$JOB/build?token=$JOBTOKEN -O /dev/null -o /dev/null

```

You need to create API token in jenkins and grab the webhook url for a given job.
> 1 votes

# Answer
I would recommend using the Generic Webhook Trigger plugin.

You can see a full example with complete Jenkins setup here: https://github.com/github/platform-samples/tree/master/hooks/jenkins/master-branch-protect
> 0 votes

---
Tags: jenkins, gitlab
---


# Question
Title: Push specific changes (defect fix) and not feature changes
I am new to DevOps. I am using Jenkins and GitHub for salesforce deployment.

## Setup

We have a `develop` branch. Feature branches are created out of it. When merged to `develop`, the deployment to the first Salesforce sandbox happens. After end of every sprint the `develop` branch is merged with SIT branch pushing changes to SIT Sandbox.

## Problem Statement

The QA happens in the 1st sandbox for sprint 2. QA also takes place in SIT Sandbox for sprint n-1 features.

1. If an issue is found in the SIT sandbox as part of sprint n-1 testing, the bug is fixed in the `develop` Sandbox
    1. a defect feature branch is created from `develop`.
    2. A fix is added to it.
    3. The branch is merged to develop, fix deployed to 1st Sandbox and tested.
2. If it passes QA, the defect feature branch needs to be merged with the SIT branch to deploy the fix to the SIT sandbox and testing resumes.

## Issue

**Only the fix** needs to be pushed to SIT before the sprint is over and not user story code from sprint 2. But if the fix is made to an apex class or object file, everything is deployed.

**How would one separate the user story code from sprint 2 and defect fix code for sprint n-1 testing when merging to SIT branch?**

# Answer
> 4 votes
This sounds like a problem for `git cherry-pick`. If you can separate the user story code from the fix code, by committing them separately, you can cherry pick the relevant commit to merge back into the `develop` branch.

See https://stackoverflow.com/questions/9339429/what-does-cherry-picking-a-commit-with-git-mean

---
Tags: jenkins, continuous-integration, git, github
---


# Question
Title: How to make a Jenkins API call when using "Log in with Google" as security?
Jenkins API calls are generally made using a username/password combination, or other set of credentials.

We have a Jenkins instance using "Log in with Google" authentication, meaning no credentials are stored in Jenkins for users since login happens with OAuth. I can neither make a new user with creds of my choice, nor view my own credentials to use for the call.

I intend to build jobs using the API, so setting the Anonymous roll to be allowed to build isn't an option. If it matters, my goal is to trigger jobs via an AWS Lambda.

How do I get credentials to use for API calls?

# Answer
> 2 votes
Typically you authenticate API calls (I assume you mean HTTP REST API; there is also a Groovy API) using an API token. The API token can be generated from a user's profile page while logged in as that user (Profile page \> Configure \> API Token). More information about generating and using API tokens is available in the official documentation. There is also a question about API tokens posted to StackOverflow.

# Answer
> 0 votes
I would recommend using the Generic Webhook Trigger... it will allow you to specify a unique token per job and will trigger from a webhook.

---
Tags: jenkins, api
---


# Question
Title: Maximally-self-managed hosting-platforms and OS-and-above containerizators (like Vagrant)
A maximally-self-managed hosting-platform like DigitalOcean/Linode lets a customer quickly create its own VPSE (Virtual Private Server Environment) which includes a common FOSS operating system like Debian, Ubuntu, Fedora, CentOS and so forth.

Besides that, the FOSS community offers a type of software that I can call *OS-and-above containerizator* (like *Vagrant*).

I'm wondering if maximally-self-managed hosting-platforms that gives an operating system to choose and work with makes software like Vagrant totally redundant in case one desires continuous integration.

For example, people who like continuous integration might take this path:

1. Spin up ubuntu/bionic64 box with Vagrant
2. Provision it with Ansible playbook that installs Docker 18.06.1-ce
3. Start Docker container based on mysql:5.7.24 image

Given such circumstances, wouldn't maximally-self-managed hosting-platforms redund the first step thus making software like Vagrant useless in such services?

# Answer
Yes, there are plenty of providers which make the first step redundant; i.e. they give you a working, optimized, running Linux box just by clicking a button, without you having to care how it works. Or they skip the need to have a "box" (VM) running at all. AWS, Azure, GCP, OpenShift etc. all do that, and do it well.

In my neck of the woods, we use Vagrant primarily to get developers up to speed quickly; i.e. to install them a VM which has just the right ingredients needed for development of a specific application (a specific version of whatever compiler, OS packages etc. are needed). This works well because Vagrant leaves the dev with a bog-standard VM, which he can either keep permanently, owning it (e.g., modifying it to set up their preferred editor/IDE right inside, and so on), or for having a throw-away.

Frankly, when we need to spin up many things, Vagrant (or rather: VMs) is just a bit too heavy. We use containers for that; and Kubernetes (and the cloud providers as mentioned) deliver a *much* higher integration than Vagrant, in any case.
> 1 votes

---
Tags: containers, automation, configuration-management, vagrant, servers
---


# Question
Title: What are the correct permission settings when running Docker in a Jenkins Pipeline?
I'm trying to get a new jenkins pipeline together to test new pull requests to our code. I'm using docker with the `ubuntu:14.04` image to simulate our production environment.

Here is a minimum working example:

```
#jenkinsfile
stage('Checkout and provision'){
docker.image('ubuntu:14.04').withRun('-u root'){
    checkout scm
    sh 'chmod -R 770 ./'
    sh './init-script.sh'
    }
}

```

and

```
 #init-script.sh
 sudo add-apt-repository ppa:ondrej/php
 sudo apt-get update -y
 sudo apt-get dist-upgrade -y
 sudo apt-get install \
    apache2 \
    php \
    php-mysql \
    php-xml \
    libapache2-mod-auth-mysql \
    libapache2-mod-php \
    php5-curl \
    zip \
    htop \
    supervisor \
    mailutils \
    git \
    build-essential -y
 sudo apt-get autoremove -y

```

And the `/etc/sudoers` file for the container is as follow:

```
#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults        env_reset
Defaults        mail_badpass
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Defaults:jenkins !requiretty

# User alias specification

# Cmnd alias specification

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d

jenkins ALL=(ALL:ALL) NOPASSWD:ALL

```

The problem I'm having is that docker is not running as root as I'm used to and instead retaining the user id of the jenkins user from the host machine. This makes it difficult to sudo.

I've tried adding the jenkins user to the containers `/etc/passwd` file and running `chmod` against that file but don't even have the permissions to do either of these from the `jenkinsfile`.

With this configuration I should be the root user. However, I either see `Error: must run as root` if I don't use `sudo` or sudo: `no tty present and no askpass program specified` if I do.

Is there a correct way to deal with this situation? Ideally from the `jenkinsfile`; I'd like to avoid creating an additional `Dockerfile` if possible as this will be a further differentiator between testing and production.

# Answer
> 12 votes
So after a debug session in chat what is needed is to allow the user running jenkins to be able to `sudo docker` passwordless on the docker host.

A typical sudoers file on ubuntu could be in `/etc/sudoers.d/jenkins`

```
jenkins_user ALL=(ALL) NOPASSWD:ALL

```

Be warned this allow `jenkins_user` to run as root without password any command, a better file should be:

```
jenkins_user ALL=(ALL) NOPASSWD:/full/path/to/docker
jenkins_user ALL=(ALL) NOPASSWD:<other needed command to be run as root>

```

This will allow to start the container as root and as such it gives all rights within the container itself by running as uid 0.

Useful resources used aside:

# Answer
> 2 votes
It's actually a bad idea to run Docker as root. What you should do instead is add the Jenkins user to the Docker group. `sudo usermod -aG docker jenkins`. That will avoid opening needless security holes and allow Jenkins to do all that it needs to do with Docker, including running as root inside the containers. I do this regularly with my builds, using this as a sample:

```
stage ('Build Docker Image') {
  steps {
    script {
      // Build the Docker image for compiling
      dockerImage = docker.build("myapp:v1")
    }
  }
}
stage ('Run UnitTests') {
  steps {
    script {
      dockerImage.inside("-itu root") {
        sh(script: "nosetests app-test.py --verbose")
      }
    }
  }
}

```

---
Tags: jenkins, docker
---


# Question
Title: Deploy war/ear to a container' marked build as failure
I have Jenkins installed in my system, on which the following are installed:

* Maven Integration Plugin
* Deploy to Container Plugin
* Ant Plugin
* Copy Artifact Plugin
* GitHub plugin
* GitHub Branch Source Plugin

.. and possibly a few others I cannot remember (because coding)...

create new freestyle Project (Deploy-to-staging) project, go to its config, and do the following:

* In Build, select copy artifacts from another project (package):

* In select post build action

In package project, edited its config as follows:

* In General, describe the project.
* In Source Code Management, select Git and enter the Repository URL.
* In Build,Select Invoke top-level Maven Target.

* In post build actions, Select Archive the Artifacts and Build other project.

When I trigger the package build it runs fine and Deploy-to-staging

Build step failed with exception org.codehaus.cargo.container.ContainerException: Failed to redeploy

I get below error when trying to deploy a WAR using Jenkins.

```
    Building in workspace /var/lib/jenkins/workspace/Deploy-to-staging
Copied 1 artifact from "Package" build number 31
Deploying /var/lib/jenkins/workspace/Deploy-to-staging/webapp/target/webapp.war to container Tomcat 7.x Remote with context
ERROR: Build step failed with exception
org.codehaus.cargo.container.ContainerException: Failed to redeploy [/var/lib/jenkins/workspace/Deploy-to-staging/webapp/target/webapp.war]
    at org.codehaus.cargo.container.tomcat.internal.AbstractTomcatManagerDeployer.redeploy(AbstractTomcatManagerDeployer.java:188)
    at hudson.plugins.deploy.CargoContainerAdapter.deploy(CargoContainerAdapter.java:77)
    at hudson.plugins.deploy.CargoContainerAdapter$DeployCallable.invoke(CargoContainerAdapter.java:147)
    at hudson.plugins.deploy.CargoContainerAdapter$DeployCallable.invoke(CargoContainerAdapter.java:117)
    at hudson.FilePath.act(FilePath.java:1077)
    at hudson.FilePath.act(FilePath.java:1060)
    at hudson.plugins.deploy.CargoContainerAdapter.redeploy(CargoContainerAdapter.java:114)
    at hudson.plugins.deploy.PasswordProtectedAdapterCargo.redeploy(PasswordProtectedAdapterCargo.java:93)
    at hudson.plugins.deploy.DeployPublisher.perform(DeployPublisher.java:64)
    at hudson.tasks.BuildStepMonitor$3.perform(BuildStepMonitor.java:45)
    at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:744)
    at hudson.model.AbstractBuild$AbstractBuildExecution.performAllBuildSteps(AbstractBuild.java:690)
    at hudson.model.Build$BuildExecution.post2(Build.java:186)
    at hudson.model.AbstractBuild$AbstractBuildExecution.post(AbstractBuild.java:635)
    at hudson.model.Run.execute(Run.java:1844)
    at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
    at hudson.model.ResourceController.execute(ResourceController.java:97)
    at hudson.model.Executor.run(Executor.java:429)
Caused by: org.codehaus.cargo.container.tomcat.internal.TomcatManagerException: The username and password you provided are not correct (error 401)
    at org.codehaus.cargo.container.tomcat.internal.TomcatManager.invoke(TomcatManager.java:698)
    at org.codehaus.cargo.container.tomcat.internal.TomcatManager.list(TomcatManager.java:876)
    at org.codehaus.cargo.container.tomcat.internal.TomcatManager.getStatus(TomcatManager.java:889)
    at org.codehaus.cargo.container.tomcat.internal.AbstractTomcatManagerDeployer.redeploy(AbstractTomcatManagerDeployer.java:173)
    ... 17 more
Caused by: java.io.IOException: Server returned HTTP response code: 401 for URL: http://localhost:8090/manager/text/list
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1894)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
    at org.codehaus.cargo.container.tomcat.internal.TomcatManager.invoke(TomcatManager.java:571)
    ... 20 more
org.codehaus.cargo.container.tomcat.internal.TomcatManagerException: The username and password you provided are not correct (error 401)
    at org.codehaus.cargo.container.tomcat.internal.TomcatManager.invoke(TomcatManager.java:698)
    at org.codehaus.cargo.container.tomcat.internal.TomcatManager.list(TomcatManager.java:876)
    at org.codehaus.cargo.container.tomcat.internal.TomcatManager.getStatus(TomcatManager.java:889)
    at org.codehaus.cargo.container.tomcat.internal.AbstractTomcatManagerDeployer.redeploy(AbstractTomcatManagerDeployer.java:173)
    at hudson.plugins.deploy.CargoContainerAdapter.deploy(CargoContainerAdapter.java:77)
    at hudson.plugins.deploy.CargoContainerAdapter$DeployCallable.invoke(CargoContainerAdapter.java:147)
    at hudson.plugins.deploy.CargoContainerAdapter$DeployCallable.invoke(CargoContainerAdapter.java:117)
    at hudson.FilePath.act(FilePath.java:1077)
    at hudson.FilePath.act(FilePath.java:1060)
    at hudson.plugins.deploy.CargoContainerAdapter.redeploy(CargoContainerAdapter.java:114)
    at hudson.plugins.deploy.PasswordProtectedAdapterCargo.redeploy(PasswordProtectedAdapterCargo.java:93)
    at hudson.plugins.deploy.DeployPublisher.perform(DeployPublisher.java:64)
    at hudson.tasks.BuildStepMonitor$3.perform(BuildStepMonitor.java:45)
    at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:744)
    at hudson.model.AbstractBuild$AbstractBuildExecution.performAllBuildSteps(AbstractBuild.java:690)
    at hudson.model.Build$BuildExecution.post2(Build.java:186)
    at hudson.model.AbstractBuild$AbstractBuildExecution.post(AbstractBuild.java:635)
    at hudson.model.Run.execute(Run.java:1844)
    at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
    at hudson.model.ResourceController.execute(ResourceController.java:97)
    at hudson.model.Executor.run(Executor.java:429)
Caused by: java.io.IOException: Server returned HTTP response code: 401 for URL: http://localhost:8090/manager/text/list
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1894)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
    at org.codehaus.cargo.container.tomcat.internal.TomcatManager.invoke(TomcatManager.java:571)
    ... 20 more
Build step 'Deploy war/ear to a container' marked build as failure
Finished: FAILURE

```

How can I fix this?

My tomcat credentials, located in \[tomcat directory\]/conf/tomcat-users.xml, are as follows:

```
  <role rolename="manager-script"/>
  <role rolename="manager-gui"/>
  <role rolename="manager-jmx"/>
  <role rolename="manager-status"/>
  <role rolename="admin-gui"/>
<user username="tomcat" password="tomcat" roles="manager-script,admin-gui,manager-gui,manager-jmx,manager-status"/>

```

# Answer
> 1 votes
Quickly going through this it looks like you have added wrong credentials to Jenkins. Can you please check the added credentials first.

```
aused by: org.codehaus.cargo.container.tomcat.internal.TomcatManagerException: The username and password you provided are not correct (error 401)

```

---
Tags: jenkins, maven, java, tomcat
---


# Question
Title: Docker Deployment strategy for microservices project
i am new to the ops side of devops and was hoping for some clarification. Specifically, if in a microservice based project you have multiple jars and each jar gets deployed in a VM on the same hardware, how are you not limiting throughput? if a server only has a fixed amount of processing power and multiple services are competing for those resources, it seems like you are loosing performance. can someone explain how this works?

# Answer
I'll ignore your usage of the word "VM" here, since you have "Docker" in the title and "container" in the tags.

One would indeed not deploy each microservice in their own VM, which would be an incredible waste of resources.

But Docker is different. It is no VM. There is no virtualization. There is no extra layer between the processes running inside the Docker container and the host kernel. There is no significant overhead in the form of RAM usage. It is more or less the same as just running the process without a container.

Docker is based on the concept of namespaces. Modern Linux kernels have namespaces for all their internal data structures (from user IDs to network interfaces to process tables). All aspects regarding accessing kernel ressources/hardware/networking etc. are exactly the same, no matter whether a process runs inside a Docker container or on the host itself. That's the beauty of it, that's also why a docker container spins up very quickly with almost no overhead, and why the actual runtime also has no appreciable overhead.

There is one single difference, which is the filesystem; and this is not due to virtualization of any kind, but due to the "onion" style of layering many filesystems on top of each other. There are options when building images to avoid this, i.e. pack many layers into one, which would alleviate such problems (and conversely, you can mount unionfs-style filesystems in pure Linux as well, and those will have exactly the same performance overhead).

But incidentally his overhead is mostly negligible because something like your standard microservice will load once, and then just run. If you use storage in a container, you usually don't write it into the container itself (though you can), but in a separate volume mounted when spinning up the container; and *those* are like normal Linux mounts, i.e. they have no performance penalty.

TL;DR: Docker has in the most cases no relevant performance penalty at all; namespacing instead of virtualization is the reason why.
> 3 votes

---
Tags: containers, microservices
---


title: Application to run PowerShell scripts

text:
# Question
Title: Application to run PowerShell scripts
I've created a number of scripts in PowerShell that require a number of parameters to be manually entered.

Unfortunately, until we have our Jenkins server setup to support these additional tasks I need to pass these scripts to other technicians.

Ideally I would like an application that could accept the parameters via predetermined fields and dropdown menus then run the appropriate script.

Is there anything already available that would fulfill that need or will I need to knock something up myself?

# Answer
I think the time and effort it will take to set up another tool that performs this type of work will be about the same as it would be to setup Jenkins. If you are looking into a different tool though, I would checkout Rundeck. It is a great tool for creating scripts and allowing other privileged users to execute them. I'm not sure if it will meet your needs for predetermined fields/dropdowns, but there are plugins available that may help.
> 7 votes

# Answer
If you don't care about web UI, you can distribute your powershell scripts as console tasks using Sparrow, you basically just save your Powershell scripts as tasks to a git repository so that users can use it.

Say, you have task, task2, task3 and so on Powershell scripts ( aka tasks ) scattered across different projects ( aka groups ):

# on your machine

```
# 1. convert powershell scripts into sparrow plugins
# and place them to local git repository
# /path/local/repo/plugins directory

# 2. create configurations for your plugins
# as sparrow tasks

sparrow task $project/$task ini

# 3. save tasks to a local git repository
# /path/local/repo/

sparrow task save /path/local/repo/
cd  /path/local/repo/ && git commit -a -m "my tasks" && git push

```

# on target machine

```
# load tasks from a git repository

git clone $repo/powershell-tasks.git powershell-tasks

# install plugins to a local system:

cd powershell-tasks && sparrow plg install $PWD/plugins --recursive --local

# install tasks into a local system:

cd powershell-tasks
sparrow task restore $PWD

# setup and run tasks

sparrow task ini project1/task1 # override default settings

 foo: 1
 bar: 2

sparrow task run project1/task1 # run script as a task

sparrow task ini project2/task2 # override default settings

 foo: 11
 bar: 22

sparrow task run project2/task2 # run script as a task

```
> 1 votes

---
Tags: automation, powershell
---


# Question
Title: Reg uploading additional files in docker hub
Is there any possibilities in keeping additional files in the docker hub account along with docker images.

There is description page, but I want to maintain additional files for each image I planning to upload. Currently bundling the files in the image and retrieving it through creating container from it. It would be great if that option available.

# Answer
> 2 votes
Short answer: No.

Long answer: Docker Hub will keep the **image**. Anything else associated with the image needs to be kept in the source repository linked to the image in the registry.

---
Tags: docker, dockerfile
---


# Question
Title: VAD (Vagrant-Ansible-Docker) stack for Ubuntu and Apache
I'm having trouble establishing a Ubuntu-LAMP environment with continuous integration - I feel lost from the different solutions out there and time and again I fear that my vanilla-Bash Ubuntu-LAMP establishment-program of four different scripts (aimed for maximally-self-managed hosting platforms like DigitalOcean or Linode) will quickly become outdated:

That some or all of the entire system getting vulnerable/unsupported and then I'll have to create another environment with a newer operating system with newer server environment (web/email) and moving manually all web applications and their data to this new environment, which is hard and consuming when I work alone maintaining my own personal web applications.

## VAD (Vagrant-Ansible-Docker)

From all my reading so far I get the impression that a VAD stack (Vagrant-Ansible-Docker) is the only way for me to avoid the problematic state I described above (if I want a VPS environment and not just shared-server hosting platform):

1. Release updates and upgrades for my OS (Ubuntu 16.04 to 18.04 to 20.04 - to whatever version; and `ufw` but without changing my `ufw` directives like `ufw --force enable && ufw allow 22,25,80,443`).
2. Updates and upgrades for all my packages (Apache 2.4-3.4 and so forth; `unattended-upgrades curl wget zip unzip mysql php php-{cli,curl,mbstring,mcrypt,gd} python-certbot-apache ssmtp`, Composer).
3. Docker images will help me automate creation of bare-metal web applications that I would then change credentially to create new web applications.

This way, for example, Ubuntu will go from 16.04 to 18.04 directly and the Apache package will go from 2 to 3 and all my Apache virtual hosts for Apache 2.4 virtual-host files will automatically transduce into 3.x.x format.

This sounds like a sweet dream with the only disadvantage of performance (I'm not sure a 5$ or even 20$ cloud-partition could handle such stack).

## My question

Is my description accurate and if so - what is the common solution that combines these three that I should use (assuming there is some combo which is an industry-standard)?

On the top of such VAD solution, I'll execute much less vanilla-Bash directives (about 25 lines instead 150-200 lines) which will be much easier for me to maintain myself, at least by means of package-management.

# Answer
> 1 votes
I think your research is leading you in the right direction, but I cannot see the value of Docker in here.

I found managing LAMP environments with Ansible completely unproblematic and the scripts I have used for 16.04 only needed a single line changes for upgrade to 18.04. I have also used them on a local development environment and there is no need to have the additional layer and security can be established easily with standard Linux permissions.

I can see the use of Docker, if you need to run the same vhost twice with different configurations on the same bare metal.

With Vagrant, this is a good tool to manage a different technology stack on the same bare metal, for example upgrading to MySQL 8 when at the same time you need to have MySQL 5.7 running on your dev machine at all times for regressions. I have not had this need so far, but can imagine situations where it is useful.

---
Tags: docker, ansible, continuous-integration, vagrant, apache-httpd
---


# Question
Title: Create clean/blank MacOS fs on MacOS or Linux
In developing/testing OSS libraries I can replicate a clean Linux fs using containers. However, if I want to test oss libs for MacOS end users, I seem to be in a bit of a quandary. Is there any way to create a clean fs on MacOS that I can test libraries with? Perhaps using `chroot`? Can someone explain exactly instead of just saying "use chroot"?

# Answer
I don't think you can containerize MacOS, but you could create a Mac OS VM and snapshot it, that way you can easily restore to the same exact Mac OS version for each test.
> 2 votes

# Answer
From what I can tell so far, the best way to replicate a clean MacOS fs on Linux is to use a VM. These instructions should suffice:

https://www.raywenderlich.com/1448-introduction-to-open-source-swift-on-linux
> 0 votes

---
Tags: containers, macos
---


title: phpMyAdmin using dockerised database

text:
# Question
Title: phpMyAdmin using dockerised database
I have installed mariadb inside docker container, and mariadb is running properly inside that container. I want to get access of mariadb through phpMyAdmin from outside docker container.

What will I have to do for that?

# Answer
You need to

1. Expose the server port in the Dockerfile
2. get the IP that the container is listening on (*e.g.* `docker inspect code-rade_cache_1 |jq .[0].NetworkSettings.Networks[].IPAddress` ) -- note that you will need JQ installed on your computer to do this
3. Set the connection in the mysqlphpadmin
> 1 votes

---
Tags: docker, databases, networking
---


# Question
Title: Recommendations about release convention or standard for Python scripts?
I have a lot of python scripts which I release to a python virtual environment on a remote machine. The virtual environment is rarely updated. The scripts are pulled from a git repository and a makefile is used to deploy them into the virtual environment directory.

My question: is there a more normal way to deploy the scripts?

I would like a process that at least remembers which files were deployed for cleanup upon the next release. I've read a bit on pip packaging, but I'm not sure if it fits our setup. The scripts need to be in a common location where they can be called by other applications. The OS is SUSE Linux.

# Answer
One could consider to package the scripts. Depending on the distribution, e.g. ubuntu, windows, centos one could create a ppa, nuget or rpm respectively. Once a newer version is installed, the package manager will remove the previous version automatically.

As yum or zypper could be used to install packages on OpenSuse one could consider to create an rpm by using either spec files or using fpm.
> 4 votes

# Answer
Sparrow makes scripts deployment and distribution simple and super flexible. It is kinda language agnostic system, meaning you can write scripts on *many* languages, Python is included. There is a nice introduction on script distribution with Sparrow.

The only hurdle with your case you will have to adjust existed scripts so that they could be packaged, it's pretty straightforward process though.
> 0 votes

---
Tags: continuous-deployment, release-management, python
---


title: Inspec tests conditional on OS version

text:
# Question
Title: Inspec tests conditional on OS version
What is the idiomatic way to tell Inspec to run test X on OS version A and test Y on OS version B? I'm aware of the technique of dumping the Chef `node` object to a JSON file in `/tmp` but that isn't doing it for me as *that* runs within the Test Kitchen VM whereas Inspec executes on the real host and therefore can't see it.

# Answer
> 3 votes
What I would suggest, like comments under your post, is to take this to the #inspec channel on the Chef Community Slack to ask there. That said, here's how I might attack this:

```
control 'some-control-slug' do
  title 'My control'
  impact 1.0
  desc 'Example code for Stack Exchange'

  if os.windows? && ::Gem::Version.new(os.release) < ::Gem::Version.new('6.1')
    # Only executed on Windows machines older than 2008r2
    describe directory('C:/Users') do
      it { should exist }
    end

  elsif os.windows? && ::Gem::Version.new(os.release) >= ::Gem::Version.new('10')
    # Only executed on Windows Server 2016 or newer
    describe directory('D:/MyFolder') do
      it { should_not exist }
    end

  end

  # Executed on all host types
  describe sys_info do
    its('hostname') { should match(/SomeAwesomeHost/i) }
  end
end

```

Additionally, you can limit the entire inspec control with Chef-like hooks, such as `only_if`. The above example code, as written, may execute on a Linux target. We could limit all of them by placing the following up near the `desc` or `title`:

```
only_if { os.windows? }

```

---
Tags: chef, virtualbox, inspec
---


title: Choice for scheduled task in AWS

text:
# Question
Title: Choice for scheduled task in AWS
I have deployed an AWS Lambda with Python 3.6 and CloudFormation executing a scheduled task which writes a JSON file once a minute to an S3 bucket. Now I wonder if this is a good way of doing it, or if an automation tool such as Ansible would be better suited for the task?

The background is that I am developing a PoC for data analysis.

# Answer
**CloudFormation** is service that allows you to create your infrastructure from code to automate your deployments.

You can set up a rule to run an AWS Lambda function on a schedule by using **CloudWatch event**. https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/RunLambdaSchedule.html
> 1 votes

# Answer
CloudFormation by itself has no way to schedule execution every minute. CloudFormation is great to create AWS resources, like Lambda, but not execute them.

There is another facility in AWS that allows scheduling execution of Lambda functions, it is called “CloudWatch Events”. You can set it to run the Lambda every minute, and you can create the rule for CWE using CloudFormation.

Ansible is similar to CloudFormation in this regard, it can create resources - but has no mechanism to do scheduled executions, only setup some other resource to execute on a schedule.
> 0 votes

---
Tags: ansible, aws-lambda
---


# Question
Title: AWS: Using CloudFront as CDN for non-AWS hosted content
Is there a way (say by providing a Route53 endpoint as origin) to distribute non-AWS hosted content using CloudFront?

(assuming the Route53 is used as dns for a site hosted outside of amazon)

# Answer
CloudFront doesn't care where your origin server is hosted or even who you use for DNS. As long as the Origin Domain Name you provide is resolvable from the Internet (and has valid SSL configuration, if enabled), CloudFront will fetch the content from that origin the same as it will fetch it from anywhere inside AWS.
> 3 votes

---
Tags: amazon-web-services, amazon-cloudfront
---


# Question
Title: What's the difference between "Ops Dev" and "DevOps"?
I've heard both terms, but I can't differentiate between the two.

# Answer
> 2 votes
I've never seen ops dev used before this post. Searching around I see things like this article that has it in the title but nowhere in the article. Then there's this article from 2015:

> So in this way, when “OpsDev” happens, IT ops teams are helping developers do their jobs, but developers are also architecting applications with IT ops in mind, helping them utilize resources better. The days of developers simply creating applications and “throwing them over the fence” to testers and IT ops teams are over.

which seems to define OpsDev as "development in a company that practices DevOps" (or more cynically, "development done correctly").

Finally, there's https://dzone.com/articles/opsdev-is-coming :

> What Is OpsDev? OpsDev means that the dependencies of the various application components must be understood and modeled first before the development process begins. In addition, the consideration for infrastructure stability, environment modeling, security and audit/compliance measures are first and foremost. Application components are stubs and they do not need to be in their final forms. Secondly, the environments in which the components will be deployed for production must be modeled. Thirdly, the processes to deploy the various components to the target environments must be automated as much as possible.

Again, this sounds to me just like normal, modern development.

DevOps is a problematic term because it has many different definitions. OpsDev, on the other hand, appears to have essentially *no* definitions. From a personal perspective, I would mentally substitute "development" for every instance of "OpsDev" and ignore the term; it appears to be just another instance of people inventing new terminology to describe old concepts so that they sound more exciting.

# Answer
> -1 votes
*In the operations team **DevOps** does not trust developers to make changes to the production infrastructure*. Developers want to focus on their application and the value it delivers to the organization. Developers want to know the characteristics of the infrastructure but do not want to build it or operate it.

The operations team is absolutely critical to the success of DevOps methodologies.

The developers must be able to trust that the infrastructure has specific characteristics: characteristics like performance, connectivity, availability, and uniformity.

To enable this trust, I believe that the operations teams are going to need to become more like developers. I call this **OpsDev**.

**OpsDev is not simply about having a scripted build for servers. OpsDev is about having a full infrastructure that is built and maintained automatically from a set of source-controlled configuration files, and then having development and test environments that are built using the same methodology.**

Source: https://www.astroarch.com/tvp\_strategy/devops-requires-opsdev-time-change-35139/

---
Tags: terminology
---


# Question
Title: Automating the creation of an Apache virtual-host file specifically
When I create new web applications on my up-2-date Ubuntu-LAMP with Apache 2.4.x environment, I create their virtual-host files this way:

```
s_a="/etc/apache2/sites-available/"
s_e="/etc/apache2/sites-enabled/"

read -p "Have you created db credentials already?" yn
case $yn in
    [Yy]* ) break;;
    [Nn]* ) exit;;
    * ) echo "Please create db credentials in then comeback;";;
esac

read -p "Please enter the domain of your web application:" domain_1 && echo
read -p "Please enter the domain of your web application again:" domain_2 && echo
if [ "$domain_1" != "$domain_2" ]; then echo "Values unmatched. Please try again." && exit 2; fi

read -sp "Please enter the app DB root password:" dbrootp_1 && echo
read -sp "Please enter the app DB root password again:" dbrootp_2 && echo
if [ "$dbrootp_1" != "$dbrootp_2" ]; then echo "Values unmatched. Please try again." && exit 2; fi

read -sp "Please enter the app DB user password:" dbuserp_1 && echo
read -sp "Please enter the app DB user password again:" dbuserp_2 && echo
if [ "$dbuserp_1" != "$dbuserp_2" ]; then echo "Values unmatched. Please try again." && exit 2; fi

cat <<-EOF > "$s_a/$domain_2.conf"
    <VirtualHost *:80>
        ServerAdmin admin@"$domain_2"
        ServerName ${domain_2}
        ServerAlias www.${domain_2}
        DocumentRoot /var/www/html/${domain_2}
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
    </VirtualHost>
EOF

ln -sf "$s_a"/"$domain_2".conf "$s_e"

```

## My question

Is there a way to automate that / shorten the amount of lines code (the actual script-file is much bigger in principle), maybe even from some built-in behavior in Apache itself and without involving further software?

If other software might be needed than from what I've read so far it should be Docker and I should look for an Apache-virtual host **docker script** that will be based on my variable declarations (in dockerhub) which I will then run with a `docker` command, but maybe Apache itself will have automation functionality for this or there is some third solution the answer's my need?

# Answer
> 2 votes
This has already been covered a bit in the comments, but I figured I'd lay out a more extensive answer.

> Is there a way to automate that / shorten the amount of lines code (the actual script-file is much bigger in principle), maybe even from some built-in behavior in Apache itself and without involving further software?

You can use `a2ensite` as a replacement for your very last line, the `ln`; all it does is set up symlinks into `/etc/apache2/sites-enabled`, which is where Apache httpd looks by default for configuration. Some details may vary by distribution.

However, this only changes your script a tiny bit. There are much larger problems you have to address.

First, I'll mention that no, Docker is almost certainly not the solution you want. Docker works best when used in a container orchestration layer like Kubernetes, and while I can easily imagine an architecture with a single Docker image that takes in parameters to create different vhosts, it's a much more complicated system than your presumably one-host system and requires substantial changes to how everything works. Docker is a hip new thing, but what many people do not realize is that it solves a set of well-understood problems and creates a set of new, poorly-understood ones, and it's likely that you don't have the problems that such an architecture would solve. So let's set that aside for now.

The first problem you have is that you're writing Apache configuration (primarily) by hand, with templating in bash and limited validation. In reality in your example this isn't a big deal since it's a small and simple config, but it's easy to start this way and end up with a large block of `sed` and `ed` commands (this I know from experience).

The larger problem is in how ephemeral your changes are. You configure all these vhosts, great. Then your server dies. What happens? You're probably going to spend a lot of time trying to rebuild it. Hopefully you have a recent backup to help, but the point here is that the last few decades we've settled into this idea of treating configuration the same way as code \- rather than setting things up by hand, you write all of your configuration into text files and a program translates that into configuration on the server. This has a multitude of benefits, including backups, code review, and a history of changes that you can look back on. Most configuration management tools also provide convenient abstraction layers. Here is an example that lays out how to translate an Apache vhost file into an Ansible template, and then you only need to add new entries to the variable list and rerun the configuration. When it comes to things like your database passwords, those too can be stored and version-controlled in Ansible Vault or a similar product.

---
Tags: docker, bash, php, apache-httpd
---


title: How to monitor a REST call response?

text:
# Question
Title: How to monitor a REST call response?
My project is using customer.io to send emails in different flows.

Every now and then we have a bug, and one of those calls stops and email is not sent.

I want to get alerted when an email is not sent in the last 24 hours. It would be great if the solution could give me alert on any spike but the mvp is 0 in the last 24 hours.

What is the best way to do it?

Currently, I am trying to use some process to poll customer.io REST API which provides exactly the information I need.

```
[{
    "campaign": "Hello",
    "sent": 0 // This should trigger an alert. sent is for last 24 hours
}, {
    "campaign": "World",
    "sent": 1 // should not trigger an alert
}]

```

Then to do some ETL on this, and feed some data source (maybe cloudwatch, haven't decided yet), and then hook grafana to give me alerts on any spikes.

I am new to this field and am wondering if I am going the right way and if there's a better/easier way to tackle the problem.

== Update - I found out about Grafana SimpleJSON plugin but it expects me to be the owner of the backend. I am going to write some lambdas and use gateway (basically implement an ETL) and use SimpleJSON plugin from grafana to get things going.

# Answer
> 1 votes
There's no generic answer to this, but a ton of options. Usually the right choice for you would be dependent on what monitoring and alerting stack you're already using.

For instance, if you are using Graphite, Prometheus, rrdtool, or any other round-robin database to record a metric when you're sending out emails, those all have APIs that allow you to query them across a time range to see what the values were. And depending on what alerting system you're using (Nagios, Icinga, Sensu, etc.) there is probably already a plugin that allows you to easily interact with that particular metrics database.

From another perspective, if you're logging when you send emails, then a log system like ELK will allow you to search and see if any of those log lines are found. Again, the various alerting systems will have plugins to most common log systems. (There are also individual systems designed purely for those tools, like ElastAlert with its flatline type for ELK.)

Thirdly, you could approach it the way that you are, by checking in with customer.io's API on a regular basis. But no, there is not one standard tool for doing this, but rather one (or at least one!) per alerting system.

Finally, you might consider doing **synthetic checks** instead of or in addition to your real-user monitoring. This means having an automated test that performs actions that you expect to result in sending an email, and then checking to see that an email gets sent.

---
Tags: monitoring
---


# Question
Title: How can I diagnose php cli command execution time inside a docker container
I've recently migrated an event subscription service called by a bash script from Ubuntu, into a Dockerised container.

The Docker image I am using is: `FROM php:7.1-apache`

The script itself is pretty straightforward:

```
#!/bin/bash

DIR="$(dirname $0)"
OUTPUT=""

while true
do
    OUTPUT=""
    OUTPUT=$OUTPUT$(php $DIR/../bin/cli.php bash:v1:issueEvents)
    OUTPUT=$OUTPUT$(php $DIR/../bin/cli.php bash:v1:processCustomerAccountEventSubscriptions)
    OUTPUT=$OUTPUT$(php $DIR/../bin/cli.php bash:v1:processProductionOrderEventSubscriptions)
    OUTPUT=$OUTPUT$(php $DIR/../bin/cli.php bash:v1:processWebEnquiryEventSubscriptions)
    OUTPUT=$OUTPUT$(php $DIR/../bin/cli.php bash:v1:processWebOrderEventSubscriptions)
    OUTPUT=$OUTPUT$(php $DIR/../bin/cli.php bash:v1:processWebQuoteEventSubscriptions)

    if [ -z "$OUTPUT" ]; then
        sleep 10
    fi
done

```

A complete round trip from event subscription to processing would take about 30 seconds on the host OS. Inside a container it is taking around 10 minutes.

My initial suspicion was that DNS was slowing things down, but I've installed `dnsutils` and the lookup times are the same both inside and outside the container.

I'd like advice regarding how I'd go about investigating the cause of this slowdown.

# Answer
> 1 votes
The general process of debugging inside the container is the same as debugging outside of one. The only thing that you generally need to know is that you can use `docker exec` to attach a bash shell inside a running container, or override the command with `--entrypoint` to launch bash instead, and then run the script manually.

At that point, your question becomes "How do I debug slow execution times in a PHP script?". That is not really in scope for this site, but you can start with a few basic things: add print statements or attach a profiler to see where things are getting slow, and then narrow it down from there.

---
Tags: docker, php, bash
---


# Question
Title: Multi-container server of PHP apps with reverse proxy?
I am going to deploy my app to production on VPS server, using Docker. My goal is stable version from latest tag at `example.com`, and dev version from dev tag at `dev.example.com`.

Because this is an PHP application, container has own nginx+php set. I don't know how - if it's even possible (without Swoole in PHP etc.) to avoid this.

Problem is in resources - I see that each app container has own nginx instance, and server (VPS) must have global nginx, working as reverse proxy for containers.

Is there are any better way to archieve my goals? Thanks!

# Answer
> Problem is in resources - I see that each app container has own nginx instance, and server (VPS) must have global nginx, working as reverse proxy for containers.

Generally speaking yes, this is how this sort of thing goes. It's more of an issue for PHP than other languages because PHP doesn't really have a standalone application server, but instead is commonly deployed using php-fpm with nginx. Since php-fpm supports communication via TCP sockets, theoretically you could run only fpm in the containers and have nginx on the host talk to fpm across the Docker networking layer, but I haven't researched this option enough to be convinced it would work.

Docker makes the most sense when used within the context of an orchestration layer like Kubernetes. Rather than running several Docker containers manually or semi-manually on a particular host, you would schedule them with kubernetes and it would distribute them across its cluster of nodes - the specific machine that runs the container becomes irrelevant. The kubernetes service then provides you with an IP via kube-proxy that load-balances across the pods of that service.
> 1 votes

# Answer
you can run one container serving Nginx for others, a container is no different from a server/VM if there is not a specific reason for each container having Nginx. you should clarify why you have one global Nginx and other nodes having Nginx, assume you do not have containers. You say the problem is resources, I am not sure your problem is the way Nginx work or with your design.
> 0 votes

---
Tags: docker, nginx, php
---


title: DNS server with api access

text:
# Question
Title: DNS server with api access
Experts, i have a requirement and wanted to find a tool that will be helpful for me.

We have a inhouse tool, that will help developers request/lease a VM for a short duration of time. When the VM is assigned, i send the developer an email with details of the VM and the application details. I currently use xip.io to send a fully qualified DNS name. Something like this

https://omni.54.84.86.26.xip.io

https://auth.54.84.86.26.xip.io

https://mgmt.54.84.86.26.xip.io

This works well, but the feedback that i got from my developers is ,

```
The url is very hard to remember

Everytime is request for a VM i get a new URL and i cant bookmark it. it keeps changing everytime.

```

I think their concern is valid. One idea to solve this is to create a per defined DNS names with username in it like

omni-prajan.myorg.com

admin-prajan.myorg.com

mgmt-prajan.myorg.com

where prajan is the username. So everytime i request for a vm, i need to programmatically modify IP that is associated with this domain name in my dns server. We are using AWS now.

Is there a better way to handle this requirement?

# Answer
Route53 has an API for creating DNS records. The API is a bit obtuse, but there are a plethora of wrappers for various languages.
> 1 votes

---
Tags: dns
---