title: Can't connect to my dockerized MySQL

text:
# Question
Title: 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?

# Answer
> 3 votes
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

# Answer
> 1 votes
First, confirm that the container is actually listening for connections and has properly bound to the interface. If not, you probably need to fix the `bind-address=` and/or `port=` directives in your my.cnf.

Otherwise, you probably have an issue with your GRANTs. Check that the IP/subnet is correctly authorized in the mysql.user table with the command

```
select user,host from mysql.user

```

If the host field is incorrect, you will need to fix it using a UPDATE

---
Tags: docker, mysql
---


title: GitLab Pages delivers random content

text:
# Question
Title: GitLab Pages delivers random content
I am experiencing weird behavior with the Pages feature of GitLab Omnibus package running on an Ubuntu 16.04 virtual machine. Some projects use Pages with Jekyll built by GitLab CI, which has been working as expected since it was first published with Gitlab CE.

For a couple of days now, visiting any of the homepages of those sites shows the content of just one of the projects. Each of them should of course show different content, but they all show the same. Even stranger: the content shown on each of the sites changes over time to one of the other projects, and I can not see whether this is deterministic.

Restarting the build processes of each of the projects did not fix this, neither did `gitlab-ctl reconfigure`, `stop` and `start`, nor rebooting the entire VM.

To investigate on that issue, I edited (which I assume is) the resulting file of the build process at `/var/opt/gitlab/gitlab-rails/shared/pages/www/www.domain.org/public/index.html`. Not in the first place, but later on during the already stated "rotating" content, the edits showed up on the webpage.

So what is going on there? Is this some caching issue? Is it malconfiguration? Is it a bug? Please help me find and fix the problem, as those are production websites.

# Answer
> 2 votes
Looks like this is actually an issue

---
Tags: gitlab
---


# Question
Title: How to mark a check as warning or error if a check fails multiple times within a certain time range using Sensu?
A certain check works, but it should be checked multiple times within a certain range before a user gets notified.

There are multiple Sensu attributes that could be configured. This list has been consulted, but no solution was found. Is it possible to mark a check as warning or error if a check fails multiple times in a certain time range?

Perhaps aggregates would be an option, but should this not be used for multiple clients instead of using it for one check?

> ```
> {
>   "clients": 15,
>   "checks": 2,
>   "results": {
>     "ok": 18,
>     "warning": 0,
>     "critical": 1,
>     "unknown": 0,
>     "total": 19,
>     "stale": 0
>   }
> }
>
> ```

# Answer
You want to use the `occurrences` filter, which is included by default in Sensu.

First, apply the filter to your handlers:

```
{
  "handlers": {
    "email": {
      "...": "...",
      "filters": ["occurrences"]
    }
  }
}

```

Then, in your check, you can use the `occurrences` attribute to only trigger the handler once the check fails or warns a certain number of times in a row:

```
{
  "checks": {
    "check-http": {
      "...": "...",
      "occurrences": 2
    }
  }
}

```
> 4 votes

# Answer
https://sensuapp.org/docs/0.28/reference/plugins.html#check-definition-attributes

The `occurrences` as defined in the other answer was required (+1). The `refresh` and `interval` were needed as well.

Refresh and occurrences had to be assigned to a check. It was not needed to change the handlers.

```
"a-check": {
  "command": "echo hello"
  "occurrences": 6,
  "refresh": 60,
  "interval": 10
},

```

https://gist.github.com/calebhailey/8a30a00c6aadfebf7f767444f0a3df49

The `interval` means after how many seconds a check is executed. The refresh means that after `60 seconds` a notification is sent and the occurrences mean that if within 60 seconds the event was triggered 6 times that a notification will be sent.

It seems like the formula is as follows:

`occurrences` * `interval` = `refresh`

`10` * `10` = `100`
> 1 votes

---
Tags: sensu
---


# Question
Title: Updating Opera browser through command line (Windows)
I'm writing a script that suppose to, among others, update Opera browser on the machine it's running on. Is there a way to update it through cmd? Is there a universal way to do so for any chromium based browser?

# Answer
> 1 votes
One you use chocolatey to install Opera. Upgrading is also supported:

```
choco upgrade opera

```

---
Tags: windows
---


# Question
Title: Is there a standard way to check if a web API is alive?
As a developer, I have been involved in producing a number of assorted web-APIs, both for internal and public use.

**Is there a standard (or de facto) way of checking if a web API is up and running?**

(And possibly report back e.g. deployment info and other metadata.)

Web APIs usually don't have a handler for a `GET` to the root-URL, and often require authentication for the other URLs. Sometimes I have solved this by adding a specific `GET http://example.com/alive` or `GET http://example.com/hello` handler in order to enable our devops to monitor the API and to make it easier for myself to quickly check if it is running. It would be nice if there was a more... official way. (:

# Answer
`It would be nice if there was a more... official way. (:` If this is not an official way how to check it? One could also say that if there are only POST's then why not using a POST?

Some services only have POST and these are checked by doing an automated POST every X minutes and check the output. If the POST fails then the monitor system will notify the team.
> 1 votes

---
Tags: deployment, monitoring
---


# Question
Title: SaltStack: Use Temporary Scripts And Not Cause State Changes To Reported
I am doing some operations with Kafka via salt, and using scripts to perform them.

My current SLS file looks roughly like:

```
/tmp/script.sh:
  file.managed:
    - source: salt://blah/blah

Run script:
  cmd.run:
    - name: /tmp/script.sh

delete /tmp/script.sh:
  file.absent
    - name: /tmp/script.sh

```

`script.sh` is idempotent itself. But I always get a `changed=2` status report at the end of applying the state, because of it putting the script down and then deleting it.

Is there a more idiomatic way in Salt to have temporary scripts that don't live on the target box? Or do people usually just leave them in /tmp so that they don't see a reported change when applying a state.

# Answer
> 0 votes
You might want to consider adding an `unless` or `onlyif` requisite in the first directive - especially if script.sh is particularly complicated or expensive. With `unless` or `onlyif`, you will use the reults of several BASH commands to determine if you need to push down and execute your script. If your system is out of plumb only then is the state enforced. If everything checks out OK, then the script will never be pushed and executed preventing `changed=2` in the final status report. You will want to use a require requisite for the second and third directives to prevent them from running if the script is not pushed by `file.managed` otherwise you will get to errors instead of two changes.

---
Tags: salt
---


# Question
Title: Why does the datasource "external" always fail?
so my issue here is that terraform really does not like a command I'm trying to run using an external datasource.

I'm trying to hack my way around a problem where terraform wont wait for a KMS encrypt operation to complete before attempting to use the ciphertext returned by KMS. I've also raised an issue in the terraform for this.

So here is what I'm attempting to do:

```
resource "aws_kms_alias" "kms_alias" {
    name          = "alias/${var.lambda_name}"
    target_key_id = "${aws_kms_key.hook_url.arn}"
}

data "external" "encrypt_url" {
    program = ["bash", "export ENC_HOOK_URL=$(aws --profile $${AWS_PROFILE} \
    kms encrypt --key-id $${KMS_ALIAS} --plaintext $${HOOK_URL} --output json \
    --region $${AWS_REGION})"]
}

resource "aws_lambda_function" "lambda_function" {
    depends_on       = ["data.external.encrypt_url"]
    filename         = "deploymentPackage.zip"
    function_name    = "${var.lambda_name}"
    role             = "${var.lambda_role_arn}"
    handler          = "index.lambda_handler"
    source_code_hash = "${base64sha256(file("deploymentPackage.zip"))}"
    runtime          = "python3.6"
    publish          = "true"

    environment {
        variables = {
            HOOK_URL = "${data.external.encrypt_url.result.ciphertextBlob}"
        }
    }

    tags {
        LastUpdated = "${var.timestamp}-${var.iamuser}-Terraform"
    }
}

```

This will run fine without the `encrypt_url` datasource but will fail with the following error when trying to run:

```
data.external.encrypt_url: data.external.encrypt_url: failed to execute "bash":
bash: export ENC_HOOK_URL=$(aws --profile ${AWS_PROFILE} kms encrypt --key-id ${KMS_ALIAS} --plaintext ${HOOK_URL} --output json --region ${AWS_REGION}):
No such file or directory

```

Now no file or directory is attempting to be called here and I'm unable to find much information about this because this function is not well documented.

If anyone has any pointers that'd be great!

# Answer
> 2 votes
The command being run by the `external` provider here is equivalent to the following:

```
bash "export ENC_HOOK_URL=$(aws --profile ${AWS_PROFILE} \
kms encrypt --key-id ${KMS_ALIAS} --plaintext ${HOOK_URL} --output json \
--region ${AWS_REGION})"

```

Bash is failing here because when used in this way it expects its first argument to be the filename of a script to run.

The `-c` option changes this interpretation so that it will instead expect this argument to be an *inline script* to run, which seems to be what you intended here. This could be expressed in the Terraform configuration like this:

```
data "external" "encrypt_url" {
  program = ["bash", "-c", "export ENC_HOOK_URL=$(aws --profile $${AWS_PROFILE} kms encrypt --key-id $${KMS_ALIAS} --plaintext $${HOOK_URL} --output json --region $${AWS_REGION})"]
}

```

Along with adding the `-c` option, it also seems like this script doesn't actually do anything, instead just assigning a result to a variable. Given that you asked the AWS command to produce JSON, I think perhaps the following will do what you want:

```
data "external" "encrypt_url" {
  program = ["bash", "-c", "aws --profile $${AWS_PROFILE} kms encrypt --key-id $${KMS_ALIAS} --plaintext $${HOOK_URL} --output json --region $${AWS_REGION}"]
}

```

