Elastic Bean Stalk - Failed to add user - amazon-elastic-beanstalk

I'm trying to add celery service to elastic bean stalk environment. So I decided to create first user and group "celery". I follow instructions from page http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html#linux-users, and I created config:
groups:
celery:
gid: "101"
users:
celery:
groups:
- celery
uid: "1501"
homeDir: "/opt/python/celery"
But during deploy, I get error:
[2017-02-10T08:59:23.899Z] INFO [16595] - [Application update app-43a4-170210_095832#474/AppDeployStage0/EbExtensionPreBuild/Infra-EmbeddedPreBuild] : Activity execution failed, because: Failed to add user celery (ElasticBeanstalk::ExternalInvocationError)
I also was modifing homeDir, and uid, and login, and gruop id, but it doesn't help. How to fix it? Or how to debug useradding by elastic bean stalk?

The workaround by 404pio offers a solution, but the ignoreErrors set to true can hide surprise errors.
I commented on that answer, but formatting is limited and gets hard to understand. Here is a way to improve on error cases:
groups:
celery:
gid: "101"
commands:
command 00_add_user_celery:
test: test ! "`id -u celery 2> /dev/null`"
command: useradd -d /opt/python/celery -g celery -u 1501 celery
ignoreErrors: false
ignoreErrors: false is the default and could also be omitted.

Workaround with commands sections:
groups:
celery:
gid: "101"
commands:
command 00_add_user_celery:
command: useradd -d /opt/python/celery -g celery -u 1501 celery
ignoreErrors: true

Related

Use kubernetes with helm and provide my predefined user and password with bitnami correctly

I am using kubernetes with helm 3.
I need to create a kubernetes pod with sql - creating:
database name: my_database
user: root
password:12345
port: 3306
The steps:
creating chart by:
helm create test
after the chart is created, change the Chart.yaml file in test folder, by adding dependencies section.
apiVersion: v2
name: test3
description: A Helm chart for Kubernetes
version: 0.1.0
appVersion: "1.16.0"
dependencies:
name: mysql
version: 8.8.23 repository: "https://charts.bitnami.com/bitnami"
run:
helm dependencies build test
After that there is a compressed file tgz.
So I extracted it and there is tar file - I extracted it too, and leave only the final extracted folder.
I presume this isn't the best approach of changing parameter in yaml for bitnami,
and using also the security.yaml - I would like knowing that better approach too.
I need to change the user + password, and link to database,
so I changed the values.yaml directly (any better approach?), for values: auth:rootPassword and auth:my_database.
the another following steps:
helm build dependencies test
helm install test --namespace test --create-namespace
after that there are two pods created.
I could check it by:
kubectl get pods -n test
and I see two pods running (maybe replication).
one of the pod: test-mysql-0 (the other is with random parse).
run:
kubectl exec --stdin --tty test-mysql-0 --namespace test-mysql -- /bin/sh
did enter the pod.
run:
mysql -rroot -p12345;
and then:
show databases;
That did showing all the database, including seeing the created database: my_database, successfully.
When I tried openning the mysql database from 'mysql workbench', and test (same user: root, and password, and port: 3306, and localhost), I couldn't run test (test connection button in database properties returns: 'failed to connect to database').
Why cannot I run properly 'mysql workbench', while in the pad itself - without any particular problem?
Is there any better approach than extrating the tgz file as I described above, and can I pass in better way (some secured yaml) the user+password?
(Right now is only the root password)
Thanks.
It sounds like you're trying to set the parameters in the dependent chart (please correct me if I'm wrong)
If this is right, all you need to do is add another section in your chart's values.yaml
name-of-dependency:
user-name: ABC
password: abcdef
the "name-of-dependency" is specified in your Chart.yaml file when you declare your chart. For example, here's my redis dependency from one of my own charts
dependencies:
- name: redis
repository: https://charts.bitnami.com/bitnami/
version: x.x.x
Then when I install the chart, I can override the redis chart's settings by doing this in my own chart's values.yaml
redis:
architecture: standalone
auth:
password: "secret-password-here"

