Suggestions to improve knowledge on docker I am new to Docker and tried some hands-on (not deeper learned upto basics of image,container) by following docker official documentation.

To take my learning curve to next level, I have implemented what I read by taking sample applications like "Dockerising a Node.js and MongoDB App by nida sajid", run a sample java restful webapplication which takes name and
email and storing it into mysql container. I've done this by using 2 containers:

tomcat - Used to deploy war file
mysql - To store the data(name&email))

My question: what are the advanced concepts that I can learn and, can you suggest me so that I can improve my knowledge

What are the advanced concepts in docker other than this (like used in real world scenario)?
Any suggestions (like websites,videos) to improve my knowledge?
How to use Docker with Jenkins?

Some good next topics for the real world are...

Security. There are several security concerns with docker, for example

Is there a problem running stuff inside the container as root?
Is there a problem giving non-root users on the host access to the docker daemon?
Is there a problem with the docker daemon running as root on the host?
All three can be solved with docker out-of-the-box. Learn how to.

Networking. Check out the docker networking options.
Image sizes are a recurring problem, especially if you build your stuff inside a docker image. Your average naive first build image may be 1GB or more - try to get the same image, whatever it is, to 500, 300 or 200 MB.
Docker volumes; how to get configuration into your containers; etc.
Private artifact repositories.
Explore the environment: docker compose, docker swarm, etc.
Finally, take  a big leap on to your next technology... OpenShift? Kubernetes?


openstack instance metadata With Openstack Nova CLI I could set or get instance metadata with nova meta set/get ... but with the  openstack "all-in-one" CLI that option does not exist.

Is it possible to work with instance metadata with the openstack client?

PS: Someone with privileges to create tags could create openstack , openstack-nova and openstack-cli ?

Just browsing through the available options, it looks like the nova meta actions may be available as openstack server set:

$ openstack help server set
usage: openstack server set [-h] [--name <new-name>] [--root-password]
                            [--property <key=value>] [--state <state>]
                            <server>

Set server properties

positional arguments:
  <server>              Server (name or ID)

optional arguments:
  -h, --help            show this help message and exit
  --name <new-name>     New server name
  --root-password       Set new root password (interactive only)
  --property <key=value>
                        Property to add/change for this server (repeat option
                        to set multiple properties)
  --state <state>       New server state (valid value: active, error)

E.g., if I run:

openstack server set myserver --property foo=bar

And then run:

openstack server show myserver

I see:

[...]
| properties                           | foo='bar'                                                |
[...]


Continuously getting locked out from EC2 instance. No supported authentication methods available I am getting continously locked out from my ec2 instance time and again. I have to take its root volume and attach it to some other instance (mostly new instance) to prevent data loss. I am not able to figure out what is causing my ssh being denied. It works for sometime and all of a sudden ssh is denied. I have tried

Comparing the authkeys with my login key. It is same.
Copying the key from a ssh working instance to this volume and re-launching. Same error.
Did some tweaks in sshd_conf and ssh_conf but to no success.

I am completely stumped here, any viewpoints on this.
I have been working on AWS for sometime now and never encountered this problem, the only change being the organsation (and the network) has changed from where i am working from? Can their network be generated some kind of DOS attack which is just shutting down my ssh access?
My team does not have an official AWS tech support plan, hence here.

Although i have not found out what leads to this. But i am finally able to login into my instance by following these steps:
1. As you are logged in create a user in the instance and give it a password.

$ adduser user1
$ passwd user1

2. Enable password authentication in /etc/sshd_config file.
3. Login with the new user.

Interestingly, this user does not gets locked out as the centos user.


Monitor Jenkins node/slave health For a project I'm working on, we need to create a Jenkins node in an AWS environment. For this task,  we will work with the docker image, which is available on https://github.com/jenkinsci/docker-ssh-slave
. The Jenkins node will be responsible for executing AWS commands which can only be done from inside the AWS environment (not outside).
This Jenkins Master is running in our local environment. We will add the node as a permanent node in the Jenkins master. The Jenkins master is not responsible for setting up the Jenkins Node, since it has no permissions to do this ( this is managed in AWS ).
However, we would like to monitor the Jenkins Slave inside AWS to see if it it still running successfully. With other docker containers, we also expose a health check. If the health check fails, the docker container is treated as unhealthy, and is restarted accordingly.
Just like we do with the other docker containers, we would like to expose such a health port as well on the Jenkins Slave. If it is not responding anymore, AWS will restart the docker container, and we have a stable system.
We already explored the Nagios monitoring, but it looks like this is exposing the health in the master, and not directly in the slave.
Is it available, or how can we add such functionality?
Could you lead us in the right direction, or recommend plugins which need to be installed, ...