In the interests of readability though, I'd recommend moving this command into an external script file (e.g. `encrypt_url.sh`) and then referencing it from the config:

```
#!/usr/bin/env bash

aws --profile ${AWS_PROFILE} \
    kms encrypt --key-id ${KMS_ALIAS} \
                --plaintext ${HOOK_URL} \
                --output json \
                --region ${AWS_REGION}

```

...

```
data "external" "encrypt_url" {
  program = ["bash", "${path.module}/encrypt_url.sh"]
}

```

This avoids the need for escaping the dollar signs, allows you to edit it in your text editor's shell script highlighting mode, and allows the script to be easily run outside of Terraform for testing purposes.

---
Tags: amazon-web-services, terraform, amazon-kms
---


# Question
Title: How to support releasing new versions of the code, running in parallel with the last stable release?
I have one service in production (on AWS), which follows the immutable server pattern. Its deployment looks like this:

1. Create a new AMI with Packer.
2. Create a new CloudFormation stack, starting with an auto-scaling group of size 1.

When I see that the new release is good, I can increase the number of instances and eventually shutdown old instances and finally remove the CloudFormation stack from the previous release.

In my initial version of the deployment, I used only one stack and updated it in place. For normal releases, that meant an the auto-scaling group was modified by CloudFormation to point to the new AMI. Then I had to either kill an existing instance or increase the auto scaling group to get an instance with the release running.

Using a new stack for every release makes the process simpler for me, as rollbacks are easier and it makes rolling out releases to parts of the users easier. Similar to the immutable server pattern, I avoid in-place updates but instead only create new resources (stacks in this case).

In the company that I work for, it is now more common to use Terraform instead of CloudFormation. I wonder if it is possible to adept the deployment that I sketched with Terraform. I don't mind using another tool, my main point is that I would like to preserve these basic concepts:

* Allow deployments of new releases without touching the stable release
* Instead of (in-place) updating the setup, only create new resources and kill the old resources.

So, far I have only briefly worked with Terraform and used it only to manage some small part for our infrastructure. As recommended, I kept the state in an S3 bucket, for instance:

```
# (from main.tf)
terraform {
  required_version = ">= 0.9.4"
  backend "s3" {
    bucket = "example-company-terraform-state"
    key    = "/foo-service/terraform.tfstate"
    region = "eu-central-1"
  }
}

```

Here, the key is always fixed. So, Terraform will update everything in place. I assume you could use a new key for new releases to have a similar effect as creating new CloudFormation stacks.

What I did not figure out is how to move traffic to the new instances. All instances should be behind an load balancer (ELB). I think, you could use a separated setup for the ELB, which will distribute traffic to instances from both the old and the new release.

So, if a new release is rolled out, there would be three different Terraform states:

1. Terraform setup for the ELB
2. Terraform setup for the old release (more specifically, its auto-scaling group)
3. Terraform setup for the new release

**Questions:**

