Amazon Linux 2 AMI – SFTP access

All actions will also be relevant for CentOS systems. In this example, a user will be added for access via SFTP using an SSH key to the web directory under Apache management. There is a default for Apache group “apache“, if necessary, replace the desired one.

All sites are on the dir:

/var/www/html

 

Add the user sftpuser (already in the existing group):

useradd -g apache -d /var/www/html -s /sbin/nologin sftpuser

Let’s give the group permissions to write since we will change the owner:

chmod -R g+w /var/www/html/*

Change the ownership of files:

chown -R sftpuser:apache /var/www/html/*

 

The “html” directory itself should not belong to the “sftpuser” user

 

Create a directory for public keys and give it the necessary permissions:

mkdir /var/www/html/.ssh
chmod 700 /var/www/html/.ssh

In this directory, create two files and place the public SSH key in them:

authorized_keys
id_rsa.pub

Set the necessary permissions to the file:

chmod 644 /var/www/html/.ssh/*

Making the user sftpuser owner:

chown -R sftpuser:apache /var/www/html/.ssh

 

Open the SSH server configuration file:

vim /etc/ssh/sshd_config

Replace the string:

Subsystem sftp	/usr/libexec/openssh/sftp-server

To the following:

Subsystem sftp	internal-sftp

And add the following block to the end of the file:

Match Group apache
X11Forwarding no
AllowTcpForwarding no
ChrootDirectory %h
ForceCommand internal-sftp

 

Reboot the SSH service:

service restart sshd

 

We connect via SFTP client by specifying the username “sftpuser” and the path to the private SSH key, on the basis of which the public one was generated, the port for connection is SSH port (by default 22).

FIX ERROR – Terraform: Instance Profile already exists

When executed, execute “terraform apply” during execution when creating the “IAM Profile“, it ends with the following error:

	* aws_iam_instance_profile.ecs_profile: 1 error occurred:
	* aws_iam_instance_profile.ecs_profile: Error creating IAM instance profile stg-artem-service-profile: EntityAlreadyExists: Instance Profile stg-artem-service-profile already exists.
	status code: 409, request id: a77fec43-7ad2-11e9-9e4e-7744dbc7b890

 

Solution:

Use AWS Cli to find the IAM Profile and delete it.

aws --profile artem iam list-instance-profiles

See the list of existing IAM Profiles:

{
    "InstanceProfiles": [
        {
            "Path": "/",
            "InstanceProfileName": "stg-artem-service-profile",
            "InstanceProfileId": "YYYYYYYYYYYYYYYYYYYYY",
            "Arn": "arn:aws:iam::XXXXXXXXXXXX:instance-profile/stg-artem-service-profile",
            "CreateDate": "2019-05-17T14:06:27Z",
            "Roles": []
        }
    ]
}

Remove unnecessary IAM Profile:

aws iam delete-instance-profile --instance-profile-name stg-artem-service-profile

FIX ERROR – Docker: Err http://http.debian.net jessie-backports/main amd64 Packages

When I try to update the list of repositories in the Docker image based on “node: 8“, the following error appears:

Err http://http.debian.net jessie-backports/main amd64 Packages

Solution

Dockerfile:
FROM node:8

RUN echo "deb [check-valid-until=no] http://cdn-fastly.deb.debian.org/debian jessie main" > /etc/apt/sources.list.d/jessie.list && \
    echo "deb [check-valid-until=no] http://archive.debian.org/debian jessie-backports main" > /etc/apt/sources.list.d/jessie-backports.list && \
    sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list && \
    apt-get -o Acquire::Check-Valid-Until=false update

Fastlane – TestFlight: Invalid App Store Icon

При заливке в TestFlight Fastlane выдает следующее:

[Transporter Error Output]: ERROR ITMS-90717: "Invalid App Store Icon. The App Store Icon in the asset catalog in 'your_app.app' can't be transparent nor contain an alpha channel."
Transporter transfer failed.

ERROR ITMS-90717: "Invalid App Store Icon. The App Store Icon in the asset catalog in 'your_app.app' can't be transparent nor contain an alpha channel."
[iTMSTransporter]

DBG-X: parameter ErrorCode = 1102

[iTMSTransporter]

DBG-X: parameter ErrorMessage = ERROR ITMS-90717: "Invalid App Store Icon. The App Store Icon in the asset catalog in 'your_app.app' can't be transparent nor contain an alpha channel.

[iTMSTransporter] (1102)

[iTMSTransporter]

ERROR: ERROR ITMS-90717: "Invalid App Store Icon. The App Store Icon in the asset catalog in 'your_app.app' can't be transparent nor contain an alpha channel."

[iTMSTransporter]

DBG-X: The error code is: 1102

[iTMSTransporter]

INFO: Done performing authentication.

 

Устанавливаем imagemagick:

brew install imagemagick

Удалим альфа канал с иконок приложения:

find ./ios/your_app/Images.xcassets/AppIcon.appiconset/ -name "*.png" -exec convert "{}" -alpha off "{}" \;

Строка для Jenkins‘а с экранированием:

sh "find ./ios/your_app/Images.xcassets/AppIcon.appiconset/ -name \"*.png\" -exec convert \"{}\" -alpha off \"{}\" \\;"

Jenkins – Perfomance testing (JMeter + Ant + Slack)

On the server with Jenkins download JMeter

Also need JMeterPluginsCMD

Create a directory for storage:

mkdir -p /var/lib/jmeter

Download and unzip the contents of two archives to this directory.

So that the structure is as follows:

root@jenkins:~# ll /var/lib/jmeter/
total 64K
drwxr-xr-x  8 jenkins jenkins 4.0K Apr 24 15:39 .
drwxr-xr-x 37 root    root    4.0K Mar 22 10:29 ..
drwxr-xr-x  5 jenkins jenkins 4.0K Apr 24 17:47 bin
drwxr-xr-x  5 jenkins jenkins 4.0K Mar 10 08:41 docs
drwxr-xr-x  2 jenkins jenkins 4.0K Mar 10 08:43 extras
drwxr-xr-x  4 jenkins jenkins 4.0K Apr 24 17:47 lib
-rw-r--r--  1 jenkins jenkins  15K Mar 10 10:08 LICENSE
drwxr-xr-x  4 jenkins jenkins 4.0K Mar 10 10:08 licenses
-rw-r--r--  1 jenkins jenkins  172 Mar 10 10:08 NOTICE
drwxr-xr-x  6 jenkins jenkins 4.0K Mar 10 09:58 printable_docs
-rw-r--r--  1 jenkins jenkins  10K Mar 10 10:08 README.md

Continue reading “Jenkins – Perfomance testing (JMeter + Ant + Slack)”

Kubernetes – Ingress few backends

Configuration example Kubernetes Ingress with the choice of backend based on the value of the argument “proxy“. And the default backend, if the value of the argument “proxy” is different from “1” and “2“, or is missing.

manifest.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: artem-test-proxy-0-app
  namespace: staging
  labels:
    app: artem-test-proxy-0-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: artem-test-proxy-0-app
  strategy:
    type: RollingUpdate
  progressDeadlineSeconds: 300
  minReadySeconds: 60
  template:
    metadata:
      labels:
        app: artem-test-proxy-0-app
    spec:
      containers:
      - name: artem-test-proxy-0
        image: dockersamples/static-site
        env:
        - name: AUTHOR
          value: Default
        ports:
        - containerPort: 80
      nodeSelector:
        nodegroup: staging
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: artem-test-proxy-1-app
  namespace: staging
  labels:
    app: artem-test-proxy-1-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: artem-test-proxy-1-app
  strategy:
    type: RollingUpdate
  progressDeadlineSeconds: 300
  minReadySeconds: 60
  template:
    metadata:
      labels:
        app: artem-test-proxy-1-app
    spec:
      containers:
      - name: artem-test-proxy-1
        image: dockersamples/static-site
        env:
        - name: AUTHOR
          value: Proxy=1
        ports:
        - containerPort: 80
      nodeSelector:
        nodegroup: staging
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: artem-test-proxy-2-app
  namespace: staging
  labels:
    app: artem-test-proxy-2-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: artem-test-proxy-2-app
  strategy:
    type: RollingUpdate
  progressDeadlineSeconds: 300
  minReadySeconds: 60
  template:
    metadata:
      labels:
        app: artem-test-proxy-2-app
    spec:
      containers:
      - name: artem-test-proxy-2
        image: dockersamples/static-site
        env:
        - name: AUTHOR
          value: Proxy=2
        ports:
        - containerPort: 80
      nodeSelector:
        nodegroup: staging

---

apiVersion: v1
kind: Service
metadata:
  name: artem-test-proxy-0-svc
  namespace: staging
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: artem-test-proxy-0-app
---
apiVersion: v1
kind: Service
metadata:
  name: artem-test-proxy-1-svc
  namespace: staging
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: artem-test-proxy-1-app
---
apiVersion: v1
kind: Service
metadata:
  name: artem-test-proxy-2-svc
  namespace: staging
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: artem-test-proxy-2-app

---

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: artem-test-proxy-ing
  namespace: staging
  annotations:
    kubernetes.io/ingress.class: ingress-staging
    certmanager.k8s.io/cluster-issuer: letsencrypt-prod
    certmanager.k8s.io/acme-challenge-type: dns01
    certmanager.k8s.io/acme-dns01-provider: dns
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/configuration-snippet: |
                    if ($arg_proxy = 1) {
                      proxy_pass http://artem-test-proxy-1-svc.staging.svc.cluster.local;
                    }
                    if ($arg_proxy = 2) {
                      proxy_pass http://artem-test-proxy-2-svc.staging.svc.cluster.local;
                    }
spec:
  tls:
  - hosts:
    - artem.services
    secretName: artem.services-secret-tls
  rules:
  - host: artem.services
    http:
      paths:
      - path: /
        backend:
          serviceName: artem-test-proxy-0-svc
          servicePort: 80

Jenkins – Deploy in Docker Swarm using Stack Deploy

An example deployment in Docker Swarm from Jenkins using stack deploy.

Jenkinsfile:

pipeline {
    agent any
    environment {
        PROJECT_NAME = 'artem-api'
        SLACK_CHANNEL = 'maintenance-artem-api'
        SWARM_MANAGER_IP = '8.8.8.8'
        SWARM_WORKER_1_IP = '1.1.1.1'
        SWARM_WORKER_2_IP = '2.2.2.2'
        TLS_CA = '/var/lib/jenkins/TLS/swarm/ca.pem'
        TLS_CERT = '/var/lib/jenkins/TLS/swarm/cert.pem'
        TLS_KEY = '/var/lib/jenkins/TLS/swarm/key.pem'
        ECR = '111111111111.dkr.ecr.us-west-1.amazonaws.com/artem'
        PROFILE = 'artem'
    }
    stages {
        stage ('Auth to AWS ECR.') {
            steps {
                sh "echo 'Auth to image repo'"
                sh "eval \$(aws ecr get-login --profile ${PROFILE} --no-include-email) &>/dev/null"
            }
        }
        stage ('Build image'){
            steps{
                script{
                    withDockerServer([uri:'tcp://127.0.0.1:4243']) {
                        sh "cp ./.jenkins/Dockerfile ./Dockerfile"
                        echo "Debug: Building  with ${ECR}:${PROJECT_NAME}-${JOB_BASE_NAME}-${BUILD_NUMBER}"
                        def image = docker.build ("${ECR}:${PROJECT_NAME}-${JOB_BASE_NAME}-${BUILD_NUMBER}")
                        image.push ()
                        echo "Debug: After push to registry"
                    }
                }
            }
        }
        stage ('Update API on Staging') {
            when { branch 'staging' }
            steps {
                sh 'envsubst < ".jenkins/Staging.yml" > "Staging.yml"'
                sh "ssh ubuntu@${SWARM_WORKER_1_IP} 'sudo docker pull ${ECR}:${PROJECT_NAME}-${JOB_BASE_NAME}-${BUILD_NUMBER}'"
                sh "ssh ubuntu@${SWARM_WORKER_2_IP} 'sudo docker pull ${ECR}:${PROJECT_NAME}-${JOB_BASE_NAME}-${BUILD_NUMBER}'"
                sh "docker -H tcp://${SWARM_MANAGER_IP}:2376 --tlsverify --tlscacert=${TLS_CA} --tlscert=${TLS_CERT} --tlskey=${TLS_KEY} stack deploy --compose-file Staging.yml artem-api"
            }
        }
        stage ('Update API on Production') {
            when { branch 'production' }
            steps {
                sh 'envsubst < ".jenkins/Production.yml" > "Production.yml"'
                sh "ssh ubuntu@${SWARM_WORKER_1_IP} 'sudo docker pull ${ECR}:${PROJECT_NAME}-${JOB_BASE_NAME}-${BUILD_NUMBER}'"
                sh "ssh ubuntu@${SWARM_WORKER_2_IP} 'sudo docker pull ${ECR}:${PROJECT_NAME}-${JOB_BASE_NAME}-${BUILD_NUMBER}'"
                sh "docker -H tcp://${SWARM_MANAGER_IP}:2376 --tlsverify --tlscacert=${TLS_CA} --tlscert=${TLS_CERT} --tlskey=${TLS_KEY} stack deploy --compose-file Production.yml artem-api"
            }
        }
    }
    post {
        success {
            slackSend channel: "${SLACK_CHANNEL}", color: 'good', message: "Job: ${JOB_NAME}${BUILD_NUMBER} build was successful."
        }
        failure {
            slackSend channel: "${SLACK_CHANNEL}", color: 'danger', message: "Job: ${JOB_NAME}${BUILD_NUMBER} was finished with some error. It may occurs because of the build was rollbacked by docker swarm, or because of other error (watch the Jenkins Console Output): ${JOB_URL}${BUILD_ID}/consoleFull"
        }
        unstable {
            slackSend channel: "${SLACK_CHANNEL}", color: 'warning', message: "Job: ${JOB_NAME}${BUILD_NUMBER} was finished with some error. Please watch the Jenkins Console Output: ${JOB_URL}${BUILD_ID}/console."
        }
    }
}

Continue reading “Jenkins – Deploy in Docker Swarm using Stack Deploy”