Can we open the default HTTP API of Jenkins in such a Jenkins slave (https://wiki.jenkins.io/display/JENKINS/Remote+access+API)
Another approach could be to add and start NGINX in docker and point the healthcheck to NGINX. But with this approach, we are not really checking the health of the the Jenkins slave.

To me it looks like you are trying to reinvent the wheel. As I understood you would like to restart a container if a health check fails. As you are using docker you should use a orchestration platform in my opinion like Fargate (ECS) or Kubernetes (k8s). I know from the latter that it is possible to define healthchecks, like readiness and health probes. If the health check fails, kubernetes will restart the POD (auto healing).

It could be possible that you would argue that k8s is not an option. If that is the case, you could also have a look to AWS OpsWorks. Although I did not try it myself yet, it is able to perform auto healing as well.


SQS: What could high number of visible messages mean if messages received & deleted are normal? I'm new to SQS.
I recently noticed the ApproximateNumberOfMessagesVisible in my SQS queue started rising. What was interesting though is that there was no sudden surge in the number of messages received or depression in number of messaged being deleted from the queue that corresponds with this surge.
NumberOfMessagesSent

NumberOfMessagesReceived

NumberOfMessagesDeleted

ApproximateNumberOfMessagesVisible

Increasing the number of SQS workers temporarily drained this queue, but what could be possible reasons for this increase?

there was no sudden surge in the number of messages received or depression in number of messaged being deleted from the queue that corresponds with this surge

Yes, it looks like there was.

But first, be sure you have the correct definitions in mind for these metrics, because your intuitive interpretation might be reversed.

"Sent" means sent to SQS and added to the queue (it does not mean sent to consumers) and "received" means delivered to a consumer (it does not mean received by SQS).

Beginning at approximately 1600 on January 3 there is an unexplained dip in "received" performance.  The consumers slowed down and accepted messages at a slower rate, despite the fact that the available messages did not justify that reduction, suggesting that the consumers were not able to process messages at their typical rate.

Beyond this point, the messages "sent" (enqueued) continued its undulating pattern, but the messages "received" (dequeued) and "deleted" (after processing) assumed a much flatter pattern, despite the fact that they had previously been following the same visual pattern as the "sent" value.

It appears that your consumers have slowed down, for external reasons (probably unrelated to SQS -- something else the consumers communicate with, like maybe a database, is not responding as quickly as usual), and so the consumers are no longer able to keep up with the offered workload, and a backlog is growing.  "Visible" messages are the messages in the queue that are waiting for an available consumer to be ready to receive them.

Theoretically, it could be that this is an internal performance problem inside SQS, but this seems very unlikely so I'd suggest that your consumers and the components of your stack that they interact with should be the focus of your troubleshooting.


Is there a policy that can limit the growth of an AWS S3 buckets total size? We have an AWS S3 bucket that accepts uploads from untrusted sources which are then processed and moved out of the bucket.

Is there a Policy that can limit the growth of the bucket to some predetermined upper bound to protect us in case something goes wrong?

Not as far as I know.

You can create Billing alerts to get notifications when AWS thinks that your monthly spend may be over a given threshold.


Module directory modules/queues.tf does not exist or cannot be read I am trying to setup terraform with modules and when doing terraform init after creating a module I have ran into an issue where I am told it does not exist or can't be read. I've checked many times and tried many paths to it and it does exist where I think it does.

Not sure in that case why it can't be read. I've included my main.tf file as well as the modules/queues.tf file

main.tf
  | main.tf
  | modules
     | queues.tf

main.tf

# This file brings together all of the modules
variable "environments" {
  type = list(string)
}

module "pae_queues" {
    source = "./modules/queues.tf"

    environments = "${var.environments}"
}

queues.tf

variable "environments" {
  type = "list(string)"
}

resource "aws_sqs_queue" "email_queue_${var.environments[count.index]}" {
  count = length(${var.environments})
  name                      = "email_queue_${var.environments[count.index]}"
  delay_seconds             = 0
  max_message_size          = 2048
  message_retention_seconds = 86400
  receive_wait_time_seconds = 10
  redrive_policy            = "{\"deadLetterTargetArn\":\"${aws_sqs_queue.terraform_queue_deadletter.arn}\",\"maxReceiveCount\":3}"

  tags = {
    Environment = "${var.environments[count.index]}"
  }
}

A Terraform module is represented by a whole directory, not an individual file. If you create a directory ./modules/queues and move ./modules/queues.tf to ./modules/queues/queues.tf then you can call that module like this:

module "pae_queues" {
  source = "./modules/queues"

  environments = var.environments
}


Can I create an Azure VM from Ansible with NICs in different resource groups? I am working on creating an Ansible playbook to

Ensure required network resources for an Azure VM are present, and
Create an Azure VM attached to those resources.

Due to the way the organization is structured, all network resources (such as NIC, NSG, Subnets and Public IPs) are placed in a Networks Resource Group in Azure. And these are managed by a separate team.

Also, the mandate is to create the Azure VMs and all non network resources in a separate resource group (let's call it AZRVMRG.

The chunk of the playbook that creates the VM looks like this:

---
- name: "Create VM {{vm_type}} - {{name}}"
  azure_rm_virtualmachine:
    resource_group: "{{rg_name}}"
    name: "{{name}}"
    vm_size: "{{size}}"
    admin_username: "{{user}}"
    admin_password: "{{pass}}"
    os_type: "{{os_type}}"
    network_interfaces: "{{nic_name}}"
    image: "{{image}}"
    tags: "{{tags}}"

Where {{rg_name}} is the AZRVMRG RG, and {{nic_name}} is an existing NIC present in the Networks RG.

Question

How do I reference the NIC present in the Networks resource group while creating the Azure VM within AZRVMRG resource group?

What I've tried

I have tried "just" referencing the NIC name, but that gives me an error similar to:

 "msg": "Error fetching network interface AZRVMNIC - Azure Error: ResourceNotFound\nMessage: The Resource 'Microsoft.Network/networkInterfaces/AZRVMNIC' under resource group 'AZRVMRG' was not found."

So clearly, its looking under the same resource group.

Notes

(I have seen VMs created in the Azure subscription this way, so this is possible in Azure. But Ansible does not document this approach in its official docs. )

From close reading of the Ansible doc page on creating Azure VMs, it's clear that you can refer to a resource such as a virtual network or NIC using its resource ID.  This lets you specify any resource, just like RM templates.

To specify a NIC created in another resource group by the networking team, with the networking_rg_name var set to that group name, you would use a resource ID like this:

- set_fact:
    nic_id: "/subscriptions/{{ subscription_id }}/resourceGroups/{{ networking_rg_name }}/providers/Microsoft.Network/networkInterfaces/{{ nic_name }}"

- name: "Create VM {{vm_type}} - {{name}}"
  azure_rm_virtualmachine:
    resource_group: "{{rg_name}}"
    name: "{{name}}"
    vm_size: "{{size}}"
    admin_username: "{{user}}"
    admin_password: "{{pass}}"
    os_type: "{{os_type}}"
    network_interfaces: "{{nic_id}}"     # Use the nic_id instead of name
    image: "{{image}}"
    tags: "{{tags}}"

This works for any resources that are in a different resource group, including virtual networks.


Can we reuse Variables across variable groups in Azure DevOps? I'm using DevOps to deploy Azure Data Factory ARM template

I'm using a deployment pipeline to take artifacts from a prior build pipeline and deploy to various environments (TEST, PROD)

I've created two variable groups: TEST and PROD. I've created two deployment "stages" TEST and PROD

Within the TEST variable group I've created a bunch of variables reflecting the TEST specific configuration.

As far as I understand, I now have to manually recreate all of these identically named variables in my PROD variable group.

Not only that I have to make a copy of my TEST stage

So I basically have two duplicate configs and two duplicate stages

It would make more sense if I had a single stage definition that could be run against different variable groups rather than repeating code and variable group definitions.

It seems strange and redundant to have to do this. I also find it strange that the concept of environments is not specifically called out in doco anywhere

So the specific question is: Is it the correct approach to define a variable group per environment then manually create identical variables in both variable groups?

and a more general question: am I missing something fundamental here or is the product not mature enough yet.

I have not used any other deployment tool in any detail before this and I'm not using YAML (just the UI) so maybe that's the piece I'm missing.

Another "What Am I missing" thing:

In the Resource Group deployment task in the override template parameters field I used the UI to assign variables to parameter values. I had to type the variables in and had to make sure I got the magic notation right. $(myVariable) Then I read another stack overflow that indicated if your variable value has a space in it you need to surround it by quotes. This is the second "you need quotes for spaces" issue I have found.

My understanding of the variable groups is that you would create this to leverage the same variables across multiple pipelines.  If you needed to update the value, you'd only have to update it on the library instead of updating it on dozens of pipelines.  If you are only going to use the variable group on a single pipeline definition, variables groups appear to be overkill.

If you have concerns about duplicating code and maintaining the exact same deployment steps across your stages, I would recommend you group them into a task group.  That way you can manage versioned updates and will also have it reflected across all pipelines and stages where it is referenced.

I think you would have some name resolution issues if you tried to use the different variable groups that have the same name on a single pipeline.  Instead, you should probably leverage the variable scope on the pipeline.  It will grab the appropriate value staged to the scope you are executing.


Conversion tool for converting kubernetes yaml files from 1.15 to 1.17? we are on kubernetes 1.15.* and our yaml files are incompatible with the latest 1.17 installation.

Is there an easy way of converting our yaml files with a tool?

You can try the kubeyaml validator. It doesn't convert the yamls but it does show the exact errors for incompatible yaml for each version.


What is the simplest way to list which attached disks are encrypted (and which not) on AWS? An auditor is asking for proof that we've encrypted all the disks on our AWS EC2 VPC. I'd like a way to list all the disks and whether they're encrypted or not.

I know I can build a report with the AWS API (or the CLI) - but I was looking for a simpler approach than that, hopefully with the console.

My question is: What is the simplest way to list which attached disks are encrypted (and which not) on AWS?

To get the number of non encrypted volumes you can run this command:

aws ec2 describe-volumes --region <your_region> --filter "Name=encrypted,Values=false" --query "length(Volumes[])"

length will return the length of the array Volumes flattened by the selection operator [] (more details on JMESPath documentation).
As we filter the slection for non encrypted volumes (--filter "Name=encrypted,Values=false") this should allow to demonstrate to the auditor the number is 0 not encrypted volumes.

Same filter can be applied in the console, in the ec2 page, under 'Elastic Block Store' => 'Volumes', type Encrypted : Not Encrypted to filter the view to non encrypted volumes only. you may add Attachment Status : Attached to list only attached volumes.


Can't connect to my dockerized MySQL I'm trying to implement this pre-cooked package of NGINX, PHP-FPM, MySQL, E-L-K.
Everything is working fine but the connection with the database. It throws a ConnectionException.
I'm not really sure if the program should try to access 172.18.0.4 instead of 172.18.0.3, and where does this configuration comes from.
The IPs of my containers are:

/dockersymfony_elk_1 - 172.18.0.2
/dockersymfony_nginx_1 - 172.18.0.5
/dockersymfony_php_1 - 172.18.0.3
/dockersymfony_db_1 - 172.18.0.4

The error:

[Doctrine\DBAL\Exception\ConnectionException]
An exception occured in driver: SQLSTATE[HY000] [1045] Access denied for user 'root'@'172.18.0.3' (using password: YES)

What could be happenning? Is there a way to check a mysql connection manually?

Since the response is Access denied for user so the port and the ip address is correct.

I guess the only issue as @James said  will be in the permission, you have to allow root access to mysql from elk and php containers, you can do it in easy way but it's not secure:

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'password';

%: mean match all

or you can specify who has the access per domain name or ip:

GRANT ALL PRIVILEGES ON *.* TO 'root'@'172.18.0.2' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'172.18.0.3' IDENTIFIED BY 'password';

PS: don't forget to change the password to match you root password


How to use cloud-init with Terraform? I am working with Digital Ocean and Terraform and I already can automate the domain, subdomain, network preferences and the host but there is a section called User data that looks like this:

The description of that field says Allows the use of Cloud-init to configure your droplet. Looking around I found the documentation.

How to take advantage of this while using Terraform?

Cloud-init files are essentially bootstrap codes, that run before each startup, and can - among others - modify files, set up services, create users, etc.

Not all types of droplets support all functionalities of cloud-init, for example CoreOS uses it's own implementation, with a very limited subset of valid values.

To use this in terraform, simply provide the cloud-init file during droplet creation:

main.tf:

resource "digitalocean_droplet" "web" {
  image              = "coreos-stable"
  name               = "web"
  region             = "lon1"
  size               = "2gb"
  private_networking = true
  ssh_keys           = ["${digitalocean_ssh_key.dodemo.id}"]
  user_data          = "${file("web.conf")}"
}

web.conf:

#cloud-config
coreos:
  units:
    - name: "etcd2.service"
      command: "start"
    - name: "fleet.service"
      command: "start"

This will for example create a droplet, where CoreOS will run etcd2 and fleet during startup

You can find some more examples in this repository, where I show how one can use these configuration options to set up some simple docker based services on CoreOS


How can I make use of bash functions in a makefile? If I need to use something like NVM in my makefile, I run into a problem, because NVM exports some bash functions that are not available in Make, even if my shell is defined as bash in the makefile.

How do I cause make to "inherit" all the parent shell's functions? Is there a way to make NVM accessible to a makefile, without writing export -f for a zillion little NVM bash functions?

There are several options that can be used here. Maybe one of the easiest is to install each function as a real script in some directory that is added to the path.  Here is how to do this:

First, we choose a path name where to store all these functions, it can be a a directory in our project, where other utility scripts used in our Makefile live. We call it nvm_install_dir

Then we write a _nvm_trampoline script which use the name it is called as to trigger the right function, and create as many file aliases to _nvm_trampoline  as there are functions in the script.  Note the leading underscore, hinting at the “private” character of the script.

This script can go along the lines of

#!/bin/sh
. "${NVM_DIR}/nvm.sh"

if [ "${0##*/}" = '_nvm_driver' ]; then
    : NOP
else
    eval "${0##*/}" "$@"
fi

Here we use ${0##*/} to remove any path element from the name under which our script is called.  We install that script under ${nvm_install_dir} and run once the following utility script:

nvm_install_dir='SET-TO-ACTUAL-PARAMETER-VALUE!'
nvm_file="${NVM_DIR}/nvm.sh"
nvm_trampoline='_nvm_trampoline'

nvm_list_functions()
{
    awk -F'[(][)]' '$1 ~ /^nvm_[^ ]*$/{print($1)}' "${nvm_file}"
}

nvm_install()
{
    nvm_list_functions | {
        while read nvm_function; do
            ln\
                "${nvm_install_dir}/${nvm_driver}"\
                "${nvm_install_dir}/${nvm_function}"
            chmod 755 "${nvm_install_dir}/${nvm_function}"
        done
    }
}

nvm_install

It is a good practice to pack the nvm_install procedure in a real function instead of just inlining its body in the script, as it gives better testing options. (It is easier to comment out the call to nvm_install than the body of the function, if we want to experiment with the script.)

Ater this, the directory pointed to by nvm_install_dir is populated with aliases to _nvm_trampoline that are executable and delegate their work to the corresponding function. We only need to add this directory to our PATH when running make.

A second approach would be to generate pseudo commands for each nvm functions, with the following script:

nvm_file="${NVM_DIR}/nvm.sh"

nvm_list_functions()
{
    awk -F'[(][)]' '$1 ~ /^nvm_[^ ]*$/{print($1)}' "${nvm_file}"
}

nvm_generate()
{
    nvm_list_functions |  {
        while read nvm_function; do
            nvm_FUNCTION=$(printf '%s' "${nvm_function}" | tr '[a-z]' '[A-Z]')
            printf '%s=sh -c \047source "${NVM_DIR}/nvm.sh"; %s "$$@"\047 %s\n'\
                   "${nvm_FUNCTION}"\
                   "${nvm_function}"\
                   "${nvm_function}"
        done
    }
}

nvm_generate

The output of this program consists of make variable assignments

NVM_ECHO=sh -c 'source "${NVM_DIR}/nvm.sh"; nvm_echo "$$@"' nvm_echo
NVM_CD=sh -c 'source "${NVM_DIR}/nvm.sh"; nvm_cd "$$@"' nvm_cd
…
NVM_COMMAND_INFO=sh -c 'source "${NVM_DIR}/nvm.sh"; nvm_command_info "$$@"' nvm_command_info
…

It can be saved to a file Makefile.nvm or nvmtools.mk that can be included our Makefiles. Calling the function nvm_command_info is done with

${NVM_COMMAND_INFO} arg1 arg2 …

Using a customised bash profile is possible, using the assignment SHELL=/bin/bash --rcfile PATH-TO-CUSTOM-PROFILE -i but I would consider this esoteric enough to puzzle the maintenance programmer.


Multiple Kafka brokers behind a single OpenShift service? Is it possible to have several brokers behind a single TCP/IP port?

I.e., offer a single endpoint for Kafka clients, and having a scalable amount of brokers behind that?

In my company, some people are configuring a (scaling) Kafka server for us, and they insist that this is not possible, and that we need to configure every single broker as a separate endpoint...

This is in a OpenShift context; it would be nice to just be able to scale the Kafka pods up and down as needed, while using the usual loadbalancing to offer a single port to the outside world.

EDIT: I am familiar with HAProxy; the question is about Kafka, not OpenShift/ HAProxy. Is there anything special to be configured (in the Kafka broker image)

Are they all synchronized amongst each other?
Are there examples for that somewhere?

Googling for "OpenShift Apache Kafka" etc. brings up plenty of examples, but all that I found seem to have a different service for each Apache Kafka broker (i.e., explicitly running 3 separate Kafka deployments inside OpenShift, with separate OpenShift services, one each). This is what I wish to avoid. I want to horizontally scale the number of Kafka processes behind HAProxy, and have one single external IP.

Yes, you can. HAProxy is purpose built to balance any TCP or HTTP connection. My old company used to run every component of Kafka with HAproxy.

Here is a whole project dedicated to running auto-scaling Kafka in Docker using HAproxy: https://github.com/pozgo/docker-kafka

You can even see their HAproxy config here where they specify the broker check (port 9092): https://github.com/pozgo/docker-kafka/blob/master/haproxy.cfg


Can we consider usage of git lfs for artifacts equally mature strategy to an artifactory? Git lfs is just support for large files in Git -> good for example for a video file sample if you need it, right?
But, if you have large artifacts like a trained model or an uber-jar or some other artifact, what is the benefit to version this binary in git?

What is Git-LFS?

Git Large File Storage (LFS) prevents that large files need to be stored in git itself.

https://git-lfs.github.com/

  Git Large File Storage (LFS) replaces large files such as audio
  samples, videos, datasets, and graphics with text pointers inside Git,
  while storing the file contents on a remote server like GitHub.com or
  GitHub Enterprise.

What is artifactory?

Artifactory stores artifacts, e.g. docker images, jars, wars

Artifactory vs. Git-lfs

Artifactory is used to store artifacts while git-lfs is used to prevent that large files are stored in git. If one will store large files in git and one would like to clone this repository it will take a decade before it is cloned.


Docker Compose V3 app container can't access couchdb container I am trying to connect to couchdb through the container but my app is not seeing it.

However if I use the external address 123.456.789.123:12345 (server_ip:external_port)
it works but I need a connection through network with the internal port 5986.

Docker-Compose.yml

version: '3'
    services:
      couchdb:
        image: couchdb:latest
        restart: always
        volumes:
          - couchdb-data-volume:/usr/local/var/lib/couchdb
        env_file: .env.docker
        ports:
          - "12345:5986"
        networks:
          app-net:
            aliases:
              - couchdb
      app:
        build: .
        image: app
        restart: always
        depends_on:
          - couchdb
        env_file: .env.docker
    networks:
      app-net:
        driver: bridge
    volumes:
      couchdb-data-volume:

ENV FILE

NODE_ENV=production
COUCHDB_SERVER=http://user:pass@couchdb:5986
COUCHDB_USER=user
COUCHDB_PASSWORD=pass

I Also tried links instead of networks but the same issue.

 links:
 - couchdb

Any Ideas ?

Your mistake is that you are did not register the app service on the app-net network. To allow containers to connect with one another, they have to share a network and then use the image name as the domain name. Docker provides a network internal DNS service.

version: '3'
services:
  couchdb:
    image: couchdb:latest
    restart: always
    volumes:
      - couchdb-data-volume:/usr/local/var/lib/couchdb
    env_file: .env.docker
    ports:
      - "12345:5986"
    networks:
      app-net:

  app:
    build: .
    image: app
    container_name: app
    restart: always
    depends_on:
      - couchdb
    env_file: .env.docker
    networks:
      - app-net

volumes:
  couchdb-data-volume:

networks:
  app-net:

The URL from the app to the couchdb service would be http://couchdb:5986. To test this, open bash inside the app service with docker exec -it app. This depends on the container_name setting.


Executing a command in running docker swarm service I am trying to run a Django project in docker swarm mode. The problem is I want to index the Elastic search container which needs to be run only after postgres completes the SQL dumping process (only in the first run). How can I do this? Any solutions.

I suggest making a cronjob container that does the SQL dump and elastic index using docker exec commands toward the corresponding containers.


How can I add another module to my existing Terraform deployment plan? I have deployed a project within Terraform. I need to add a 4th application module to my existing plan. How do I update my plan to include this 4th module and deploy the missing module without starting over? I thought terraform import might be an option, but I'm not understanding how it would be done.

Terraform is idempotent so will only change what needs to be changed.
So after applying your existing plan, if you add more modules or resources and run another plan and apply, it will add the new resources not the whole infrastructure.
Terraform import is used when you want to start managing a resource created outside your Terraform code for example created in the AWS console, AWS CLI).
It basically associates and existing resource with your new Terraform code, so that Terraform doesn't try to recreate it when you run the plan/ apply.


What do I need to do as to prevent docker from downloading when I `run`? If I don’t want anything to download when I run
 docker run -ti --rm \
            -v /home/sable/heudiconvTest/BIDS:ro \
            -v /home/sable/heudiconvTest/qsipOutput:/out \
            pennbbl/qsiprep:latest \
            /data /out participant

What do I need to do? Do I just do pull pennbbl/qsiprep:latest and that’s it?

Provided that the commands run on the same machine, yes, that should work.
To be even safer and to make it clearer, I would use an explicit version tag, such as 0.9.0beta1, or 0.8.0, instead of latest.


Azure DevOps proxy for Git Does Azure DevOps 2019 Proxy server (formerly TFS proxy server) support Git repositories? The documentation only mentions TFVC repositories, and it works great, but we are not sure if Git repositories can be configured to use Azure DevOps (TFS) proxy (not to confuse with regular Web proxy). Appreciate any help!

Yes, you are right. Azure DevOps (or TFS) Proxy was designed to support Team Foundation Version Control while TFS did not support GIT in earlier versions. The documentation does not contain any information for GIT, it contains only for TFVC: Configure Team Foundation version control.
Consider using Git Virtual File System: https://github.com/microsoft/VFSForGit


How to configure bitbucket pipeline and deploy to alibaba clouds I have a repo on my bitbucket. I want to deploy it via bitbucket pipeline to my alibaba clouds ecs. I dont know what are steps required to manage it.

You can be done this task using below steps:

1: Creating the Bitbucket Git Repository And Adding our Application and Docker Configurations in it

2: Integrating Bitbucket with ACR

3: Deploying The Application

4: Securing our Application with Let’s Encrypt SSL/TLS

for full details check this:


How to implement the four-eyes principle for emergency fixes? Consider this scenario (any comparison with real world situations is purely by accident):

3:07 am: incoming support call "Something in production went down, I need your help!".
3:12 am: connected to the system (logon accepted) ... and no time for coffee.
3:15 am: lucky you, right away you could spot the issue via some error message somewhere.
3:17 am: use your SCM toolbox to grab the code, fix the issue, test it, great ... my fix works!
3:20 am: get in touch with the DevOps-team to ship the fix and to get production running again.
3:21 am: red flag ... "To respect four-eyes, we need 2 more eyes to get approval for this fix".
3:22 am: ggggrrrreat, now what, who else can we call (= wake up some manager)?

If you implemented some approval procedure similar to my answer to "What are possible implementations (or examples) of the four-eyes principle?", then you're out of luck ... here are your choices:

Your fix will be stuck (read: production will be down) until 2 more eyes got involved.
You figure out a way to get around the missing eyes.

So how to implement the four-eyes principle for emergency fixes? ... So that you get production up and running asap, i.e. around  3:25 am ... And so that you can also close the call (and go back to where you came from)?

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

Here is a blueprint of it:

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

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

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


How to setup Cloudfront for Load balancer for a private staging domain name? I've got a domain name foobar-staging.com, that I use for the staging environment to get feedback, testing or demo before releasing to production. Recently, decided to deploy the UI static files to s3 and everything else falling back to ALB.
The original setup is only accessible privately, so the user has to connect to a VPN to be able to access foobar-staging.com, and as far as I've tested so far Cloudfront content origins need to be public, so it seems that I won't be able to keep the staging server private, unless someone confirms me otherwise?

What I want to access privately is:

Domain name > Cloudfront > s3 (/routeX, /routeY) or ALB (other routes /*)

The EC2s only have private ips and the ELB security group do not allow public access. I've allowed 80/443 0.0.0.0/16 access to see the Cloudfront work for the setup... I don't necessarily need Cloudfront (other alternative would do, as I can't route to s3 in ALB), but without having Cloudfront in front of s3 and alb, I'd have to access the UI application through the s3 amazon domain, which I'd much prefer to use the foobar-staging.com.

Is it possible to do?

My solution is based on signed cookies (find how to implement it here, https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-cookies.html); I've created a lambda that handles this for me a bit differently, as I need users to access a location to get their cookie in the easiest way possible and have someone control to whom can be granted the auth cookie. An example of a basic implementation of this is here: https://aws.amazon.com/blogs/compute/simply-serverless-using-aws-lambda-to-expose-custom-cookies-with-api-gateway/

Finally, after you have provided your Content origin in Cloudfront, in the Behaviors tab where you setup the Content origin desired behaviour you need to set "Restrict Viewer Access (Use Signed URLs or Signed Cookies)".

Obs: make sure you also forward all cookies and query strings.


OpenVPN - routing public domain over tunnel? I have an OpenVPN server running in an AWS VPC and I can ping my servers over the tunnel via their private IP, so from that perspective it's working.

Some of our servers have public DNS names server.example.io and I'd like OpenVPN clients to be able to reach the servers using their DNS names over the tunnels. For example, one of our servers has a UI and rather than typing the private IP of the server in the browser, they should be able to reach the server over the tunnel using the public domain name.

Is this possible? We are using the OpenVPN Access Server AMI.

Yes, this is possible.

You can create a private DNS zone for example.io using AWS route53 in the AWS VPC where your openvpn server is running. Then you can point server.example.io to the private IP of the instance.
By default in AWS VPC, if a private DNS zone is present, it gets the preference. If the DNS record is not present, then it goes out of VPC for DNS resolution.

So, when your users are connected to the VPN, they all will be in the same network of AWS VPC. Hitting server.example.io will resolve to private IP and requests will be routed internally within VPN tunnel.

NOTE: If you are using multiple VPC or your server.example.io is in another VPC, you may need to add routes for that in your VPN configuration.


Jenkins - Mono repository build only changed the folder My Organization keeps a single git repository in bitbucket. It hosts multiple projects under the same branch.
I have to automate the build process using Jenkins; I configured a webhooks that invoke on any push to  development branch. Now, I have to generate a build based on which sub-directory the changes happened in, e.g. if code was committed  to /Microservice2, it will generate build for MS2, _etc.

How does one achieve this using Jenkins?

Am assuming you are familiar with Groovy at basic level. Well, you could do the following with Shell scripts too, but I have done something similar using native capabilities of Groovy.

Store changeset by running git log ..., those three dots mean you should go thru' git-log man page to check the options that will list the changed files with folder names.
Iterate thru' the changeset (from item 1) to identify the folder (microservice 2 or 3, 4, so on and so forth).
Once the service is identified, try and set few environment variables that can be reused in other scripts, if you want. Advantage with this approach is, you stand to have access to them until the completion of build.

Hope this helps.


How to restrict filesystem access in Atlassian Bamboo builds? We have Atlassian Bamboo running on Ubuntu. When a developer is setting up a build, then he or she has the possibility to run shell script tasks. This is useful to run (custom) commands on the codebase you are building.

However, the scripts that run can also access the filesystem outside their job directory in the Bamboo working directory (<Bamboo-home-dir>/xml-data/build-dir/JOB_KEY). So JOB_A can also access files of JOB_B: cd ../JOB_B.

Is there a possibility to restrict this access?

P.S. I am aware of the fact that builds are ran by (local or remote) agents in Bamboo and you can build different projects by different agents. However, if two projects are built by the same agent, the projects could access each other's files.

There is currently no ability to restrict jobs which are able to run on the same agent from potentially interacting with each other. There are a bunch of feature requests asking for this sort of granularity, but if I understand your question correctly the most fitting request would be this one BAM-2504 Jira Ticket

It's a huge gap in the product line, the only solution I've found is similar to what is proposed by the request linked above, essentially your bamboo process would need to run with sufficient privileges to impersonate a set of users who represent the projects which you would like to keep separate.

Once you have this sort of mechanism in place you just need to try to enforce that all plans run as one of the impersonatable accounts, depending for example on the project or the creator etc.

Problematically the way that access controls currently exist this would mean that few core admins would need to set up all the plans so that they can he sure of the required permissions split rather than letting non-administrative users edit and create their own plans.

If this sort of approach isnt feasible, which it isn't once you get into the "many hundreds of users" type of range, then the only thing you can really do to try and stop build jobs from interacting with each other is implement the very weak controls that bamboo gives you.

I've tried two approaches to doing this:

Delete or cripple (remove all capabilities from) your local agents and for every different project/team/whatever that on boards to your bamboo instance you need to force them to BYO build server. In most instances I've been involved in the cost of an agent is utterly trivial compared to the cost of potential data leakage or malicious plan interactions.
Make sure that projects that do have, or that think they do have, sensitive data involved in their plans always sanitise their environments after they build. This shifts the burden off the team administering the tools and onto the projects writing their plans and forces them to defensively clean up any information that they don't want potentially available to others.

Neither solution is even close to perfect but to the best of my knowledge that's about as much separation as you can enforce if you have a shared bamboo instance.


How to Block Traffic From a Single IP in AWS Our server being hammered by traffic from some particular IP. It was causing a 20x increase in traffic to some URLs. So I wanted to block all traffic from that single IP.

Yes, we can block traffic from single IP or IP range. Please follow below steps to do this

Open VPC dashboard

Open the Network ACLs view

Open the ACL editor

Select the subnet to which your EC2 instances or load balancers are connected.

Click Inbound Rules

Click Edit

Add a rule to block the traffic/IP

You will now see the ACL editor. On the last row, you can add a new rule.

Here is how you should fill out the fields:
Rule
Use any number less than 100, which is the number of the default accept-all rule. This is important because rules are evaluated in order, and your rule needs to come before the default.
Type
Select “All traffic” or Particular Protocol which you want to Block
Source
The CIDR you want to block. To match a single IP address, enter it here and append /32. For example, I blocked 22.87.45.187/32
Allow/Deny
Select “DENY”
Now click Save and you should see the updated rules table.
Fore more details visit https://www.serverkaka.com/2018/05/block-traffic-from-single-ip-in-aws.html

UPDATE: How to do it in CLI

NOTE: This example command includes --dry-run option, so it is safe to run. It will not create NACL rule. Run it without this option, if you want to apply it.

aws ec2 create-network-acl-entry --dry-run --network-acl-id acl-146adb6f --ingress --rule-number 20 --protocol tcp --port-range From=80,To=80 --cidr-block 22.87.45.187/32 --rule-action deny

More examples:
https://docs.aws.amazon.com/cli/latest/reference/ec2/create-network-acl-entry.html#examples


Docker: PHP deployment in apache, couldn't acces container URL in local browser; shows blank page I'm trying to deploy PHP files in Apache container using Dockerfile, Dockerfile on console shows successfully built and tagged but after running the container, i couldn't access the container IP or Container URL in local browser

Dockerfile

FROM ubuntu:bionic
RUN apt-get update
RUN apt-get install -y software-properties-common && \add-apt-repository ppa:ondrej/php && apt-get update
RUN apt-get -y upgrade && DEBIAN_FRONTEND=noninteractive apt-get -y install \
apache2 php7.0 php7.0-mysql libapache2-mod-php7.0
RUN sed -i "s/short_open_tag = Off/short_open_tag = On/" /etc/php/7.0/apache2/php.ini
RUN sed -i "s/error_reporting = .*$/error_reporting = E_ERROR | E_WARNING | E_PARSE/" /etc/php/7.0/apache2/php.ini

ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2
ENV APACHE_LOCK_DIR /var/lock/apache2
ENV APACHE_PID_FILE /var/run/apache2.pid

EXPOSE 80
ADD www /var/www/site
ADD apache-config.conf /etc/apache2/sites-enabled/000-default.conf
ADD hosts /etc/hosts
CMD /usr/sbin/apache2ctl -D FOREGROUND ```

You need to expose the container ports locally using either:

docker run --rm -it -p 8080:80 myapp
or a docker-compose.yml file:

services:
  myapp:
    image: myapp:tag
    ports:
    - 8080:80

Then, you'll be able to curl localhost:8080.


Pre-install Jenkins plugins using Docker image If I have a jenkins docker image:

FROM jenkins/jenkins:lts

is there a way to pre-install certain plugins using the Docker image, for example all the bitbucket plugins:

I assume we'd probably have to unpack some tars to the filesystem somewhere like so:

 FROM jenkins/jenkins:lts

 USER root

 WORKDIR /jenkins/main/dir

 RUN tar -xvf some-jenkins-plugins.tar

This seems to be the right idea: https://stackoverflow.com/questions/29328278/installing-jenkins-plugins-to-docker-jenkins/29328489#29328489

so in the Dockerfile you'd just use:

COPY plugins.txt /usr/share/jenkins/plugins.txt
RUN /usr/local/bin/install-plugins.sh < /usr/share/jenkins/plugins.txt

I tried it and it worked for me.


Default StorageClass set up for Docker EE Kubernetes We're using Docker EE Kubernetes on-prem set up and noticed that cluster(s) don't have default StorageClass set up. To the best of my knowledge this is supposed to be set up during install/set up, but not done here.

I am aware of steps and have YAML in place to create a PV and StoageClass but trying to understand if there are any best practices and 'right' approach to set that up?

I came across nfs-volume but still not clear if we need a separate NFS drive/server, or can we use one of the nodes for creating the StorageClass(SC)?

Also we don't want the SC to be available for other namespaces or pods as I need to set up SC as a pre-requisite for installing an Ingress Controller.

Found out that there is no specific 'default' storageclass(SC) type for Docker EE or others, it depends on the requirement and specific to Kubernetes provider(s). I went ahead and created a sc with 'local' provisioner type.


What is warm(ing) up? There are a few questions that mention something about warm up, such as:

How to filter out system-generated calls in monitoring of Azure Webapps?

  ... to keep the container instance/VM warmed up.

What is the ec2 cli command to modify the minimum number of nodes in a scaling group?

  ... to warm up the autoscaling group to run jobs.

What is this warm up thing? Is it something similar to "being ready when some request comes in (e.g.  to preload things in memory, to prevent some sort of I/O operations)"? If not what could be a good comparison to explain it to a novice?

All container services and Function-As-a-Service services of the big cloud providers, such as Amazon ECS, Lambda and Azure cloud functions run on actual virtual machines of these providers. Normally they only take a small number of milliseconds to start up, but when your container or function has not run for a certain amount of time, they will take a couple of seconds to actually start up the virtualization environment for your container or function. These startup times improve all the time, but you still get better startup time results by calling your functions or a request in your container in regular intervals.

A typical interval could be every minute, so that you can be sure that the virtual environment the container or function runs on has likely not been shut down, as it just was in use in the past 60 seconds.

In relation to an auto scaling group, I would say that "warm up" is a bit of a mis-nomer. Either there are enough instances provisioned to handle the traffic you expect, or you may need to make a 'scheduled change' to the number of instances, but there is actually nothing to warm the instances up.

One edge-case would be if instances have disk contents restored from backup. On AWS, there is some delay in getting the contents on these disk from snapshot and the disk can be warmed up by reading all blocks on it


Provisioning meaning Provisioning is the process of setting up IT infrastructure. It can
also refer to the steps required to manage access to data and
resources, and make them available to users and systems.
Provisioning is not the same thing as configuration, but they are both
steps in the deployment process. Once something has been provisioned,
the next step is configuration.

I find the following lines confusing
"It can also refer to the steps required to manage access to data and resources, and make them available to users and systems."
"Provisioning is not the same thing as configuration, but they are both steps in the deployment process"
How can you make your resources available to the user without setting them up and configuring them. So why isn't configuration a part of provisioning?
Also what exactly do you mean by setting up the resources?

As per my understanding on cloud native infra.
Provisioning involves creating resources like VMs/instances, setting up IAM roles and policies, Firewalls, DBs, Load balancers, any clusters like EKS, GKE, etc.
And, configuration part involves, preparing your instances to run actually your apps by installing necessary softwares and packages, setting up tables in DBs and populating data, RBAC controls on resources, etc.


ansible question to execute and display multiple commands I have the simple ansible script below:

- hosts: myhost
  tasks:
    - name: few commands
      command: "{{ item }}"
      with_items:
        - ls -l
        - df -h
        - cat /tmp/1

there will be more commands and files, how I can display the execution of each command ?

One could use -vvv to get the output of the commands while running the playbook:

changed: [localhost] => (item=echo helloworld) => {
    "ansible_loop_var": "item",
    "changed": true,
    "cmd": [
        "echo",
        "helloworld"
    ],
    "delta": "0:00:00.002517",
    "end": "2019-12-20 15:20:09.042020",
    "invocation": {
        "module_args": {
            "_raw_params": "echo helloworld",
            "_uses_shell": false,
            "argv": null,
            "chdir": null,
            "creates": null,
            "executable": null,
            "removes": null,
            "stdin": null,
            "stdin_add_newline": true,
            "strip_empty_ends": true,
            "warn": true
        }
    },
    "item": "echo helloworld",
    "rc": 0,
    "start": "2019-12-20 15:20:09.039503",
    "stderr": "",
    "stderr_lines": [],
    "stdout": "helloworld",
    "stdout_lines": [
        "helloworld"
    ]
}


Kubernetes - unable to login to Dashboard I have installed Kubernetes using AWS Minikube scripts - https://github.com/scholzj/aws-minikube

After installation I am trying to run

kubectl proxy

But I am getting this

  https:kubernetes-dashboard:\" is forbidden: User \"system:anonymous\"
  cannot get services/proxy in the namespace \"kube-system\"

I am not even able to list pods because I do not have valid tokens with system.master role. I have no idea how I can create a user or token and authenticate when there is no admin user present on the system yet.

Can you please explain to me?

how we can extract the certificates from the kubeconfig file:

Locate your kubeconfig or config file which you use to run kubectl commands. If you have used my Vagrant file above, you can find it on /etc/kubernetes/admin.conf
You need to export a single file (.p12) with the following two certificates: the client-certificate-data, and the client-key-data. My example runs the command on /home/vagrant. If you run this command on macOS, be sure to change the base64 -d to base64 -D

$ grep 'client-certificate-data' ~/.kube/config | head -n 1 | awk '{print $2}' | base64 -d >> kubecfg.crt

$ grep 'client-key-data' ~/.kube/config | head -n 1 | awk '{print $2}' | base64 -d >> kubecfg.key

$ openssl pkcs12 -export -clcerts -inkey kubecfg.key -in kubecfg.crt -out kubecfg.p12

Import the kubecfg.p12 certificate, reopen your browser, and visit the Kubernetes Dashboard URL. Accept any warning and you should see the authentication page. You can skip the login and check you are not able to perform any task.
The following steps have been copied from the Kubernetes Dashboard wiki page (Creating-sample-user)

    1- Create service account

        cat <<EOF | kubectl create -f -
        apiVersion: v1
        kind: ServiceAccount
        metadata:
          name: admin-user
          namespace: kube-system
        EOF
        >>

    2- Create ClusterRoleBinding

        cat <<EOF | kubectl create -f -
        apiVersion: rbac.authorization.k8s.io/v1
        kind: ClusterRoleBinding
        metadata:
          name: admin-user
        roleRef:
          apiGroup: rbac.authorization.k8s.io
          kind: ClusterRole
          name: cluster-admin
        subjects:
        - kind: ServiceAccount
          name: admin-user
          namespace: kube-system
        EOF
        >>

    3- Get the Bearer Token. Once you run the following command, copy the token value which you will use on the following step.

        $ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')

    4- Come back to your browser and choose token on the login page. You will need to paste the token value you have copied on the previous step.
5- Click “SIGN IN” and you should be able to see your Kubernetes Dashboard fully operational.


Assign Directory Read/Write Privileges to Azure Service Principal from the command line? I am trying to provision a user in Azure Active Directory using Terraform's AzureAD provider.  At the top of the azuread_user documentation, it states:

  NOTE: If you're authenticating using a Service Principal then it must have permissions to Directory.ReadWrite.All within the Windows Azure Active Directory API.

I have created the Azure Active Directory User using the az command line:

az ad sp create-for-rbac --role="Owner" --scopes=$SubscriptionUrl --name $PrincipalName

However, this doesn't have Directory.ReadWrite.All permissions, as that would be a fairly insane security risk.

How can I add the Directory.* permissions to the Service Principal using the az command line (by preference) or even the Azure Powershell Cmdlets, I would even be willing to craft a WebRequest if that would help me solve the problem!

What you need here are the az ad app permission commands.

Here is a complete example (assuming powershell):

$apiId = "00000002-0000-0000-c000-000000000000" # Windows Azure Active Directory
$apiPermissionsId = "78c8a3c8-a07e-4b9e-af1b-b5ccab50a175" # Directory.ReadWrite.All
$spn = az ad sp create-for-rbac --role="Owner" --name blah | ConvertFrom-Json
az ad app permission add --id $spn.appId --api $apiId --api-permissions ("{0}=Scope" -f $apiPermissionsId)
az ad app permission grant --id $spn.appId --api $apiId
az ad app permission admin-consent --id $spn.appId

For reference, Microsoft has a list of the GUIDs used for various applications.

On some occasions I have been unable to find documentation for the magic GUIDs required for a particular app/permission, in which case I would resort to adding them through the portal manually (Azure Active Directory ➔ App Registrations ➔ Required Permissions) and then reading the JSON manifest back to reveal the required GUIDs which can then be plugged into automation.


How to automate submission to Amazon Marketplace? Is anyone aware of a way to automate the submission of an AMI to Amazon's Marketplace? I want to take a public AMI and share it to the AWS Marketplace so it can be scanned for listing and then submit the product metadata sheet.

Our preferred environment is Python, but I didn't see any relevant hooks in the boto3 library so I'm open to alternatives.

Snapshot Permissions

Boto3 has a function that allows you to create volume permissions, which is what AMI Sharing with AWS Marketplace requires you to do. snapshot.modify_attribute will allow you to share your AMI with the marketplace account like so (you can also use a JSON representation if you prefer, it's in the docs):

response = snapshot.modify_attribute(
    Attribute = 'createVolumePermission',
    OperationType = 'add',
    UserIds = [
        '679593333241', # Marketplace user ID
    ]
)

There is also an official API function that will help you achieve the permissions requirement listed in AMI Sharing with AWS Marketplace if you decide to migrate from boto3 (or if a reader isn't using boto3). If your AMI is private, you need only make this API call:

https://ec2.amazonaws.com/?Action=ModifySnapshotAttribute
&SnapshotId=ID_HERE
&CreateVolumePermission.Add.1.UserId=679593333241
&AUTHPARAMS

This should add the permission that the marketplace needs to access your AMI. As for replacing ID_HERE with the snapshot's ID, you can do that with boto3 by using your snapshot object's snapshot_id property snapshot.snapshot_id before making the API call (that being said, there's little reason for you to use this API since you have to use boto3 anyways).

Product Metadata

You should be able to use the relevant ServiceCatalog functions in boto3 such as create_product to upload product metadata. There are also equivalent official API functions (this one is just CreateProduct, they're not listed in a way that allows me to link to them nicely). It's worth noting that the official API only accepts JSON whereas boto3 will generate the JSON itself. Which one is more useful to you depends on how your data is structured in your product metadata file(s). Since I don't know that I can't directly write the code to do it.


certbot renewal fails over ipv6 I'm using LetsEncrypt CA for SSL certificates with a cron job that renews them. Recently moved one of our domains to dual ipv4/ipv6 stack and now the certificate renewal fails for that domain:

Attempting to renew cert (nodrama.io) from /etc/letsencrypt/renewal/nodrama.io.conf produced an unexpected error: Failed authorization procedure.

www.nodrama.io (tls-sni-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization ::

Incorrect validation certificate for tls-sni-01 challenge.

Requested 1d2e60bbb911a0fa373af1c71068a98f.df68ccc953b03b03cbca639fa7b20469.acme.invalid from [2600:1f16:14a:7b00:e9ba:752c:feb8:49d5]:443.

Received 1 certificate(s), first certificate had names "5de1f81c71783962782726ac76156d00.51706d503a8be636f033680ff5a1664e.acme.invalid, dummy". Skipping.

If I remove the 443 over ipv6 from the nginx server configuration then the challenge goes through, cert is renewed.
Bring it back and after that the content is availiable on ipv6 over https:

Connected to nodrama.io (2600:1f16:14a:7b00:e9ba:752c:feb8:49d5) port 443 (#0)
* found 592 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
* server certificate verification OK

Changed the challenge from tls-sni to:

  --preferred-challenges http

and the certificates are renewed.


Ansible - Copy multiple files I am trying to copy multiple files to the target like so:

  tasks:
  - name: "Copying files"
    copy:
      src: files/{{ item }}
      dest: /my/folder/
    with_items:
      - file.txt

The files directory is in the same directory as the Ansible playbook. However when running the script, I get this error:

docker: TASK [Gathering Facts] *********************************************************
    docker: fatal: [test]: FAILED! => {"msg": "failed to transfer file to /home/user/.ansible/tmp/ansible-local-123331or28t2a/tmp6st_fxv1 ~user/.ansible/tmp/ansible-tmp-1579990845.0734024-189911264147319/AnsiballZ_setup.py:\n\n\n"}
    docker:

Why is that? Why can Ansible not copy the files to the target machine?

Following you comment: no I cannot reproduce your problem. Since you did not provide the rest of your files (inventory, etc...) and I cannot guess where is your problem, here is a quick proof by example using the php:7.0-apache image.

The inventory (inventories/docker_test/hosts.yml)

---
all:
  hosts:
    docker_test:
      ansible_connection: docker

Launching the test container

docker run -d --rm --name docker_test php:7.0-apache

The test playbook.yml

---
- hosts: docker_test
  gather_facts: false

  tasks:
    # Your image does not have python which is mandatory for ansible
    # Please note this is for demo only. You should get python installed
    # by extending the image through a Dockerfile and build it.
    - name: Dirty low-level command to get python installed
      raw: apt-get update && apt-get install -y python3

    - name: Gather facts now we can
      setup:

    - name: Copy a dummy file
      copy:
        dest: /etc/apache2/sites-available/dummy.conf
        content: "# I'm a dummy file"

Playbook run and output

$ ansible-playbook -i inventories/docker_test/ playbook.yml

PLAY [docker_test] ********************************************************************************************************************************************************************************************************

TASK [Dirty low-level command to get python installed] ********************************************************************************************************************************************************************
changed: [docker_test]

TASK [Gather facts now we can] ********************************************************************************************************************************************************************************************
[WARNING]: Platform linux on host docker_test is using the discovered Python interpreter at /usr/bin/python3.5, but future installation of another Python interpreter could change this. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.

ok: [docker_test]

TASK [Copy a dummy file] **************************************************************************************************************************************************************************************************
changed: [docker_test]

PLAY RECAP ****************************************************************************************************************************************************************************************************************
docker_test                : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0


Why would graphite-webapp browser not display any body content? I have used 0.9.x Graphite in the past as the basis of my monitoring system, and am trying a fresh install of 1.0.1 prior to upgrading across my systems (Ubuntu, 14.04, though I doubt that matters).

I appear to have graphite-webapp and carbon-cache running (supervisorctl reports both as RUNNING, and there are not errors in any logs I can find). I have confirmed by navigating in the server /opt/graphite/webapp/storage/whisper/ that there is in fact data to display in the first place.

I am able to access http://localhost:8080 and see the usual graphite webapp header, but the body of the page is blank (where normally I would expect to see the file-browser that lets me choose data on the left, and it graphs the selected data on the right).

To the best of my knowledge, I have configured graphite as per the installation instructions, but obviously I have done something wrong.

If there are particular configuration files that would be useful for me to include (which can also server as a debugging path for future people who may have this issue), please comment the files that may help.

Note to editor: The tag should be "graphite", probably, but I don't have the rep to tag it correctly.

You need to collect static assets in your Django

cd /opt/graphite/webapp && PYTHONPATH=/opt/graphite/webapp django-admin.py collectstatic --noinput --settings=graphite.settings

Static files will be installed in /opt/graphite/static.
Then you need to configure your webserver to serve them directly.
For Nginx something like:

location /static {
   root /opt/graphite
}


Docker desktop Ports binding not available Why are the port options not available in docker desktop (windows 10)?

current settings (I have tried both engine options):

The Docker Desktop is giving the option to publish ports to the container ports that have been "exposed" in the image. Exposing a port in an image is documentation from the image creator to those running the image, to know what port the application inside the container should be listening. And in this case, it's Docker Desktop that's running the image and looking at that documentation.
More details on "expose" can be found in Docker's documentation: https://docs.docker.com/engine/reference/builder/#expose


Deploy two independently hosted services in production at once without any downtime I have two different services. Let's say Service A and Service B. Service B is dependent on Service A. Both code bases are hosted in separate repo in Bitbucket and code bases are maintained by different teams. Service A has three backend servers and Service B has seven backend servers. I use Jenkins as a CI for code deployment. So, whenever we merge the code in master branch, Jenkins start the deployment. The process is same for Service A and Service B but they have two different Jenkins server.

Now, problem is that if Service A team deploy something in production independently with major changes in code base. Then whole application will break. Because Service B is not ready yet to compatible with the code changes of Service A. Let's say, parameters of a function has been changed where Service B is expecting a different parameter.

I am looking for a solution, where Service A code merge in master gonna happen only it is time for deployment of Service B. So, every deployment of Service B, it first deploys the code of Service A and then follows with Service B. This whole deployment will take a lot of time. Main application should not be down by this time (because once Service A is deployed then user has to wait for Service B deployment, otherwise they will face errors).

So, I am thinking if it's possible where new deployment will happen in a separate instance When deployment is completed in that instance then it will replace the previous instance. So, code will be updated in main production without any down time or error.

What is the recommended way to achieve this ? Can I do something with Ansible in this case ?

I think you're taking the problem on the wrong side, you may start a whole new infrastructure aside and then switch loadbalancers from blue to green, loosing sessions, breaking ongoing transactions etc.

The proper way to achieve what you're doing is coding differently, when A relasease a breaking API ni version n, a should be able to continue to answer call to api in version n-1. the usual method is to have the version in the uri or an header, for exemple:

<a-host>/api/1/getCustomers and <a-host>/api/2/getCustomerList (for exemple if n is 2). With that, you can do a rolling update of B, with backends still using api v1 and new ones using api v2.


Kubernetes used to orchestrate Containerized Machines 0
I am using k8s to orchestrate an environment on a local network. My idea is to deploy a number of linux machines each of which should have its own "External" IP.
Right now I found guides to expose services on External IP (e.g. https://kubernetes.io/docs/tutorials/stateless-application/expose-external-ip-address/), but this is tailored to expose services on a precise port.
My need is more targeted to expose an entire machine on a precise static IP and not just a port. This would allow me to easily deploy and reshape any network topology I need. Notice that doing it without exposing the IPs (hence using internal k8s routing/dns) is not an option because this environment should be interfaced with real/bare metal hardware already present in the network.
Here follows a little example of the desired result:

Can anyone relate to this and let me know if this is even possible?

You should look at DaemonSets. You can configure it so that the Pods runs on each node of your Kubernetes cluster. Each individual Pod (running your Linux machine) can be exposed to outside network using the IP address of the node on which it is running.

My need is more targeted to expose an entire machine on a precise static IP and not just a port.

Before getting into further explanation, I should point out that there is nothing like exposing entire machines.
Access to any machine is always through a combination of IP address and Port. So you should decide based on which port you would like to access on the container.
Example:
Let's say I have a 3 node Kubernetes cluster, I can create a DaemonSet with the application/image of my choice. Below names/details are imaginary, but should give an idea on the mapping.
ubuntu-daemonset-pod-xyz    k8s-node-1    192.168.2.1
ubuntu-daemonset-pod-abc    k8s-node-2    192.168.2.2
ubuntu-daemonset-pod-hij    k8s-node-3    192.168.2.3

The Pods above can be "exposed" on the IP address of the node on which it is running. That is: ubuntu-daemonset-pod-xyz on 192.168.2.1.


How to approach dynamic environments per Git feature branch workflow? Our system consists of

2 frontend applications A and B (both in JavaScript/Angular),
3 backend applications C, D and E (main API and two microservices all in Go)
MongoDB as F

Our team grows bigger, it's 10 developers at the moment.

We are working on 2, 3 new major features at the same time.

We only have two pre-production environments which makes it hard to test/present different features that are being built at the moment (and on top of that, to test fixed bugs and hot fixes etc.).

We use Git and try to follow git branching model (which might not be relevant here).

To make it easier, we can assume, that each repository has its own Dockerfile to create a fully working container with that application.

What are the options to make it super easy (one command) to publish/switch to a feature that a developer is working on so it's available on one of the environments (that could maybe be created dynamically?)

Should we create 6 new servers/containers if we only make changes in application A?

I would like to have easily accessible versions via a URL like https://a166.preview.example.com where a is the application name and 166 is the application version (or branch name).

What you're after is referred to as "Review Apps" by Gitlab and Heroku. It relies on a CI/CD system that runs pipelines on every branch, and exposes the branch name to the build (usually as an environment variable). You can then use the branch name to namespace the resources created by your Infrastructure as Code.

You have mentioned Docker so I will use Kubernetes as an example, but this approach can be applied to just about any deployment method.

Normally when deploying a Docker image, you would name your deployment after the app, e.g.:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
# ...

Using either some kind of preprocessor (Jinja, envsubst, etc.) or a tool like Helm we can pass in some parameters to make the resource include the branch name during the pipeline:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-${BRANCH_NAME}
# ...

This way, branches do not deploy on top of each other. The resources they deploy are isolated to the branch.

For an API or web app, you'll want some kind of DNS name and load balancer. Kubernetes handles this quite easily with Ingress and DNS controllers, so I'll use CloudFormation as an example this time.

AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  Branch:
    Type: String
  Environment:
    Type: String
  Zone:
    Type: String

Resources:
# ALB resources omitted for brevity...

  Route53:
    Type: AWS::Route53::RecordSet
    Properties:
      Name: !Sub
        - "my-app-${Branch}.${Environment}.${Zone}"
      HostedZoneName: !Ref Zone
      Type: A
      AliasTarget:
        HostedZoneId: !GetAtt ALB.CanonicalHostedZoneID
        DNSName: !GetAtt ALB.DNSName

Here we create a DNS record that is very specific to the branch. The DNS record resolves to a load balancer which should point to the containers deployed by the pipeline for this branch. The stack name is also specific to the branch, so pipelines on other branches will not affect it. The end result is that each feature branch will have a dedicated URL (https://my-app-my-feature.dev.example.com) that your developers can use to test and showcase to stakeholders.

  Should we create 6 new servers/containers if we only make changes in application A?

No. This isn't specifically related to Review Apps, but microservices in general should be self-contained: decoupled from each other so that they can be deployed in isolation. Removing dependencies and making small changes will increase your development/deployment velocity.

Considerations

Cleanup

What happens when you merge or delete your branch? Without setting up some kind of cleanup, those containers and DNS records will sit around forever. You need some kind of cleanup. Something that just runs periodically and deletes resources associated to old branches is pretty simple to write, or you could take webhooks from your git server and delete those resources on an event.

Databases

Some resources may not warrant getting deployed per-branch, although this should be the exception rather than the norm. You probably don't want to deploy a new database every time someone makes a branch (perhaps unless you have a good schema management tool and DB population scripts). You can have all deployments connect back to the same DB. Ensure that any changes you make to the schema are backwards compatible at least one version behind.


Why can this ENV not be found when it is defined in one layer using a Dockerfile? When the following Dockerfile:

ENV A=123 \
    B=$A
RUN echo $B

is run, it results in:

Step 2/2 : RUN echo $B
 ---> Running in x

 ---> y
Removing intermediate container z

When two ENV layers are defined:

ENV A=123
ENV B=$A

it works:

Step 2/2 : RUN echo $B
 ---> Running in x
123
 ---> y
Removing intermediate container z

The ENV keyword will be translated to export command (builin of the shell usually), if you remove the multi-line declaration you end up with this equivalent:

export A=123 B=$A

What happens here is that when the shell parse the line to give it to export input, A is not yet exported and available as an environment variable.

Step by step this will give:

You type export A=123 B=$A
The shell parse the line and pass A=123 B= to export's stdin
export parse each argument in the form key=value and as such export A to be 123 and B to be empty

On the second form, A is available to the shell when the line is parsed, and as such the resulting export's stdin is B=123


Why am I unable to push docker image in gce (gcr.io)? I created a new VM instance on my GCE compute engine (I have Owner permissions). On that instance, I installed git, docker, and gcloud - everything is done under sudo su.

I was hoping I can use that VM instance to deploy images to GCR, but whatever I do - I cannot seem to have sufficient permissions to push the images from that instance.

I granted "Storage Admin" along with the "Editor" permissions to the VM Instance (autogenerated) IAM service-account.
When I run docker login eu.gcr.io I receive Login Succeeded with no problems.
I copied both a p12 key and a .json key to the .ssh folder (I generated them on the IAM console) - but that had no use too.
To tag and push the docker image, I use this::

docker tag [SOURCE_IMAGE] [HOSTNAME]/[PROJECT-ID]/[IMAGE]

and

docker push [HOSTNAME]/[PROJECT-ID]/[IMAGE]

Notice: It seems that at this stage (2018) gcloud docker -- push is obsolete (and it didn't work for me as well...)

Notice: The bucket is NOT created yet, so setting permissions on the Storage console is out of the question at this point.

What could be the reason for the Permission Denied problem ?

From the Before you begin section of the instructions you referenced:

  Make sure that you:

  Have access to the registries which you will be pushing to and pulling from

This is specified in more details in Using Container Registry with Google Cloud Platform:

  To push private Docker images from a Compute Engine instance, your
  instance must have read-write or full-control permission to
  the image's bucket.

So the GCS bucket corresponding to gcr.io (or whichever GCR domain you want to use) and the desired cloud project must already be created and your GCE instance's service account must have the necessary role/permissions for push operations.

It's true, the instructions you referenced mention in Push the tagged image to Container Registry:

  When you push an image to a registry with a new hostname, Container
  Registry creates a storage bucket in the specified multi-regional
  location.

So I believe you'd have to:

first create create the bucket by executing a push to the desired GCR domain and project, but:

from your own computer (or some machine which is not a GCE instance, but YMMV)
using the credentials of an acceptable identity, not the GCE instance service account's ones. I'd try with a real user credentials, I'm not sure if a service account's ones would cut it.

after the bucket is created add to its access control the GCE instance service account's role/permissions for push operations
then perform pushes from the GCE instance


What are trusted providers that offer wildcard certificates and associated costs to be used in an Orchestration Platform like Kubernetes? Currently, certbot and nginx are used to create a trusted webpage. Recently, an attempt was made to move the images to a kubernetes cluster on google cloud platform. A guide was found to configure an SSL loadbalancer. It was tried and it shows multiple textboxes to insert a key, cert and chain.

An attempt was made to see whether Google offers wildcard certs as well, but no information was found. Certbot itself announced last year that they will support wildcard certs, but that does not seem to be the case as well. First impression is that using certbot in the google loadbalancer will not be possible or will be cumbersome as the certs have to be renewed every three months.

When one Googles: cheap wildcard ssl then a lot of results are shown. The questions are which of these providers can be considered as safe, what are the costs and what providers do you use and why?

Have a look at "Ingress" and "Cert-Manager":

With a Kubernetes Ingress you can configure the load balancer, see e.g. https://cloud.google.com/kubernetes-engine/docs/tutorials/http-balancer
With "Cert-Manager" you can get certificates from Let's Encrypt (like certbot does), and it handles renewing automatically. See https://github.com/jetstack/cert-manager


when does currentBuild.changeSets in Jenkins gets filled? Some background: The project I'm working on is in SVN. Very very large. A lot of tests are running on Jenkins. I want to implement a new tests which should be executed only if files in certain directory have been changed.

The idea that I had was:

to trigger the job using a pollSCM every ten minutes
check the files in currentBuild.changeSets. If a file contains the directory, continue.
Only then I do a full checkout of the repository, compile, and run the tests.

But before I write the code, I was wondering when does  currentBuild.changeSets? Will it have the required information when triggered by a pollSCM? I could not find this in the documentation

Yes, this could be done in a better way using git and hooks and other tools but that's what I have right now.

It will be set after any checkout steps (or derivatives of checkout such as git or svn).

So for instance:

println(currentBuild.changeSets) // should print an empty set

checkout(scm)

println(currentBuild.changeSets) // should print out any changes in the current build


What is a secure way for storing AWS IAM credentials? When creating a new user in AWS IAM, it generates access keys for that user. Where is a secure and readily accessible location to store these credentials?

Well there are a lot of places to keep them secure

you can use something like hashicorp vault to keep those kind of secrets
you can use something like lastpass and my personal favorite is enpass

But first you need to define your needs so you can choose the right tool to use and integrate with your daily use


Jenkins Shared lib not working properly Recently I tried to add Shared Libraries to my Jenkins instance to make it easier to maintain all code that runs in each project.

I have a repo myorg/jenkins

Inside of it I have Jenkinsfile and groovy file meant to contain libraries, Jenkinsfile looks like this:

@Library('utils@develop')_
import com.*

jenkinsSlave = "slave.myorg.com"

node(jenkinsSlave) {
    stage('Test') {
        def var = "kek"
        myorg.echoTest(var)
    }
}

I try to execute echoTest method there and I'm passing one argument.

Shared libs look like this (Jenkinsfile is in root directory of this repo):

src
└── com
    └── myorg
        └── Utils.groovy

Utils.groovy:

#!/usr/bin/groovy
package com.myorg

def echoTest(test) {
  println("Test + ${test}")
}

return this

In Jenkins I've added this repo to global libraries section and I pointed to main branch, which is develop in this case.

Unfortuantely, when I run build jenkins throws this:

groovy.lang.MissingPropertyException: No such property: myorg for class: groovy.lang.Binding
    at groovy.lang.Binding.getVariable(Binding.java:63)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:264)
    at org.kohsuke.groovy.sandbox.impl.Checker$6.call(Checker.java:288)
    at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:292)
    at org.kohsuke.groovy.sandbox.impl.Checker.checke

[...]

I tried various configuration but so far I cannot make this work. I've tried to follow few tutorials about implementing this and I cannot pass through here.

Does someone notice any misconfiguration in this setup?

You have not instantiated the Utils class in the myorg classpath so you cannot reference the method echoTest(). Try Utils.echoTest or just echoTest()


How to increase jenkins logger size? I use Jenkins log recorders as described in docs:
https://www.jenkins.io/doc/book/system-administration/viewing-logs/
It works, but log is only about 255 lines long, which is too short for my processing.
Newest lines are shown, I cant reach older logs, so I dont know what happened in the beginning.
How do I increase this size? I would like to keep at least 1MB of data.

I'm pretty sure this Jenkins system property will do the trick:

hudson.util.RingBufferLogHandler.defaultSize

tuning
Since: 1.563
Default:  256
Description: Number of log entries in loggers available on the UI at /log/

You can also custom Configure Loggers for Jenkins or create a logger in Jenkins for troubleshooting and diagnostic information that capture specifics you are looking for.
Additional references:
JENKINS - Logging
JENKINS - Logger Configuration
Or, if you are the admin, you should be able simply to scan the logs on the filesystem. Review what log rotation options and retention you may have.


How to find out the used Key pair name via AWS CLI? I'm aware of get-password-data command which can display PasswordData data like:

$ aws ec2 get-password-data --instance-id i-0123456789
{
    "InstanceId": "i-0123456789",
    "PasswordData": "\r\nAOh...xg==\r\n",
    "Timestamp": "2018-03-27T16:52:04.000Z"
}

however I'd like to know which Key pair name was used to launch the instance, so I can pass it using --priv-launch-key in order to decrypt the password.

For a given instance, you would first use aws ec2 describe-instances to get the information JSON for your instance.

The information also contains the keypair name used to create that instance.

E.g. for an instance i-0e2x8xd7xxx  (Note: I use the awesome tool jq to do JSON parsing but you can use any other solution)

aws ec2 describe-instances --instance-ids i-0e2x8xd7xxx | jq '.Reservations[].Instances[].KeyName'

Output:

"my_key_name"

You can store that in a variable, say $keypair_name and then pass it into your aws ec2 get-password-data command.

You would also need to pass in the path on your machine where your keypairs are located e.g. $keypair_path.

For example:

aws ec2 get-password-data --priv-launch-key $keypair_path/$keypair_name .....


How do I configure Travis CI build testing for a Java Eclipse project? I have an Eclipse Java project on GitHub. I would like to set up auto-build testing with Travis CI. However, when I enable build testing for my project, compilation always fails with the following error.

Buildfile: build.xml does not exist!
Build failed

The command "ant test" exited with 1.

How do I configure Travis CI to run build tests for my Java Eclipse project?

The easiest method is to have Eclipse generate an Ant build script for you.

Right click on your project in the Package Explorer and select Export in the context menu. Choose the export type General -> Ant Buildfiles and click Next.

On the next screen, make sure your project is selected. You can keep leave the options on their default settings. Click Finish to generate your build.xml file.

Lastly, to ensure Travis CI runs the project correctly, create a .travis.yml in your project's root folder. For Java projects, it should contain at least the following.

language: java
jdk:
  - oraclejdk8

script: ant build

Source: Kofun devblog - Using Travis CI with Java Eclipse Project


Group authentication in kubernetes I am trying to implement group based authentication in k8s with RBAC. My requirement is as below:
There is a linux group named "readonly". There are 3 users reader1, reader2 and reader3 in readonly group.
How can I implement the RBAC to give readonly access to all the users who are part of that group and all the future users who will become part of that group ? Readonly access means, access to list, get and watch resources using kubectl.
I came across .subjects[0].kind: Group in clusterrolebinding. But not sure how can that be used or if that can even be used for the above scenario
Thanks.

This is something I have implemented recently.
NOTE: I'm assuming you are aware ho to add users. or users in group in this case.
here is what I have applied:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: readonly_role
rules:
- apiGroups:
  - ""
  resourceNames:
  - ""
  resources:
  - "pods"
  - "pods/logs"
  - "deployments"
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - authorization.k8s.io
  resources:
  - selfsubjectaccessreviews
  - selfsubjectrulesreviews
  verbs:
  - watch
  - get
  - list

---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: bind_readonly_dev_role
subjects:
- kind: Group
  name: myorg:readonly
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: readonly_role
  apiGroup: rbac.authorization.k8s.io

You can use either ClusterRole & ClusterRoleBinding or else just Role & Rolebinding, depending on your requirement. In case you are not looking for cluster scoped access, instead just a namespace, I would strongly suggest going with the Role & Rolebinding kind of object.
What I'm doing/creating in the above?
I'm creating one RBAC Role (readonly_role) scoped to Cluster.
and in that I'm specifying I want to let access pods, logs (i.e pods/logs), and deployments. additionally you. can also add things like services or else if you just want to give access to all specify "" instead.
in the 2nd part, I'm creating a ClusterRoleBinding Object named bind_readonly_dev_role  which ensures only users in group myorg:readonly are having this role or privileges in the role we just created (readonly_role ).
NOTE: Incase you want to allow proxy access to certain applications, like kubectl proxy.
you might have to specify them separately in the ClusterRole rules.
I do like this for one of my svc:
- apiGroups:
  - ""
  resourceNames:
  - dashboard:5000
  resources:
  - services/proxy
  verbs:
  - '*'

at last but not least, you have to test if the user has those privileges correct,
you can test like this:
kubectl auth  can-i get pods --as myorg:readonly

in the above replace the pods with the object you want the users of the group to have access to.
Hope this helps!


How many DB instances to use? When to switch to container services? I'm looking for some insights into cloud management. I won't go into much detail, I just need some general information/resources that I can follow, about these topics:

When to use container services like Fargate, ACI, App Service? If the project isn't big enough, is it worth to migrate from more traditional approach (so VM instances with docker-compose running inside)?
Managed DBs - I totally get their advantages and I'm a huge fan. But
they are expensive. How many instances should be deployed? Let's
assume that I have 5 independent projects and each project has
dev/staging/prod environments. Should I have 15 DB servers
(instances) running? Or can I perhaps run one DB instance and serve
dev/staging environments from there and keep prod instances
seperate? Important: I mean database server instances, not
databases.

I've been trying to find some info online but most docs don't go into that much detail. Could you give me some more insight on how to run this type of infra? Mind you, the projects are not big, the databases are 1-2 GB in size (dev/staging DBs much less than that). What approach would you choose and why?

The choice of the approach is a risk assessment, if one of the DB client (application) goes wild and bring your server instance down, what is the cost in term of human hours lost during the outage ?
If you run the DB yourself instead of managed you have to include your time costs to update it, backup it, monitoring it, etc. is it really cheaper ?
All this is very company specific and need to take into account the human cost, does a staging environment down block 1 or 80 devs ? Are the devs junior or senior ? The cost per hour of outage change a lot from these simple two metrics.
At the end of the day, that's a judgement on accepted risk of outage and capacity to restart versus administration time to avoid the outage for which there's no magical mathematics formula.


Snake bites its tail problem automating configuration of Certbot with Ansible I have a public web-site with Nginx in front of it. We use free Letsencrypt certificates to set up https. These are acquired and renewed by Certbot program. I want to implement entire servers configuration with Ansible playbooks. These playbooks have to:

Automatically setup everything from scratch on a set of freshly dispatched empty CentOS instances.
Be able to setup with a different domain name if necessary
Be completely idempotent so I can make small changes and just run them as is.

There are two similar problems I faced trying to achieve it.
The first is I need Nginx already running to fulfill challenges to acquire certificate and then run Nginx with different config to make use of now acquired certificate. When I acquire certificate Nginx has to serve some files for Letsencrypt to check. This incurs several problems:

Playbook has to run Nginx twice in one go with different configs. This is tricky to express using Ansible because of descriptive nature of playbooks. Nginx now has different states in just one Playbook execution. I no longer express state but rather instructions.
Using several slightly different configs means either a lot of Nginx config code repetitions or complex and confusing ifs in them.

The second problem is that I wanted to put all my Nginx configuration under VCS so I want playbooks to come with already written Nginx configs. However this not the way recommended by Certbot. Certbot wants you to use a command that parses and then generates Nginx configs to add a certificate there. This may seem convenient but I this way I cannot be sure the results are going to be completely reproducible. Suppose I acquire cert and generate config, then change something by hand and then I lose my servers and domain name and try to run them from scratch. Then some new problems may occur which otherwise wouldn't have. My Nginx configs are complex with many services on different ports, conditions and other details. I have to control how it looks like.
I considered making several different playbooks for different cases. But this also leads to code repetitions and makes using them more complex for a newcoming employee. And rarely used playbooks or scripts may become out of sync.
I did achieve a solution that passes all these criteria. But I am not happy with it because it turned out rather complex with Nginx configuration happening twice and many ifs and booleans variables. And it's not how Ansible playbooks are intended to be written. Is there a good way to do all this?

Don't read the text written on Certbot site, the real talk is in the documentation.
In order to make less actions, consider grouping configs by domains. Plays for a playbook in order to achieve what you want:
Deploy certbot and nginx with no config files, then for each domain on host:

Deploy an nginx config for default server with location /.well-known/acme-challenge { root /etc/letsencrypt/challenges; }
Reload nginx config
Check existence of a certificate for the domain in /etc/letsencrypt/live/domain
If cert is already presented, end the run
certbot certonly -n --web-root=/etc/letsencrypt/challenges --keep -d domain to make a cert request
Check for cert in a retry loop
Fix permissions for live certificates
Deploy normal nginx configs

You may deploy a stub config per domain instead of using the default server. The playbook could be run asynchronously for each domain.