Can't connect to local MySQL server through socket because Access denied

I am trying to get a coverage report in GitHub Actions
but when I run the pipeline I gives me this error:
Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock
Then I search around add added the sudo mysql start service and now I get this error, but I don't know were or have to write mit -root -password and the -host?
Access denied for user 'root'#'localhost' (using password: YES)")
how do I do that?
name: Django CI
on:
push:
branches: [ unittests ]
paths-ignore: '**/SkoleProtocol/attendanceCode/tests/test_selenium.py'
pull_request:
branches: [ unittests ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
max-parallel: 4
matrix:
python-version: [3.7, 3.8, 3.9]
steps:
- uses: actions/checkout#v2
- name: Set up Python 3.7
uses: actions/setup-python#v2
with:
python-version: 3.7
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Create test database
run: |
sudo service mysql start
- name: Coverage report
run: |
pip install coverage
coverage run manage.py test
coverage report
- name: Lint with flake8
run: |
pip install flake8
flake8 ./attendanceCode --exit-zero # Exit with status code "0" even if there are errors.
- name: Django Tests
run: |
python3 manage.py test
Two things that stand out.
Do you happen to have the credentials in an env file else where?
- name: Create test database
run: |
sudo service mysql start
You just happen to start the service rather than creating the database.
Try:
sudo /etc/init.d/mysql start // To start the service
mysql -uroot -proot -e "CREATE DATABASE __dbname__;"

How can I use Ansible when I only have read-only access?

I am using Ansible to automate some network troubleshooting tasks, but when I try to ping all my devices as a sanity check I get the following error:
"msg": "Authentication or permission failure. In some cases, you may have been able to authenticate and did not have permissions on the remote directory. Consider changing the remote temp path in ansible.cfg to a path rooted in \"/tmp\".
When I run the command in Ansible verbose mode, right before this error I get the following output:
<10.25.100.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "echo Cmd exec error./.ansible/tmp/ansible-tmp-1500330345.12-194265391907358" && echo ansible-tmp-1500330345.12-194265391907358="echo Cmd exec error./.ansible/tmp/ansible-tmp-1500330345.12-194265391907358" ) && sleep 0'
I am an intern and thus only have read-only access to all devices; therefore, I believe the error is occurring because of the mkdir command. My two questions are thus:
1) Is there anyway to configure Ansible to not create any temp files on the devices?
2) Is there some other factor that may be causing this error that I might have missed?
I have tried searching through the Ansible documentation for any relevant configurations, but I do not have much experience working with Ansible so I have been unable to find anything.
The question does not make sense in a broader context. Ansible is a tool for server configuration automation. Without write access you can't configure anything on the target machine, so there is no use case for Ansible.
In a narrower context, although you did not post any code, you seem to be trying to ping the target server. Ansible ping module is not an ICMP ping. Instead, it is a component which connects to the target server, transfers Python scripts and runs them. The scripts produce a response which means the target system meets minimal requirements to run Ansible modules.
However you seem to want to run a regular ping command using Ansible command module on your control machine and check the status:
- hosts: localhost
vars:
target_host: 192.168.1.1
tasks:
- command: ping {{ target_host }}
You might want to play with failed_when, ignore_errors, or changed_when parameters. See Error handling in playbook.
Note, that I suggested running the whole play on localhost, because in your configuration, it doesn't make sense to configure the target machines to which you have limited access rights in the inventory.
Additionally:
Is there anyway to configure Ansible to not create any temp files on the devices?
Yes. Running commands through raw module will not create temporary files.
As you seem to have an SSH access, you can use it to run a command and check its result:
- hosts: 192.168.1.1
tasks:
- raw: echo Hello World
register: echo
- debug:
var: echo.stdout
If someone have multiple nodes and sudo permission, and you want to bypass Read Only restriction, try to use raw module, to remount disk, on remoute node with raed/write option, it was helful for me.
Playbook example:
---
- hosts: bs
gather_facts: no
pre_tasks:
- name: read/write
raw: ansible bs -m raw -a "mount -o remount,rw /" -b --vault-password-file=vault.txt
delegate_to: localhost
tasks:
- name: dns
raw: systemctl restart dnsmasq
- name: read only
raw: mount -o remount,ro /