* Has the approach of using different S3 keys for the Terraform state the same effect as using separate CloudFormation stacks? (What I'm looking for is a way to have multiple Terraform setups that do not interfere with each other.)
* Do you see a solution to the problem of getting all instances (from the old and the new release) behind a shared ELB?
* I read that you can export resources in Terraform. Do you think, I could create a Terraform setup for the ELB, export the ELB as a resource, and use it in the Terraform setup for the instances (plus auto-scaling group) to make them attach to the shared ELB?

---

Note: For my other service, where I use CloudFormation, we do not use an ELB, so it is strictly speaking a different problem. I only mentioned it to explain what I found useful about the deployment and why I think about applying some of the ideas for other services.

# Answer
There are a few different ways to achieve goals of this sort, each with some different tradeoffs. I'm going to describe the most common ones below.

---

The simplest approach is to use Terraform's `create_before_destroy` mechanism with autoscaling groups. An example of this pattern is included in the `aws_launch_configuration` documentation.

In this scenario, changing the AMI id causes the launch configuration to be re-created. Due to `create_before_destroy`, the new configuration is created first, then a new autoscaling group is created, adding the new instances to an attached ELB. The `min_elb_capacity` argument to `aws_autoscaling_group` can be used to ensure that a given number of instances are present and healthy in the attached ELB before considering the autoscaling group to be created, thus delaying the destruction of the old autoscaling group and launch configuration until the new one is serving requests.

The downside of this approach is the lack of control it represents. Since Terraform is thinking of the entire set of changes as a single run, it's impossible to pause after creating the new instances to allow other checks to be carried out before destroying the old ones. As a consequence, the ELB healthcheck is the only input to deciding if the new release is "good", and rolling back is impossible once the old resources have been destroyed.

---

A second common approach is to adopt a sort of "blue/green deployment" pattern with explicit changes to two clusters. This is done by putting all of the per-release resources in a child module, and instantiating that module twice with different arguments. In the top-level module this would look something like the following:

```
resource "aws_elb" "example" {
  instances = "${concat(module.blue.ec2_instance_ids, module.green.ec2_instance_ids)}"

  # ...
}

module "blue" {
  source = "./app"

  ami_id = "ami-1234"
  count  = 10
}

module "green" {
  source = "./app"

  ami_id = "ami-5678"
  count  = 0
}

```

The principle of operation here is that in the "steady state" (no deployment in progress) only one of these modules has a non-zero count, and the other one has zero. During a deployment, they are both set to the same non-zero count, but with different `ami_id` values. Each deployment swaps which of the modules is the "active" module, with both being active *during* the deployment.

When using this approach, each step is a distinct Terraform operation:

1. change count of the *inactive* module to nonzero and set its AMI id
2. apply the change with Terraform, thus activating the new module
3. verify that the new release is good
4. change count of the older module to zero
5. apply the change with Terraform, thus deactivating the old module

Although this has more steps, it allows arbitrary verification and an arbitrary amount of time to pass during step 3. It also allows "rolling back" by resetting the previously-inactive cluster count to zero.

Since both the old and new clusters exist in the same configuration, there is the risk of using this pattern incorrectly and prematurely destroying the active cluster. This can be mitigated by carefully reviewing Terraform's plan to make sure it leaves the old cluster untouched, but Terraform itself can't guarantee this.

Also, since both clusters are using the same child module configuration, it can be tricky to make updates to that configuration while retaining the blue/green separation. If changes are made that would require Terraform to replace the running instances, it's necessary to temporarily have two copies of the module code on disk, make the `source` arguments point to separate copies, and make the change only to the copy used by the inactive module.

---

The final approach I'll present is the most extreme and manual, but it does the best job of meeting your requirements and retaining control. This is, in effect, the most literal interpretation of your current CloudFormation workflow, and is a more concrete version of the approach you talked about in your question.

In this approach, there are two entirely-separate Terraform configurations, which I will call "version-agnostic" (things that must survive between versions, such as your ELB) and "version-specific" (the resources that are re-created for each new version).

The version-agnostic configuration will contain the ELB and will, as you suspected, export its id for consumption by the version-specific configuration:

```
terraform {
  required_version = ">= 0.9.4"
  backend "s3" {
    bucket = "example-company-terraform-state"
    key    = "exampleapp/version-agnostic"
    region = "eu-central-1"
  }
}

resource "aws_elb" "example" {
  # ...
}

output "elb_id" {
  value = "${aws_elb.example.id}"
}

```

This configuration can be initialized, planned and applied as usual, creating an ELB with no attached instances to start.

The version-specific configuration would be similar to the "app" child module in the previous approach, but this time as a top-level module. The backend configuration for this module would omit the S3 key, since this will change for each new release as you expected:

```
terraform {
  required_version = ">= 0.9.4"
  backend "s3" {
    bucket = "example-company-terraform-state"
    region = "eu-central-1"
  }
}

```

The specific key can then be set (or re-set) when running `terraform init`:

```
$ terraform init -reconfigure -backend-config="key=exampleapp/20170808-1"

```

Here I chose to use a "current date, release index" tuple as an identifier for a release. By running `terraform init` with a new value for this argument, an entirely separate state is created, independent of the last. Using `-reconfigure` tells Terraform that you don't wish to migrate the old state to the new, but rather to just switch directly to the new state path, possibly creating a new state in the process.

You can then run `terraform show` to confirm that indeed the state is empty (and thus operations won't affect existing resources) and then run a plan/apply cycle as normal.

Once you're satisfied with the new release, you can switch back to the previous version and destroy it.

The version-specific configuration will need the id of the ELB from the version-agnostic configuration in order to populate the `load_balancers` attribute of `aws_autoscaling_group`. To get access to this, we can use the `terraform_remote_state` data source to read the values from its state in S3:

```
data "terraform_remote_state" "version_agnostic" {
  backend = "s3"
  config {
    bucket = "example-company-terraform-state"
    key    = "exampleapp/version-agnostic"
    region = "eu-central-1"
  }
}

resource "aws_autoscaling_group" "example" {
  # ...

  load_balancers = ["${data.terraform_remote_state.version_agnostic.elb_id}"]
}

```

With a system of this complexity, it would likely be best to run Terraform via some sort of wrapper script or orchestration to make the release process less onerous. For example, such a script might automatically generate the new version number to avoid the risk of a human operator mistyping the date or accidentally conflicting with an existing one. There's some recommendations and caveats about running Terraform via scripts in the guide *Running Terraform in Automation*.

---

Although the third option here is the most direct mapping of your CloudFormation approach, the second option is more commonly used due to it striking a reasonable compromise between control and workflow overhead.
> 19 votes

---
Tags: amazon-web-services, deployment, terraform, immutable-servers, aws-elb
---


title: Jenkins Promotions vs Pipelines

text:
# Question
Title: Jenkins Promotions vs Pipelines
We've been starting to link build&test&deployment jobs together into sequential tasks (for now as simple as: build -\> run tests -\> if tests pass -\> deploy) and had some experiments with Promoted Builds and Pipelines.

Is our understanding correct that Promoted builds and Pipelines are two different separate strategies to Continuous delivery? Or, can they still be used together?

# Answer
I just configured `promoted builds plugin` and the `pipelines` plugin and found at least one difference between the two plugins, i.e. the first plugin seems to be able to allow manually deploy of certain stages, while the pipelines plugins seems to deploy everything automatically.

According to this answer, manual deploy of a certain stage seems to be missing.

In summary, it seems that it would be nice to combine the two plugins as it could be handy to have a manual check before deploying to production, i.e. a human has to press the button in order to deploy to production.

According to this answer it is not possible to combine both plugins at the moment.
> 3 votes

---
Tags: jenkins, continuous-delivery
---


# Question
Title: terraform - how should I clone my code repo?
I have a very simple terraform configuration. I boot up an aws instance of Ubuntu trusty and assign a security group.

My question is who is responsible of getting the latest code from my code repo? is it a bash script in terraform `user_data` argument or should I make a modified AMI that has a bash script to pull the code repo.

Basically my repo has docker configuration in it and all i need is to clone and do `docker-compose -f env.yml up`

# Answer
You can achieve the clone of the repo and the execution of docker-compose in several ways.

You are right when you think that cloud-init could do that. Check this link for more information
> 1 votes

---
Tags: docker, amazon-web-services, terraform
---


# Question
Title: What are best practices to solve `All files/directories will have '-rwxr-xr-x' permissions` when building docker images on Windows?
When a docker image is built on a Windows host the following message is returned:

```
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows
Docker host. All files and directories added to build context will have '-rwxr-xr-x'
permissions. It is recommended to double check and reset permissions for sensitive files
and directories.

```

# Answer
It is not currently possible to disable that warning, see discussions on Issue 20397:

> That warning was added, because the Windows filesystem does not have an option to mark a file as 'executable'. Building a linux image from a Windows machine would therefore break the image if a file has to be marked executable.
>
> For that reason, files are marked executable by default when building from a windows client; the warning is there so that you are notified of that, and (if needed), modify the Dockerfile to change/remove the executable bit afterwards.

In a sense this also means it's practically impossible to actually solve the issue.

What maybe can help a bit is moving the error message from stderr to stdout, released in docker 17.04. See Issue 29856.
> 5 votes

---
Tags: docker, windows
---


# Question
Title: How to allow users to list authorized buckets in GCP Storage?
I created a storage bucket B and I granted a user as "Storage Object Viewer" on it. The user can view bucket content with a direct link (e.g. https://console.cloud.google.com/storage/browser/B/?project=azerty).

Is it possible to allow a user to list all buckets that he is allowed to read? It would be more user friendly to see them in Storage Browser Web console i.e. https://console.cloud.google.com/storage/browser

# Answer
It's not currently possible to list all the accessible buckets **across all cloud projects**, neither in the developer console browser nor via the `gsutil` command. Both of them only display buckets for one project at a time.

But if you specify a particular project (or stick with the one selected by default) you can list the accessible buckets inside that project in both `gsutil` (as shown in @chupasaurus's answer) and in the developer console browser. In the browser you get to the project selection popup by clicking on the project's dropdown menu in the top navigation bar.

You could try to file a feature request for it at https://issuetracker.google.com/components/187243/manage#basic, it *might* get accepted if it shows enough interest.
> 1 votes

# Answer
From AWS documentation: "The `ListAllMyBuckets` operation returns a list of all buckets **owned** by the sender of the request.". Owned, not having some access to it, and IIRC you can't see all the buckets you have read access in AWS Console either.

`gsutil -p azerty ls gs://` would show all buckets which user have List access to.
> 0 votes

---
Tags: google-cloud-platform, google-cloud-storage, gcp
---


# Question
Title: How to set CloudWatch alarms for non-compliancy in AWS Config rules?
I have a set of rules in my AWS Config dashboard. And, I want to set a AWS CloudWatch alarm to be triggered whenever Config detects non-compliant resource(s).

\[The plan is to link that alarm to an SNS topic for sending out emails to the team for any non-compliant event/resource\]

Is there a straightforward way to do that? Or is there a workaround for the same?

---

I went through the available metrics in the Cloudwatch dashboard, but haven't found anything related to AWS Config.

# Answer
> 1 votes
From what I know of AWS Config there's no way at the moment to directly publish a metric from which you can base an alarm.

If the notification has to come from a Cloudwatch alarm then AWS Config will let you execute Lambda based on rules set up in AWS Config - link.

If you want a simpler option AWS Config also lets you publish directly to an SNS topic when your rule is evaluated - link

Failing this you can also watch for CloudTrail events and then publish a CloudWatch metric which you can base an alarm on. This is fairly in depth though and if the important part is getting the emails to be looked at by a person then your best bet is probably to have AWS Config publish directly to SNS itself.

---
Tags: amazon-cloudwatch
---


# Question
Title: Google CloudPlatform remove/delete app deployed during tutorial steps
I created a Project at Google CloudPlatform, and followed it's on screen tutorial to deploy an PHP app.

Now that it's done, how can I delete/remove the deployed app to prevent charges.

I saw an option at: "`Google Cloud App Engine -> Settings -> Disable App`" but does it prevent charges?

# Answer
Yes, disabling an application prevents charges, but only from the App Engine prospective, there could still be other changes from other Cloud products usage. From Disabling an application:

> Your app's resources in both the standard and flexible environment are disabled and therefore, won't incur charges. However, billing charges can still occur for the other services in your Cloud Platform project, for example you can still incur storage charges for your stored data.

To completely end all Cloud billing for a project you can shut it down (i.e. mark it for deletion!). But please note that you won't be able to re-use its ID, ever.
> 0 votes

---
Tags: google-cloud-platform
---


# Question
Title: 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

1. Comparing the authkeys with my login key. It is same.
2. Copying the key from a ssh working instance to this volume and re-launching. Same error.
3. 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.

# Answer
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.
> 3 votes

# Answer
One way I get locked out while developing is by changing the permissions on any of the directories or files associated with the keys used by `ssh`. This happens to me when I untar files or run some installation script while initializing the machine that touches the `ec2-user` account.

Make sure the permissions are like:

```
1> ls -ld $HOME $HOME/.ssh
drwx------ 15 ec2-user ec2-user 4096 Aug  1 13:15 /home/ec2-user/
drwx------  2 ec2-user ec2-user 4096 Jun 10 11:18 /home/ec2-user/.ssh/

2> ls -l $HOME/.ssh/authorized_keys
-rw------- 1 ec2-user ec2-user 385 Jun 10 11:18 /home/ec2-user/.ssh/authorized_keys

```

If not, and you are logged in as `ec2-user`, you can change them with

```
sudo chown ec2-user:ec2-user ~ec2-user ~ec2-user/.ssh ~ec2-user/.ssh/authorized_keys
chmod 700 ~ec2-user ~ec2-user/.ssh
chmod 600 ~ec2-user/.ssh/authorized_keys

```

To protect myself against my own mistakes, I create a new user and copy the `ec2-user` key over. That account is used as a backup and not part of any script. Once I tested everything, I remove the account.
> 2 votes

# Answer
**Thumb Rule:** Not finding a root cause is Not a solution

Now from your inputs What we get is

1. You get locked out while using SSH login (passwordless)
2. You are able to login if its password login

what I think might have happened is that your private key file format might have been changing (one consideration is EOL) if you are using a windows / mac or linux editors or switching between them for SSHing into the remote.

So do a "cat -e ~/.ssh/id\_rsa" and check the contents if you see a ^M at the End of the line , then most probably you have edited the private file with a CRLF editor. Do a "dos2unix ~/.ssh/id\_rsa" to convert the file to LF format

Check this https://unix.stackexchange.com/questions/32001/what-is-m-and-how-do-i-get-rid-of-it
> 0 votes

---
Tags: amazon-web-services, amazon-ec2
---


title: LambdaA -> delay mins -> lambdaB

text:
# Question
Title: LambdaA -> delay mins -> lambdaB
I need to launch a LambdaA function and after X minutes I need to launch a LambdaB function with parameters passed from LamdaA

I have testing the following:

APIGW \> LambdaA \> SQS with delay \> SQS can't trigger lambda functions APIGW \> LambdaA \> SNS \> trigger LambdaB . In that case I can't add a delay

I need to do it serverless and without constant pooling for a queue or new messages.

Is there any other possibility to trigger a second lambda function with a "big" delay?

# Answer
Use Step Functions. They allow you to coordinate lambda functions and have an inbuilt wait state
> 5 votes

# Answer
From your comment above:

> The main difficult is launch the second lambda with a delay from the first one and without doing a pooling constantly

As using SQS queues are an option for you, you can make CloudWatch alarms which can monitor for activity in the queues, and link them up with SNS, which can be used as a trigger for LambdaB.

So, your flow can be:

```
Lambda1 --> SQS --> CloudWatch metric linked to an alarm --> SNS --> Lambda2

```
> 2 votes

---
Tags: amazon-web-services, aws-lambda, serverless
---


title: AWS Spot instances price

text:
# Question
Title: AWS Spot instances price
While trying to create spot instances I notices that the Price for almost all instance types (from m3 , c3, c4) are always higher than the On-Demand price of corresponding variants in us-east-1c and us-east-1f regions (for almost 3 months)

Can someone explain why? Is AWS falling short of VMs in those AZs?

# Answer
You notice that you now have access to 6 availability zones in us-east-1, where you previously only had 4 or 5.

Adding capacity is the reason that new availability zone is now available.

Because of the way the spot market works, there is no way to know what the highest winning bid was, at any given time... because the current market price is based on the *lowest* winning big for each round. That sounds counter-intuitive, but here's the logic: given *n* available instances in the spot market, the system identifies the highest *n* bids. These bids are the winning bids. The *lowest* of these winning bids is the price all of the winners will pay, and becomes the new current market price.

Each time the market shifts (new bids arrive, or active apot requests are canceled, or on-demand instances are started/stopped, presumably resulting in the available spot pool growing or shrinking), the system re-evaluates all the bids. If you are no longer a winning bidder, your instance will be terminated, but if you're a new winner, you'll get the instance you've been waiting for.

Based on what's publicly known, we can conclude these things:

* the current market price is the lowest bid among all the current winning bidders, assuming there are any winning bidders
* you will not get a spot instance right now if you bid below the current market price, but you'll get one if/when the price drops below your current bid.

Therefore, when the spot price is at maximum, there are no unsold spot instances. We can logically conclude that this is necessarily true, because:

* a single winning bid that is lower than the maximum would cause the market price to be lower than thr maximum; therefore, it defies logic that there could be any spare capacity, because this implies that all current winning spot instance bidders made outrageous bids when they could have obtained the instances for substantially less money either by placing a smaller spot bid or by using an on-demand instance
* it also defies logic that AWS would artificially inflate the price above the on-demand price, because there is no rational reason for someone to pay more in the spot market when the could use an on-demand instance.

We can further conclude that one of two things has happened to cause this, both of which have the same net result:

* there is no spot capacity available at all -- if this is true, it makes sense that the indicated price would stick to the upper maximum value, because you must bid at or above the current price to get an instance now. The actual market price in a situation where there is no capacity at all would be more properly called `NULL` because there is no price at which you can obtain a spot instance. Or, you might say the current market price is infinite, because regardless of how high you bid, you can't have a machine that doesn't exist. Some might naïvely say the current price is $0 but that is definitely incorrect and would send the wrong market signal. Where this leaves us is that the most logical *representation* for the price in a zero-capacity condition would be the maximum/ceiling price. This gives a clear market signal to any sensible algorithm -- don't bid in this market, the value is not there; or
* there is some capacity, but it's all claimed by people who bid the maximum possible.

Which of these two conditions is actually true doesn't matter, because the net impact is the same -- no available capacity.

If that second possibility doesn't make sense to you, that's because you are a rational person. There are always people who try to game the system.

Instances in the spot market are ephemeral, since the market shifts are outside your control. I've had spot instances run uninterrupted for many months on end, and I've had them cycle up and down many times over the course of one day. This is part of the market.

It is possible to improve the chance of a spot instance persisting by placing a high bid... but it is not possible to *guarantee* that a spot instance will keep running, regardless of how high you bid... because even if all the high bidders colluded with each other and bid the exact same high price, the capacity is finite, so if all current spot instance capacity is sold, not all of the high bidders would have machines allocated to them.

However, there's always that guy who thinks he's smarter than the rest of us, bidding far too high, presumably on the assumption that his instances are likely to continue running, and that since price spikes are transient, he expects only to pay the high price for only a short time. If there are such gamblers in the market, then they would have the same effect of pushing the price to its limit when capacity is constrained. This becomes clearest when you consider the fact that if there were only 1 available machine, then only 1 person needs to place an outrageous bid, to set the market price unreasonably high.

The maximum spot price bid is now 10x the on-demand price. This has not always been the case. The logical conclusion is that there are indeed those who bid outrageously high, because they are trying to game the system and use spot instances for a persistent workload, so they bid high to try to keep those machines running. It's a flawed strategy, but it does explain the prices hitting the ceiling and sticking there when capacity is limited.
> 6 votes

# Answer
Essentially yes. From what I've observed when there is limited capacity in that availability zone the spot price jumps to 10x the on demand price.

Be sure to use as many AZs as possible (6 currently in us-east-1) when using spot instances to provide better guarantees you can launch an instance.
> 4 votes

---
Tags: amazon-web-services, amazon-ec2
---


# Question
Title: Best method of retrieving environment information via Salt Stack?
I have been tasked with using Salt Stack to find out what files/services exist in each of our environments (Test, UAT, Production).

The Salt master can speak to all servers in Test and UAT (Production Salt master is yet to be configured) so I was thinking of creating a state in 'base' which can target all minions just doing simple file.exist queries. However I quickly came to the realisation that certain files won't exist on certain servers due to the different nature of them. E.g. Our API server has a lot of specific scripts and configs which won't exist on our LDAP server.

What is the most efficient and scalable way of implementing this? Could I define roles for each type of server (e.g. webserver, ldap server, api server) and therefore a specific state for each role?

# Answer
> 3 votes
SaltStack provides a method for modifying grains and adding additional information to the grains dictionary in several different ways by either setting them in the /etc/salt/minion config and/or through the /etc/salt/grains file.

For example: 1. add grains to the minion config. Note, simply include the grains key here:

> ```
> id: minion-07
> grains:
>   roles:
>     - production
>   region: nl-amsterdam
>
> ```

2. add custom grains within the /etc/salt/grains file. Note, add grains without prefacing them with grains:

> ```
>    roles:
>        - production
>      region: nl-amsterdam
>
> ```

3. Alternatively you may set roles via command line shell from master or from salt minion:

> `salt 'your minion' grains.setval roles [production, dev, qa]`
>
> `salt-call grains.setval roles [production, dev, qa]`

For matching grains I usually use Jinja2. Or you may refer to commandline/config file approaches:

> `salt -C 'G@roles:production' test.ping`

By using sytnax in the top.sls file:

> ```
> base:
>   'roles:production':
>     - match: grain
>     - salt.master
>   'roles:dev':
>     - match: grain
>     - api-dev
>
> ```

Alternatively you may consider using environments in SaltStack, see here for more details: https://docs.saltstack.com/en/latest/ref/states/top.html#environments

However, roles are more suitable for running specific states, at least We use them in our our company. So up to you what is the best ;)

---
Tags: linux, configuration-management, salt, scalability
---


title: Can I rename an RDS instance?

text:
# Question
Title: Can I rename an RDS instance?
I have inherited a collection of RDS MySQL instances with random (useless) *DB Instance* names.

I often have to dig into the *tags* section to find out which project they belong to.

One of the settings I can modify in an RDS is the `DB Instance Identifier`.

If I change this, what will happen besides for the name change? **Will it affect anybody's code?** Or is it a harmless change?

These are live systems that I cannot afford to bring down.

# Answer
> 10 votes
Yes, you can rename an RDS instance... at your own peril.

> When you rename a DB instance, the \[DNS\] endpoint \[hostname\] for the DB instance changes, because the URL includes the name you assigned to the DB instance.
>
> http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER\_RenameInstance.html

Your application code requires configuration changes to be coordinated, for this reason.

See the link above for the other implications. This is a supported and generally safe operation, but only in your maintenance window, because there will necessarily be a brief disruption as the DNS is changed and your app code is cycled in with the new database hostname.

# Answer
> 3 votes
Yes you can change the name of the RDS instance, but it is highly discouraged to do so in LIVE Production environment. It would change the EndPoint which might impact other resources actively accessing the RDS server (like an application server).

This would probably require a property / env-variable change in your code or configs (which would ideally end up for a release of config through config management)

To avoid disruption (In future) and rollout changes with lesser RTO , you can create an intermediate DNS entry (CNAME) in Route53 for your RDS server and use the intermediate URL in your application. When the RDS server name changes you could just change the DNS CNAME of the new RDS Endpoint. **NOTE:** During the name change your RDS server would be unavailable (with old name) for few minutes and this might cause disruption

That being said, you are already biased on a solution (change of RDS names) for your problem. BuT

There are multiple solutions for your actual problem (managing RDS servers for each project)

A. Try to avoid using AWS Console as much as possible. Why dont you start looking into AWS CLI (which can pull the tags) and write a wrapper Python/Bash script to list all the RDS servers - with Project Names, from this output you could manage these servers, like take a snapshot , backup etc. You can also use mysql --login-path (If you are on mysql for DB administration) https://opensourcedbms.com/dbms/passwordless-authentication-using-mysql\_config\_editor-with-mysql-5-6/.

B. (Cost agnostic approach) If you have anyways decided to change the RDS Names, then there is something you can do without any impact.

```
B.1 When the next code/config release happens try to bring in the intermediate DNS change into action.

B.2 (Optional) Enable Multi AZ in RDS (HA and twice the price). This will help your application to access the secondary active slave when there is any disruption due to name change. There is an option called Reboot with failover which would reboot the master while failing over to the active secondary

B.3 Enable replication (read-replica) (this will give you a new RDS end-point). Name the read replica properly with your project names

B.4. Once replication is complete (and during your SLA / maintenance window) promote your read replica (this will break replication) and make the intermediate DNS point to the new RDS (with your proper names)

```

> **NOTE** All the above approaches would not guarantee data integrity and improper data updates due to in-flight transactions. So it is always better to stop all transactions (by stopping all application accessing and deploying a maintenance page and do the operations)

---
Tags: amazon-rds
---


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

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

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

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

# Answer
> 4 votes
@Abhay Pai

why not posting this as 5 different questions?

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

---
Tags: docker, project-management, orchestration, sre
---


# Question
Title: Is it possible to recover accidentally deleted HashiCorp's Vault secrets?
According to this tutorial, it is possible to delete a secret, by running:

```
vault delete secret/hello

```

What will if someone in the organization accidentally removed a secret. Is it still possible to recover this?

# Answer
> 3 votes
If your secret backend is a separate service, which it should be, then with regular backups you should be able to stop vault, replace the backend with a backup and be good to go.

I've done this for a file backend but don't know what would happen for other backends so ymmv.

---
Tags: hashicorp-vault
---


# Question
Title: Are NixOS and GuixSD the incoming Linux distros of DevOps?
The main advantage of these distros is the declarative approach which allows for setup to be done in the same way as you would configure a Vagrantfile or Dockerfile.

In the way that Docker replaced/is replacing VMs for reproducibility, is there a chance these distros will eventually replace typical distros that are used in a DevOps setting due to their atomic and functional nature?

# Answer
> 2 votes
Some articles, including this one give some arguments why docker is popular:

> In a nutshell, here's what Docker can do for you: It can get more applications running on the same hardware than other technologies; it makes it easy for developers to quickly create ready-to-run containered applications; and it makes managing and deploying applications much easier. Put it all together and I can see why Docker is riding the hype cycle as fast as I can recall ever seeing an enterprise technology go.
>
> Moreover, for once the reality is living up to the hype. Frankly, I can't think of a single company of any size that's not at least looking into moving their server applications to containers in general and Docker in specific.

My personal view is that a tool could be successful if it will solve a (major) problem. For example, a half year ago I gave a presentation of docker in the company, the developers had some doubts until they experienced a issue that it was not possible to run all microservices on their local machine.

The same is applicable to the question:

> Are NixOS and GuixSD the incoming Linux distros of DevOps?

It depends whether these distributions will solve a (huge) problem.

---
Tags: linux, configuration-management, nixos
---


title: Understanding Docker layers

text:
# Question
Title: Understanding Docker layers
We have the following block in our `Dockerfile`:

```
RUN yum -y update
RUN yum -y install epel-release
RUN yum -y groupinstall "Development Tools"
RUN yum -y install python-pip git mysql-devel libxml2-devel libxslt-devel python-devel openldap-devel libffi-devel openssl-devel

```

I've been told that we should unite these `RUN` commands to cut down on created docker layers:

```
RUN yum -y update \
    && yum -y install epel-release \
    && yum -y groupinstall "Development Tools" \
    && yum -y install python-pip git mysql-devel libxml2-devel libxslt-devel python-devel openldap-devel libffi-devel openssl-devel

```

I'm very new to docker and not sure I completely understand the differences between these two versions of specifying multiple RUN commands. When would one unite `RUN` commands into a single one and when it makes sense to have multiple `RUN` commands?

# Answer
A docker image is actually a linked list of filesystem layers. Each instruction in a *Dockerfile* creates a filesystem layer that describes the differences in the filesystem before and after execution of the corresponding instruction. The `docker inspect` subcommand can be used on a docker image to reveal its nature of being a linked list of filesystem layers.

The number of layers used in an image is important

* when pushing or pulling images, as it affects the number of concurrent uploads or downloads occuring.
* when starting a container, as the layers are combined together to produce the filesystem used in the container; the more layers are involved, the worse the performance is, but the different filesystem backends are affected differently by this.

This has several consequences for how images should be built. The first and most important advice I can give is:

> **Advice #1** Make sure that the build steps where your source code is involved comes as late as possible in the *Dockerfile* and are not tied to previous commands using a `&&` or a `;`.

The reason for this, is that all the previous steps will be cached and the corresponding layers will not need to be downloaded over and over again. This means faster builds and faster releases, which is probably what you want. Interestingly enough, it is surprisingly hard to make optimal use of the docker cache.

My second advice is less important but I find it very useful from a maintenance view point:

> **Advice #2** Do not write complex commands in the *Dockerfile* but rather use scripts that are to be copied and executed.

A *Dockerfile* following this advice would look like

```
COPY apt_setup.sh /root/
RUN sh -x /root/apt_setup.sh
COPY install_pacakges.sh /root/
RUN sh -x /root/install_packages.sh

```

and so on. The advice of binding several commands with `&&` has only a limited scope. It is much easier to write with scripts, where you can use functions, etc. to avoid redundancy or for documentation purposes.

People interested by pre-processors and willing to avoid the small overhead caused by the `COPY` steps and are actually generating on-the-fly a *Dockerfile* where the

```
COPY apt_setup.sh /root/
RUN sh -x /root/apt_setup.sh

```

sequences are replaced by

```
RUN base64 --decode … | sh -x

```

where the  is the base64-encoded version of `apt_setup.sh`.

My third advice is for people who wants to limit the size and the number of layers at the possible cost of longer builds.

> **Advice #3** Use the `with`-idiom to avoid files present in intermediary layers but not in the resulting filesystem.

A file added by some docker instruction and removed by some later instruction is not present in the resulting filesystem but it is mentioned two times in the docker layers constituting the docker image in construction. Once, with name and full content in the layer resulting from the instruction adding it, and once as a deletion notice in the layer resulting from the instruction removing it.

For instance, assume we temporarily need a C compiler and some image and consider the

```
# !!! THIS DISPLAYS SOME PROBLEM --- DO NOT USE !!!
RUN apt-get install -y gcc
RUN gcc --version
RUN apt-get --purge autoremove -y gcc

```

(A more realistic example would build some software with the compiler instead of merely asserting its presence with the `--version` flag.)

The Dockerfile snippet creates three layers, the first one contains the full gcc suite so that even if it is not present in the final filesystem the corresponding data is still part of the image in same manner and need to be downloaded, uploaded and unpacked whenever the final image is.

The `with`-idiom is a common form in functional programming to isolate resource ownership and resource releasing from the logic using it. It is easy to transpose this idiom to shell-scripting, and we can rephrase the previous commands as the following script, to be used with `COPY & RUN` as in *Advice #2.*

```
# with_c_compiler SIMPLE-COMMAND
#  Execute SIMPLE-COMMAND in a sub-shell with gcc being available.

with_c_compiler()
(
    set -e
    trap 'apt-get --purge autoremove -y gcc' EXIT
    apt-get install -y gcc
    "$@"
)

with_c_compiler\
    gcc --version

```

Complex commands can be turned into function so that they can be fed to the `with_c_compiler`. It is also possible to chain calls of several `with_whatever` functions, but maybe not very desirable. (Using more esoteric features of the shell, it is certainly possible to make the `with_c_compiler` accept complex commands, but it is in all aspects preferable to wrap these complex commands into functions.)

If we want to ignore Advice #2, the resulting Dockerfile snippet would be

```
RUN apt-get install -y gcc\
 && gcc --version\
 && apt-get --purge autoremove -y gcc

```

which is not so easy to read and maintain because of the obfuscation. See how the shell-script variant outs emphasis on the important part `gcc --version` while the chained-`&&` variant buries that part in the middle of noise.
> 41 votes

# Answer
Each instruction you create in your Dockerfile results in a new image layer being created. Each layer brings additional data that are not always part of the resulting image. For example, if you add a file in one layer, but remove it in another layer later, the final image’s size will include the added file size in a form of a special "whiteout" file although you removed it.

Let's say you have the following Dockerfile:

```
FROM centos:6

RUN yum -y update
RUN yum -y install epel-release

```

The resulting image size will be

```
bigimage     latest        3c5cbfbb4116        2 minutes ago    407MB

```

As opposite, with "similar" Dockerfile:

```
FROM centos:6

RUN yum -y update  && yum -y install epel-release

```

The resulting image size will be

```
smallimage     latest        7edeafc01ffe        3 minutes ago    384MB

```

You will get even smaller size, if you clean the yum cache in a single RUN statement.

So you want to keep balance between readability/easy of maintenance and number of layers/image size.
> 14 votes

# Answer
The `RUN` statements represent each one layer. Imagine that one downloads a package, installs it and would like to remove it. If one uses three `RUN` statements then the image size will not shrink as there are separate layers. If one runs all the commands using one `RUN` statement the disk image size could be reduced.
> 5 votes

---
Tags: docker, dockerfile
---


# Question
Title: Running Ansible no-op's faster with a dynamic inventory and cached facts files
I've got an ever expanding playbook that patches a few hundred machines to the latest version, I just add the same role with different parameters.

Obviously, the playbook is taking longer and longer to run on each machine, even though it's not really doing anything on them.

What I'm doing is in the pre-tasks, I'm getting a changelog file, checking that and running each of the roles when an identifier that a successful run puts in that changelog file does not exist. But, even so, ansible still takes a fairly onerous amount of time to do nothing.

When I strace the main ansible process it looks like its trying to hit a bunch of non-existent cached facts files and the inventory script.

I think I've created the dynamic inventory correctly, it accepts both the "--host" and "--list" parameters (although I'm not certain that --host is being called).

I've got about 100 devices that I haven't gathered facts for in the inventory file and I've got:

```
fact_caching_connection = /tmp/factscache
fact_caching = jsonfile

```

set up.

If I take that out, it doesn't try to hit up the missing facts files, but it there is a `stat` in the strace against the inventory generator file over and over again. I know it can't be generating the entire inventory because that take 5 seconds.

I've tried generating regular inventory files and using those, I've tried generating inventory files with both \_meta and the regular host\_vars (currently using \_meta to house the host vars because I heard that was faster).

(running ansible 2.0)

# Answer
> 2 votes
Instead of storing the Ansible code centrally, one could extract the code and distribute it to every project. Another benefit of this approach is that config and code will be seen together and that developers will change config and Ops could fix e.g. bugs instead of working in silos. Running the code per project will prevent that the executions will take longer, longer and longer.

# Answer
> 1 votes
You could isolate the roles and run just them, you can generate a static inventory list before you run the particular role(and it's associated task).

Make sure that the task doesn't have a whole lot of inheriting/dependant roles. As 030 mentioned, it might be a good idea to implement some kind of way to semantically separate the roles.

---
Tags: ansible
---


# Question
Title: How are declarative distros different than Kickstart?
NixOS and GuixSD both bill themselves as "declarative" and DevOps-friendly. How and in what ways are these declarative distros different than Kickstart and/or a Linux distro managed by a configuration management tool?

What advantages and/or disadvantages are there to this style of declarative linux configuration as opposed to these currently existing technologies?

# Answer
> 5 votes
AFAIK Kickstart is only usable for the initial installation of the OS, but not for subsequent package maintenance upgrades/downgrades.

Unless I miss something (quite possible, I don't have much experience w/ them) the Linux distros managed by configuration management tools require a minimum level of health from the OS (and some package requirements, at least in some cases) to be able to operate those tools, say to perform a rollback. At least NixOS appears to not have such requirement (or rather it is already fullfilled at the OS level). From About NixOS:

> Rollbacks
>
> Because the files of a new configuration don’t overwrite old ones, you can (atomically) roll back to a previous configuration. For instance, if after a nixos-rebuild switch you discover that you don’t like the new configuration, you can just go back:
>
> ```
> $ nixos-rebuild switch --rollback
>
> ```
>
> In fact, all old system configurations automatically show up in the Grub boot menu. So if the new configuration crashes or doesn’t boot properly, you can just roll back by selecting an older configuration in the Grub boot menu. Rollbacks are very fast: it doesn’t involve lots of files having to be restored from copies.

# Answer
> 3 votes
**Pros:**

1. No configuration management tools like puppet, chef, salt or ansible needed

**Cons:**

1. **Dependent:** If one has written a lot of NixOps files and one decides to go to another provider then one has to rewrite all the provision scripts, while a tool like terraform is cloud agnostic
2. No autoscaling like docker
3. Promotion of silos, e.g. `DevOps friendly`. In my opinion dev should release software as well. Now one could just use docker that they use in development as well.

---
Tags: configuration-management
---


# Question
Title: Are distributed distributions like NixOS able to replace docker in terms of autoscaling?
Autoscaling means that the number of instances increases if the load intensifies. Docker is used in for example Kubernetes in order to autoscale. Are distributed distributions like NixOS suitable candidates for autoscaling as well?

# Answer
> 5 votes
Autoscaling has nothing to do with NixOS or Docker. This is just the feature of cloud backed applications.

However it is true that the best results are achievable using immutable infrastructure, but you do not need neither of these tools to achieve such. Instead you can build your own AMI (using Packer) and then use AWS CodeDeploy to deploy your application on each of the instances.

These tools are orthogonal, so you can use them, but there is no problem with using autoscaling without them.

---
Tags: autoscaling, nixos
---


# Question
Title: Is Serf an added value when a container orchestration platform like kubernetes is used?
When the Hashicorp's website was checked it seems that there is another tool, i.e. Serf. Back in the day there was another tool called `otto`, but that was deprecated at a certain moment.

After reading the use cases I wonder whether it is an added value to use `serf` when a container orchestration platform like kubernetes is used.

# Answer
Serf is gossip protocol implementation and has absolutely nothing to do with orchestration tools like k8s. Even if such protocol is used internally, then in most cases it isn't available for you applications running in given orchestrator.

So if your app or workflow depends on gossip protocol, then you will have use out of Serf, otherwise there is no point.

---

Gossip protocol is way of messaging to all nodes without:

* Centralized point of knowledge
* Single point of failure
* Using whole network capability of any of the nodes

In simple words it works like "message chains" ("If you do not send this to N people you will never find your love" or something like that).

1. One node send notification to N out of M of its fellows
2. If you receive message that you have already received, then do nothing.
3. Otherwise go to step 1.

Given such simple protocol you can calculate probability when all your nodes will receive message with 99% chance.
> 4 votes

---
Tags: monitoring
---


# Question
Title: Is it possible to use a list with 'file.exists' in Salt?
I asked a question recently regarding the most efficient and scalable way to check which files/services exist in multiple environments. Thanks to an answer I have successfully set up roles for all of my salt minions.

I am now in the process of writing my first salt state which will check that all expected files/services are present for all minions with the `apiserver` role.

I am using the `file.exists` feature, however as you can expect there are 100's of files/services I wish to check, I'm sure there must be a way of listing these files/services in a list or string? I can't find anything in the documentation under file.exists but it is possible in other file.'s

Here is the current state of my `init.sls` file:

```
# This state will check all minions identified as 'apiserver' for files and/or services which should exist

# This section checks the 'checkservices.sh' is present in /opt (used for Jenkins check jobs)

checkservices.sh:
  file.exists:
    - name: /opt/checkservices.sh

# This section checks for expected files/scripts within /opt/apiv2/

apiv2.properties:
  file.exists:
    - name: /opt/apiv2/apiv2.properties

jvm.options:
  file.exists:
    - name: /opt/apiv2/jvm.options

restart.sh:
  file.exists:
    - name: /opt/apiv2/restart.sh

status.sh:
  file.exists:
    - name: /opt/apiv2/status.sh

shutdown.sh:
  file.exists:
    - name: /opt/apiv2/shutdown.sh

start.sh:
  file.exists:
    - name: /opt/apiv2/start.sh

# This section checks for 'bootstrap.jar' in /opt/apiv2/repo/

bootstrap.jar:
  file.exists:
    - name: /opt/apiv2/repo/bootstrap.jar

```

My second question is; is my current method (above) considered bad practice or is it just an ugly/inefficient way of doing it?

# Answer
> 1 votes
Yes - there are at least two options available for managing files in the manner you describe. The first such way is to manage the entire directory using file.directory:

```
/opt/apiv2:
  file.directory:
    - user: root
    - group: root
    - dir_mode: 755
    - file_mode: 644
    - recurse:
      - user
      - group
      - mode

```

The second way can manage a manifest of several files at many paths is to use the `source_hash` feature of file.managed:

This allows you to provide a source tar file and a file containing md5sum hashes:

```
apiv2-0.7.3.tar.gz:
  file.managed:
    - name: /tmp/apiv2-0.7.3.tar.gz
    - source: salt:///apiv2/distrib/apiv2-0.7.3.tar.gz
    - source_hash: salt:///apiv2/distrib/manifest-0.7.3.hash

```

You would then create a text file on your salt server /srv/salt/apiv2/distrib/manifest-0.7.3.hash with contents similar to:

```
37b51d194a7513e45b56f6524f2d51f2    /opt/apiv2/apiv2.properties
acbd18db4cc2f85cedef654fccc4a4d8    /opt/apiv2/repo/bootstrap.jar
73feffa4b7f6bb68e44cf984c85f6e88    /opt/apiv1/apiv1.properties

```

Your *might* even be able to use templating,

```
apiv2-0.7.3.tar.gz:
  file.managed:
    - name: /tmp/apiv2-0.7.3.tar.gz
    - source: salt:///apiv2/distrib/apiv2-0.7.3.tar.gz
    - source_hash: salt:///apiv2/distrib/manifest-0.7.3.hash
    - template: jinja

```

however Salt Stack might want to push down the file each time because after the templates are rendered, the hash will have changed, so the creators might just have elected to throw an error if you try these two features together. In short, Your Mileage May VaryTM

---
Tags: configuration-management, salt, yaml
---


# Question
Title: New Kubernetes Cluster: remote error: tls: bad certificate
This is my first attempt at setting up a Kubernetes cluster in my test environment. In preperation, I created 3 instances running Fedora Atomic:

```
10.11.184.8: master/etcd
10.11.184.5: node01
10.11.184.6: node02

```

Then using contrib/ansible playbooks for Ansible, I deployed kubernetes to my instances. It completed with "0" failures for each host.

I then connect to my master and begin to check that status of it:

```
[root@kubemaster ~]# kubectl get cs
NAME                 STATUS    MESSAGE              ERROR
scheduler            Healthy   ok
controller-manager   Healthy   ok
etcd-0               Healthy   {"health": "true"}

```

However, I go to check my nodes and it returns nothing:

```
[root@kubemaster ~]# kubectl get nodes
No resources found.

```

I begin to check logs, and I find the below repeating over and over from all three of the IPs listed above:

```
http: TLS handshake error from 10.11.184.5:32788: remote error: tls: bad certificate

```

It appears that the ansible playbook did generate some certificates:

```
[root@kubemaster ~]# ll /etc/kubernetes/certs/
total 40
-r--r-----. 1 kube kube-cert 1220 Aug 15 19:11 ca.crt
-r--r-----. 1 kube kube-cert 4417 Aug 15 19:11 kubecfg.crt
-r--r-----. 1 kube kube-cert 1704 Aug 15 19:11 kubecfg.key
-rw-rw----. 1 root kube-cert 4417 Aug 15 19:11 kubelet.crt
-rw-rw----. 1 root kube-cert 1704 Aug 15 19:11 kubelet.key
-r--r-----. 1 kube kube-cert 4917 Aug 15 19:11 server.crt
-r--r-----. 1 kube kube-cert 1704 Aug 15 19:11 server.key

```

And the kube-apiserver binary is being passed these as a parameter:

```
/usr/bin/kube-apiserver --logtostderr=true --v=0 --etcd-servers=http://10.11.184.8:2379 --insecure-bind-address=127.0.0.1 --secure-port=443 --allow-privileged=true --service-cluster-ip-range=10.254.0.0/16 --admission control=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota --tls-cert-file=/etc/kubernetes/certs/server.crt --tls-private-key-file=/etc/kubernetes/certs/server.key --client-ca-file=/etc/kubernetes/certs/ca.crt --token-auth-file=/etc/kubernetes/tokens/known_tokens.csv --service-account-key-file=/etc/kubernetes/certs/server.crt --bind-address=0.0.0.0 --apiserver-count=1

```

If I view the logs on one of the nodes, I see a lot of messages like so:

```
Failed to list *v1.Node: Get https://10.11.184.8:443/api/v1/nodes?fieldSelector=metadata.name%3D10.11.184.8:443/api/v1/nodes?fieldSelector=metadata.name%3D10.11.184.5&resourceVersion=0: x509: certificate is valid for 10.254.0.1, 192.168.0.11, 172.16.63.0, 172.16.63.1, not 10.11.184.8

```

Is it likely that my certificates were not generated correctly? I am looking at this documentation. Perhaps I should attempt to manually create the certificates using openssl or easyrsa?

# Answer
From the documentation you linked, it states,

> The referenced file must contain one or more certificates authorities to use to validate client certificates presented to the API server.

This means your client's certificate is invalid because either:

1. The server doesn't trust the client's signing certificate authority
2. The client doesn't trust the server's signing certificate authority
3. The certificate's DN doesn't match the hostname

The most likely scenario is that 1. The server doesn't trust the client's signing certificate authority since the server doesn't verify DNS for the client certificate and the error indicates this is a `remote error` not on the client. **Most likely this means the client's certificate was signed on the client itself, not on the server.**

You will need to make sure to generate the certificate on the client, have the server sign it and then transfer the certificate back to the client. Otherwise, you need to add the server's CA certificate to the Client's keystore.. You can ensure you do not have a DNS/DN mismatch by setting hosts file entries.
> 3 votes

---
Tags: kubernetes
---


# Question
Title: Strange behaviour of Docker CE/EE client on Windows - timeout for certain image layers
With a private registry, I cannot pull images because certains image layers fail to download. The pattern seems to be that this happens with larger, 50MB sized layers. It shouldn't be a registry neither network problem as colleagues with other systems manage to get these images.

```
6bbedd9b76a4: Pulling fs layer
fc19d60a83f1: Download complete
de413bb911fd: Download complete
2879a7ad3144: Download complete
668604fde02e: Download complete
f257ac562635: Download complete
07486ea9391a: Download complete
c131a1091dea: Download complete
e4e87f3caf2a: Downloading
6ef05c7ca3e3: Retrying in 1 second
85b7b45e23a1: Download complete
077ff1474b65: Retrying in 1 second
f85147a0e9d7: Waiting

```

Other errors on new retries with same image:

```
2c1171c58a199d2ec9daee729d88146dfb91caba4788: local error: tls: bad record MAC

error pulling image configuration: tls: received record with version 5ea7 when expecting version 303

```

UPD. Strange enough, the very first image layer which always gets stuck before it downloads anything stucks rarely at "downloading... 987B".

UPD2. Same behaviour with Docker EE client (Docker-Client/17.03.0-ee-1)

UPD3. Filed this as a bug to the Moby project.

# Answer
This has been a Docker bug caused by jumbo Ethernet frames while using VPN which has now been fixed. Thanks Docker team!

https://github.com/moby/moby/issues/34080
> 1 votes

# Answer
You may wish to try disabling and uninstalling any antivirus software you have installed and see if it resolves the issue (I of course don't recommend this in the long term). I have seen two different instances of antivirus interrupting SSL conections on Windows 10 recently. Chrome would report a similar error to "bad record MAC" and the issue was generalized to any SSL website or connection and any browser. Unstalling or changing A/V software resolved the issue.
> 1 votes

---
Tags: docker, windows
---


# Question
Title: Docker swarm stop spin up containers at 250
**TLDR: Docker won't spin up more then 250 containers.**

I'm deploying a cluster of 3 docker services to a swarm with 2 nodes. 2 of the services need to contain 1 container (have a `replicas: 1` in the `docker-compose` file), and the third service need to have 300 containers (have a `replicas: 300` setting).

The problem is it's spin up those 3 services, the first two with 1 container each (work like they should), and the third service spin up 248 containers out of 300 (I see this when I do `docker service ls`). I try to search if there is a limit of the service or swarm but couldn't find any.

I will much appreciate any help I can get.

* If it's matter, each node with a 30GB RAM and 8 cores, and I use only 1/3 of the RAM.

# Answer
I just figure it out. The problem is not with the service or the swarm, it's with the network.

When I use `driver: overlay` the default `subnet` is `10.0.0.0/24` which result in 254 address. So I change the mask in the `subnet`, to 22, which result in 1022 address, I added:

```
ipam:
  config:
    -subnet: 10.0.0.0/22

```

And now the network section in the `docker-compose` file looks like this:

```
networks:
  web:
    driver: overlay
    ipam:
      config:
        - subnet: 10.0.0.0/22

```
> 5 votes

---
Tags: docker, docker-compose, docker-swarm
---


# Question
Title: Same Docker image, multiple configurations
I got an application server image built with Docker. However, this image contains an OpenVPN client which needs a different certificate for each client, among other minimal configuration files.

I push this image to multiple servers across the globe. Every of them communicates with each other, thats the reason to use the VPN.

How should I put the configuration for such servers? I think this is out the scope of Docker. Must I use a configuration server like Ansible or so?

# Answer
> 2 votes
One could pass environment variables when running docker, e.g.:

> Additionally, the operator can set any environment variable in the container by using one or more -e flags, even overriding those mentioned above, or already defined by the developer with a Dockerfile ENV:
>
> ```
> $ docker run -e "deep=purple" --rm ubuntu /bin/bash -c export
>
> ```

# Answer
> 2 votes
One solution would be to create a base image with OpenVPN and global configurations and child images for the certs.

The base `Dockerfile` might look like this.

```
FROM debian:latest
RUN apt-get update && apt-get -y install \
  openvpn \
  easy-rsa \
  etc

RUN <any needed configurations>

```

`docker build -t openvpn:baseimage .`

The cert `Dockerfile`.

```
FROM openvpn:baseimage
COPY certs /etc/easy-rsa/

CMD openvpn

```

`docker build -t useast:1 .`

You could push the certs to the respective nodes with some kind of management tool and `build` the child images there. The base image would live in an available registry. Once the base image is cached on each node in Docker, the builds should be quick.

There are multiple solutions to this problem depending on what's best for the given environment.

# Answer
> 0 votes
If I get it right you use the same image for each container but their "state" change regarding the location, so you need an uniq cert per container.

I suppose, if you have the need of OpenVPN, this is not a Swarm cluster. (If it was no need for openVPN), so no access to docker `config` or `secret`.

I would go for a key/value store like consul and bundle it with consul-template so your config are store to the same place and consul-template generate the related files directly in the container.

# Answer
> 0 votes
You can use sharing volumes between the host that run the container and the instance, in this case you can put the crt files in anywhere in the hosts then map it to specific folder in the container, the same for configuration you can configure the service to read the configuration file from specific path and every time you mount whatever configuration you like to that specific folder and the service will read it.

For more info: https://docs.docker.com/engine/admin/volumes/volumes/

# Answer
> 0 votes
As you are trying to manage multiple servers you should start looking into any config management tools.

You could start looking into Ansible, as it is easier to setup and manage than other CM tools like Chef and Puppet (which have their own dependent resources to manage and run) .

Ansible is agentless, SSH based config tool written on python. (But it does not require you to code in py)

You just have to learn yml syntax (Jinja2) which is pretty easy . Its just a set of instructions on how to configure the server

Now coming to your use case

1. When you say that you push the docker images to multiple server across globe (which means you have a central node which can connect to all servers). This node can behave like the Ansible master (Where you install all ansible dependencies)

If its is Deb based I have the scripts handy

```
    sudo apt-get -y install python-dev
    sudo apt-get -y install libffi-dev
    sudo apt-get -y install libssl-dev
    sudo pip install paramiko
    sudo pip install PyYAML
    sudo pip install Jinja2
    sudo pip install httplib2
    sudo pip install six
    sudo pip install markupsafe
    sudo pip install ansible

```
2. After you install ansible write a sample playbook (with just a echo command) http://docs.ansible.com/ansible/latest/playbooks\_intro.html
3. Lists all your servers in the inventory file http://docs.ansible.com/ansible/latest/intro\_inventory.html
4. Execute your playbook for testing with below command ansible-playbook -i --extra-vars "key=Value"
5. Modify your playbook to include Docker image and set env variables of your credentials. Encrypt your creds using Bcrypt or some util
6. Store your playbooks in Git or other Source control

Happy Coding in Ansible.

---
Tags: docker, deployment, configuration
---


title: How to give value in runtime for chef

text:
# Question
Title: How to give value in runtime for chef
I got stuck with a scenario where I need to provide runtime value while restarting/starting `httpd` service using Chef.

I installed SSL certs where it asks password for every reload or start. I tried giving:

```
service 'httpd' do
  supports restart: true, reload: false, status: true
  options "password"
end

```

But I don't have any luck.

Any help about how to pass this value while `httpd` restarts using Chef?

# Answer
You shouldn't. Instead you should use proper secrets management system that would provide you unlocked SSL certificate.

---

By secret management I mean tooling like k8s secret management or Vault.

You can read Medium post about secrets.
> 2 votes

---
Tags: chef, apache-httpd
---


title: Shell Scripting

text:
# Question
Title: Shell Scripting
I am trying to execute a PHP shell script on my friends mail server to show him the impact of such vulnerability. Vulnerable code but unfortunately it doesn't seem to be running.

This is the script I wrote:

```
echo shell_exec($_GET['cmd']);

```

# Answer
Please provide more information about the method and the result as Husyn asked, it may be more suited to programming SO if it is PHP related. Anyway:

* `<?php` should be present at the start of any PHP script.
* If a PHP error occurs, you might not see it without error reporting enabled.
* If the actual shell command fails or outputs warnings, you won't see it with `shell_exec` unless you add the stderr to stdout redirection `2>&` to the command, or use `exec`.
> 2 votes

---
Tags: shell-script, php
---


title: openstack instance metadata

text:
# Question
Title: 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` ?

# Answer
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'                                                |
[...]

```
> 1 votes

---
Tags: cloud, openstack
---


# Question
Title: Why is the K8s UI not available when rancher is used?
K8s has been created using rancher, but when one would like to access the UI it shows:

```
Service unavailable

```

**Methods**

*Method 1*

* rancher was deployed locally using vagrant
* k8s was deployed
* click the ui button

*Method 2*

perhaps the local firewall was causing the issue?

* rancher was deployed on digital ocean
* k8s was deployed
* service unavailable again

# Answer
> 2 votes
I've seen this happen, especially on the newest (as of now) version. Try going into the "Infrastructure stack" and look for stopped containers. Often it helps to just refresh the entire deployment (hit the button "up to date" next to the "kubernetes" stack and hit save (If I remember correctly) in the bottom to force the "refresh").

You could also try manually just restarting the kubernetes-dashboard containers.

Lastly you could use the kubectl cli to delete the dashboard pods and force them to get recreated.

Let me know how it goes! I know I had to do this fix a few times.

---
Tags: rancher, kubernetes
---


# Question
Title: Artifactory vs Git for Infrastructure Version Control / Configuration Management
I'm trying to understand the difference between managing configuration files for the purposes of simplifying automated deployment.

We have 5 environments to build. So far 2 have been built with no versioning at all. Right now we're using Artifactory to "manage" the rpm files. I've been tasked to "version control the other stuff". Right now, other stuff means a couple of properties files.

My question is, if I were to simply "version control the other stuff", I would store the properties files in Github, I'd then have Jenkins "build" then "deploy" it to Artifactory? Isn't it extremely difficult to manage infrastructure versioning without infrastructure as code?

My second question is, since our goals are to simplify automated deployment, shouldn't we be using Ansible (or puppet or chef but I like ansible). We could then store Ansible playbooks (and cloudformation templates, etc.) in Github. In this case, what binaries would there be to version?

# Answer
> 7 votes
Version Control (using say Git) and Artifact Management (using Artifactory) are complementary. Version control is useful for easily browsing the historical changes and who made them. Artifact management tools can do this but it's clunky. Also they don't offer a fine grained view of changes, as one version change might involve a large amount of changes.

When integrated with a workflow like feature branches, version control offers some real benefits around collaboration particularly for distributed teams.

Some places use just version control with no artifact management, i.e. Reddit. They deploy to 800 servers 200 times a week using just Git. This may or may not be the best solution for you.

An artifact can be many things, not just a binary. It can be a tar ball of files, an rpm, a virtual machine or a docker container. But I've not really seen artifact tools used to deploy configuration management, you could just deploy straight from Git or bundle it into a tarball or rpm.

# Answer
> 9 votes
This is a simple thumb rule one could follow

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

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

---
Tags: ansible, configuration-management, artifacts, github, infrastructure
---


# Question
Title: Does "docker run" actually SSH into the container?
If I run

```
docker run -it ubuntu bash

```

Does it actually SSH into the container, or does it use another protocol?

# Answer
No, it uses an internal "attach protocol" via the Docker daemon.
> 13 votes

---
Tags: docker, containers
---


# Question
Title: docker "Cannot mkdir: Permission denied"
I'm trying to run wordpress inside docker.

I've been following this tutorial : https://www.sitepoint.com/how-to-use-the-official-docker-wordpress-image/

But when I run this command :

```
docker run -e WORDPRESS_DB_PASSWORD=xxxxxx -d --name wordpress --link wordpressdb:mysql -p 127.0.0.1:8080:80 -v "$PWD/":/var/www/html wordpress

```

The container crashes, and in the logs I can see things like :

```
tar: ./wp-admin: Cannot mkdir: Permission denied

```

# Answer
Hm, i'll answer myself here I guess.

The problem was, I had "broken" volumes.

So, I've made a little script to "reset" docker and install wordpress. Careful it removes everything.

```
#!/bin/bash

# remove images
docker rmi $(docker images -q)
# remove containers
docker stop $(docker ps -aq)
docker rm $(docker ps -aq)
# remove volumes
docker volume rm $(docker volume ls -q)

echo "Type mysql root password : "
read mspass

docker run --name wordpressdb -e MYSQL_ROOT_PASSWORD=$mspass -e MYSQL_DATABASE=wordpress -d mysql:5.7

docker run -e WORDPRESS_DB_PASSWORD=$mspass --name wordpress --link wordpressdb:mysql -p 127.0.0.2:8080:80 -v "$PWD/":/var/www/html -d wordpress

```
> 2 votes

# Answer
Try to run such command as root or grant user and group rights to the folder with chown.

That's only what comes to my mind for now.
> 3 votes

# Answer
Perhaps information like 1) the docker host OS details (RHEL, Centos, Ubuntu, etc) 2) the mounted directory permission (ls -al) would help to debug this issue...

This could be an SELinux issue as well, so disable SELinux and try
> 1 votes

---
Tags: docker, linux
---


# Question
Title: AWS Task definition memory for Ubuntu docker image
We are using **alpine** image on AWS ecs which work fine on just 100mb memory in task definition. Now we need ubuntu image which size is more then 180mb while alpine is just 5mb.

* I want to know that we need to increase memory according to image?
* or Docker image run completely in memory or just current processes in memory what if I specify memory less then docker image size in task definition?

AWS recommend 300 to 500mb but in development I want to save memory.

Thanks

# Answer
There are two important parameters that you can use wisely to deal with AWS ECS task definition.

memory:

> The hard limit (in MiB) of memory to present to the container. If your container attempts to exceed the memory specified here, the container is killed.

memoryReservation:

> Docker attempts to keep the container memory to this soft limit; however, your container can consume more memory when it needs to.

I recommend you to go with **memoryReservation**. So your task definition will look like this.

```
{
  "family": "my-alpine",
  "networkMode": "bridge",
  "containerDefinitions": [
    {
      "image": "alpine:latest",
      "name": "my-alpine",
      "memoryReservation": 100,
      ...
      ...
    }
  ]
}

```
> 2 votes

---
Tags: docker, amazon-ecs
---


# Question
Title: How to create named volumes in Kubernetes?
Several named volumes have been created in docker-compose. How to create these in Kubernetes?

How to transform the following `named volume` example defined in docker-compose to kubernetes format

```
version: "3"
services:
  x:
    image: z
    volumes:
      - a:/path/inside/container
  y:
    image: c
    volumes:
      - a:/path/inside/container
volumes:
  a:

```

# Answer
k8s have documentation page about volumes and their types https://kubernetes.io/docs/concepts/storage/volumes/

So in short you need to define `spec.volumes` and `spec.containers[].volumeMounts` like:

```
apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: gcr.io/google_containers/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {}

```
> 5 votes

---
Tags: kubernetes
---


# Question
Title: What are the responsibilities of a project manager in a DevOps project?
A project in DevOps should logically change the management mechanisms. What are the responsibilities of a project manager in a DevOps project ?

**Note**: A project DevOps of what I understand is a project that has a beginning and an end, it is a temporary effort to create a product or a unique result and that uses the concept DevOps to produce a software.

# Answer
Truth would be that should not happen in a DevOps environment . Your "project" will probably use Agile concepts, but there's nothing in DevOps telling how a project has to be run because DevOps is *product centric* (more details on the blog post and with search on this term).

"DevOps" is about breaking silos and have a team composed of developers, architects, ops, exploitation peoples who handle a software on its lifetime, that is antagonistic with the waterfall project approach.

To quote here Jez Humble:

> Products not projects

So your answer would be : There's not responsibilities for a project manager on a DevOps product because the main idea behind devops is to have a team handling the product on long term and not on a planned project time only.
> 5 votes

---
Tags: project-management
---


title: Managing branched DLLs in nuget

text:
# Question
Title: Managing branched DLLs in nuget
Our company has a product line and most development happens on the trunk. We had 3 releases slotted back to back with the last one being an update to the first one. the first one is in 3rd party testing with the second in in house testing. The development of the third is completed but due to the amount of breaking changes was done on a separate branch of the first two. This code needs to be placed on nugget to prevent any checked in code from referencing the local developers computer. I don't want to make a nugget package for this branch as it will just die/get pruned when it goes into internal testing. I also don't want to override the current package as internal testing may require changes to be made, causing confusion in version numbers.

What is the best way to manage/publish branched DLLs using NuGet? should NuGet even be used?

# Answer
> 1 votes
So what is happening is that the changed code just sat until internal testing was done (never a good thing as this is how code get stale quickly). Once internal testing was ready, the code was then merged into the trunk causing it to be published into nugget under the trunk's feed. Some business politics ensued and we finally got to a real single code base mindset from the product owner's perspective (which was the issue that got us into this situation). Moving forward I don't anticipate this to arise.

Code can be branched out. However, only code in the trunk will go to our internal nugget feed or our build/deployment processes.

---
Tags: nuget
---