Can't connect to db docker container

currently working on moving our application to start using docker. It's a typical app with backend and frontend. I don't have any troubles with front, while still can't launch back.
I have Docker file for backend:
FROM williamyeh/java8
RUN apt-get -y update && apt-get install -y maven
WORKDIR /explorerbackend
ADD settings.xml /root/.m2/settings.xml
ADD pom.xml /explorerbackend
ADD src /explorerbackend/src
RUN ["mvn", "clean", "install"]
ADD target/explorer-backend-1.0.jar /explorerbackend/app.jar
RUN sh -c 'touch /explorerbackend/app.jar'
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /explorerbackend/app.jar" ]
and Docker file for mysql:
FROM mysql
ADD createDB.sql /docker-entrypoint-initdb.d
The reason i'm using a separate Docker file for mysql instead of just using image in docker-compose is necessity to create 2 databases on start (otherwise backend will not launch)
createDB.sql file looks as:
CREATE DATABASE IE;
CREATE DATABASE IE_test;
Now i have docker-compose.yml file which is supposed to start 2 containers and make backend connect to database:
version: "3.0"
services:
database:
environment:
MYSQL_ROOT_PASSWORD: root
build:
context: *PATH_TO_DIR_WITH_DOCKERFILE*
dockerfile: Dockerfile
ports:
- 3306:3306
volumes:
- db_data:/var/lib/mysql
backend:
build:
context: *PATH_TO_DIR_WITH_DOCKERFILE*
dockerfile: Dockerfile
ports:
- 3000:3000
depends_on:
- database
volumes:
db_data:
When I run the command docker-compose up database container is up and running while backend is failing:
backend_1 | java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.
However I'm able to log in to database container and I do see databases created:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| IE |
| IE_test |
| mysql |
| performance_schema |
| sys |
+--------------------+
6 rows in set (0.00 sec)
The only reason I see might be related to yml property file of backend:
app:
data-base:
name: IE
link: database
port: 3306
.................
From the frontend container I'm able to ping database (but am I allowed to put into property file just link:database):
root#897b187f9042:/frontend# ping database
PING database (172.19.0.2): 56 data bytes
64 bytes from 172.19.0.2: icmp_seq=0 ttl=64 time=0.086 ms
64 bytes from 172.19.0.2: icmp_seq=1 ttl=64 time=0.088 ms
So, I assume it's pingable from backend container as well, but why it's not able to connect to db server?
MySQL takes a few seconds to start-up. In-order to confirm this is a race-condition, try the following:
$ docker-compose up -d database && sleep 5 && docker-compose up
When/if this confirms the race-condition, you can alleviate that with a HEALTHCHECK on your database image.
See: https://github.com/docker-library/healthcheck/tree/master/mysql
Script from above link:
#!/bin/bash
set -eo pipefail
if [ "$MYSQL_RANDOM_ROOT_PASSWORD" ] && [ -z "$MYSQL_USER" ] && [ -z "$MYSQL_PASSWORD" ]; then
# there's no way we can guess what the random MySQL password was
echo >&2 'healthcheck error: cannot determine random root password (and MYSQL_USER and MYSQL_PASSWORD were not set)'
exit 0
fi
host="$(hostname --ip-address || echo '127.0.0.1')"
user="${MYSQL_USER:-root}"
export MYSQL_PWD="${MYSQL_PASSWORD:-$MYSQL_ROOT_PASSWORD}"
args=(
# force mysql to not use the local "mysqld.sock" (test "external" connectibility)
-h"$host"
-u"$user"
--silent
)
if select="$(echo 'SELECT 1' | mysql "${args[#]}")" && [ "$select" = '1' ]; then
exit 0
fi
exit 1
Eventually, we found the problem which is a kind of oversight.
The root cause was backend dockerfile:
FROM williamyeh/java8
RUN apt-get -y update && apt-get install -y maven
WORKDIR /explorerbackend
ADD settings.xml /root/.m2/settings.xml
ADD pom.xml /explorerbackend
ADD src /explorerbackend/src
RUN ["mvn", "clean", "install"]
ADD target/explorer-backend-1.0.jar /explorerbackend/app.jar
RUN sh -c 'touch /explorerbackend/app.jar'
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /explorerbackend/app.jar" ]
The idea is pretty simple:
1. Take java image
2. install maven
3. copy src folder of my project from host
4. install with maven in container
5. move jar to workdir inside container
6. launch it
However, option 5. doesn't look correct, as instead of copying jar file what was just created by maven inside container i was copying it from my host.
Issue was resolved simply replacing
ADD target/explorer-backend-1.0.jar /explorerbackend/app.jar
with
RUN cp /explorerbackend/target/explorer-backend-1.0.jar /explorerbackend/app.jar
Thanks Rawcode for looking into it!

Run statsd as a daemon on EC2 instances programatically

EDIT: My goal is to be able to emit metrics from my spring-boot application and have them sent to a Graphite server. For that I am trying to set up statsd. If you can suggest a cleaner approach, that would be better.
I have a Beanstalk application which requires statsd to run as a background process. I was able to specify commands and packages through ebextensions config file as follows:
packages:
yum:
git: []
commands:
01_nodejs_install:
command: sudo yum -y install nodejs npm --enablerepo=epel
ignoreErrors: true
02_mkdir_statsd:
command: mkdir /home/ec2-user/statsd
03_fetch_statsd:
command: git clone https://github.com/etsy/statsd.git /home/ec2-user/statsd
ignoreErrors: true
04_run_statsd:
command: node stats.js exampleConfig.js
cwd: /home/ec2-user/statsd
When I try to deploy the application to a new environment, the EC2 node never comes up fully. I logged in to check what might be going on and noticed in /var/log/cfn-init.log that 01_nodejs_install, 02_mkdir_statsd and 03_fetch_statsd were executed successfully. So I guess the system was stuck on the fourth command (04_run_statsd).
2016-05-24 01:25:09,769 [INFO] Yum installed [u'git']
2016-05-24 01:25:37,751 [INFO] Command 01_nodejs_install succeeded
2016-05-24 01:25:37,755 [INFO] Command 02_mkdir_statsd succeeded
2016-05-24 01:25:38,700 [INFO] Command 03_fetch_statsd succeeded
cfn-init.log (END)
I need help with the following:
If there is a better way to install and run statsd while instantiating an environment, I would appreciate if you could provide details on that approach. This current scheme seems hacky.
If this is the approach I need to stick with, how can I run the fourth command so that statsd can be run as a background process?
Tried a few things and found that the following ebextensions configs work:
packages:
yum:
git: []
commands:
01_nodejs_install:
command: sudo yum -y install nodejs npm --enablerepo=epel
ignoreErrors: true
02_mkdir_statsd:
command: mkdir /home/ec2-user/statsd
03_fetch_statsd:
command: git clone https://github.com/etsy/statsd.git /home/ec2-user/statsd
ignoreErrors: true
04_change_config:
command: cat exampleConfig.js | sed 's/2003/<graphite server port>/g' | sed 's/graphite.example.com/my.graphite.server.hostname/g' > config.js
cwd: /home/ec2-user/statsd
05_run_statsd:
command: setsid node stats.js config.js >/dev/null 2>&1 < /dev/null &
cwd: /home/ec2-user/statsd
Note that I added another command (04_change_config) so that I may configure my own Graphite server and port in statsd configs. This change is not needed to address the original question, though.
The actual run command uses setsid to run the command as a daemon.