Quantcast
Channel: linux-notes.org
Viewing all 152 articles
Browse latest View live

Утилита pv —прогресс bar для консольных утилит в Unix/Linux

$
0
0

Утилита pv — прогресс bar для консольных утилит в Unix/Linux

pv — это утилита которая имеет сокращение от pipeviewer и позволяет пользователю видеть прогресс выполнение той или иной команды по конвейеру и предоставляя информацию (прошедшее время, процент завершения (с индикатором выполнения), текущую пропускную способность, общий объем данных и ETA) — это просмоторщик пайпов.

Установка pv в Debian/Ubuntu

Установка pv утилиты, очень простая, выполняем:

# aptitude install pv

или

# apt-get install pv

Установка pv в CentOS/Fedora/RedHat

Для начала, подключаем репозиторий EPEL:

Включить EPEL репозиторий

Установка pv утилиты, очень простая, выполняем:

# yum install pv

Установка pv в FreeBSD

Установка pv утилиты, очень простая, выполняем:

# cd /usr/ports/sysutils/pv/
# make install clean

Или:

# pkg_add -r pv

Установка pv в Mac OS X

Устанавливаем homebrew: Установка homebrew на Mac OS X после чего, выполняем:

$ brew install pv

Установка pv в OpenSolaris

Если Вы пользователь OpenSolaris:

$ pfexec pkg install pv

Установка pv для других Unix/Linux

Если не имеется пакета для установки, то переходим на официальную страницу pv, загружаем архив и выполняем ряд действий:

$ tar -zxf pv-version.tar.gz
$ cd pv-version
$ ./configure && sudo make install

Опции для утилиты pv

pv принимает множество опций и сейчас я предоставлю их.

Коммутаторы (Display Switches)

Если не указаны опции для вывода, pv ведет себя так, как если бы вы задали «-p», «-t», «-e», «-r» и «-b» (т. е. все включено). В противном случае будут показаны только те типы вывода, которые явно включены:

  • -p, —progress — Включает индикатор выполнения. Если стандартный ввод не является файлом и не задан размер (с модификатором «-s»), индикатор выполнения не может отобразить корректно данные, насколько близок к завершению передачи, поэтому он просто перемещается влево и вправо, чтобы показать что данные перемещаются.
  • -t, —timer — Включить таймер. Это покажет общее время, в течение которого pv работает.
  • -e, —eta — Включить таймер ETA. Утилита попытается угадать, как долго до завершения, исходя из предыдущих скоростей передачи и общего размера данных. Этот параметр не будет иметь эффекта, если общий размер данных не может быть определен.
  • -r, —rate — Включите счетчик скорости. Это покажет текущую скорость передачи данных.
  • -b, —bytes — Включите счетчик для общего отображения байт. На нем отобразится общий объем переданных данных.
  • -n, —numeric — Цифровой выход. Вместо того, чтобы визуально показывать прогресс, pv даст целочисленный процент, по одной на строку, по стандартной ошибке, подходящий для пайпа (через свернутое перенаправление) в диалоговом окне (dialog). Обратите внимание, что опция «-f» не требуется, если используется «-n» опция.
  • -q, —quiet — Запретить вывод. Полезно, если опция «-L» используется сама по себе, чтобы просто ограничить скорость передачи в пайпе.

Модификаторы вывода

  • -W, —wait — Ждать, пока первый байт не будет перенесен, прежде чем показывать какую-либо информацию о ходе или вычислять любые ETA. Полезно, если программа к которой вы подключаетесь, требует дополнительной информации до ее запуска, например, для передачи данных в gpg или mcrypt, которые требуют кодовой фразы, прежде чем данные могут быть обработаны.
  • -s SIZE, —size SIZE — Предположим, что общий объем передаваемых данных — это SIZE байт при вычислении процентов и ETA. Те же суффиксы «k», «m» и т. Д. Могут использоваться с «-L».
  • -l, —line-mode — Вместо подсчета байтов, подсчитываеться строки (символы новой строки). Полоса выполнения будет двигаться только при обнаружении новой строки, а значение, переданное в параметр «-s», будет интерпретироваться для счета строки.
  • -i SEC, —interval SEC — Ждать SEC секунд между обновлениями. Значение по умолчанию — обновлять каждую секунду. Обратите внимание, что это может быть десятичное число, такое как 0,1.
  • -w WIDTH, —width WIDTH — Предположим, что терминал имеет ширину WIDTH, вместо того, чтобы пытаться его угадать (или назначить 80, если это невозможно предугадать).
  • -H HEIGHT, —height HEIGHT — Предположим, что терминал имеет HEIGHT высоту, вместо того, чтобы пытаться его угадать (или назначить 25, если это невозможно предугадать).
  • -N NAME, —name NAME — Префикс выводимой информации с помощью NAME. Полезно в сочетании с «-c», если у вас сложный пайп и вы хотите, чтобы он мог разделить вывод на разные части.
  • -f, —force — Пренудительный вывод. Обычно pv не выводит никакого визуального вывода, если стандартная ошибка не является терминалом. Этот параметр заставляет это показать.
  • -c, —cursor — Используйте escape последовательности позиционирования курсора вместо использования возврата каретки. Это полезно в сочетании с «-N (name)», если вы используете несколько pv запросов и соединяете его в один длинный конвейер.

Модификаторы передачи данных

  • -L RATE, —rate-limit RATE — Ограничьте передачу до максимального RATE байта в секунду. Суффикс «k», «m», «g», или «t» могут быть добавлены для обозначения килобайт (*1024), мегабайт и т. д.
  • -B BYTES, —buffer-size BYTES — Использовать размер буфера передачи BYTES байтов. Суффикс «k», «m», «g», или «t»могут быть добавлены для обозначения килобайт (*1024), мегабайт и т. д. Размер буфера по умолчанию — это размер блока файловой системы входного файла, умноженный на 32 (максимальный 512kb) или 400 кбайт, если размер блока не может быть определен.
  • -R PID, —remote PID — Если PID является экземпляром pv, который уже запущен, -R PID заставит этот экземпляр действовать так, как если бы ему была назначена командная строка этого экземпляра. Например, если запустить «pv -L 123k» и он имеет 9876 ID процесс, тогда запуск «pv -R 9876 -L 321k» заставит его начать использовать ограничение скорости 321k вместо 123k. Обратите внимание, что во время работы некоторые параметры не могут быть изменены, например «-c», «-l» и «-f».

Общие опции

  • -h, —help — Выводит показать справку об использовании данной утилиты и завершает работу.
  • -V, —version — Выводит версию ПО и завершает работу.

ФОРМАТИРОВАНИЕ

Если задана опция «-F», формат вывода можно определить строкой формата. Внутри этой строки могут использоваться следующие последовательности:

  • %p — Индикатор выполнения. Развертывается, чтобы заполнить оставшееся пространство. Следует указывать только один раз. Эквивалентно «-р» опиции.
  • %t — Пройденное время. Эквивалентно «-t» опции.
  • %e — Оставшееся время (ETA). Эквивалентно «-e»опции.
  • %I — Время завершения (ETA). Эквивалентно «-I»опции.
  • %r — Текущая скорость передачи данных. Эквивалентно «-r» опции.
  • %a — Средняя скорость передачи данных. Эквивалентно «-a» опции.
  • %b — Байты, передаваемые до сих пор (или строки, если указано «-l» опция). Эквивалентно «-b» опции.
  • %T — Процент используемого буфера передачи. Эквивалентно «-T» опции. Показывает «{—-}» если передача выполняется с помощью splice, поскольку сплайсинг в/из пайп(а) не использует буфер.
  • %nA — Показать последние n записанных байтов, (например, %16A — последние 16 байт). Показывает только точки, если передача выполняется с помощью splice, поскольку сплайсинг в/из пайп(а) не использует буфер.
  • %N — Префикс имени, присвоенный «-N» опцией.
  • %% — Один %. Стандартная строка, эквивалентная включению всех переключателей вывода (display switches), `%N %b %T %t %r %a %p %e’.

Использование утилиты pv в Unix/Linux

Например, можно использовать утилиту pv вместо cat, следующим образом:

# pv linux-notes.org.zone.txt | gzip > linux-notes.org.tar.gz
 963 MB 0:00:50 [2.04MiB/s] [======================>.................] 10% ETA 0:04:50

Собственно, все наглядно выглядит. Не правда ли?

Давайте упакуем некоторую папку в архив:

# tar -czf - backUPs | pv > backUPs.tgz
 455MiB 0:00:13 [35.7MiB/s] [            <=>                                   ]

Наглядно, но не знаешь когда операция завершиться, по этому, давайте добавим ключ «-s» чтобы вывести ETA, например:

# tar -czf - backUPs | pv -s $(du -sb backUPs| grep -o '[0-9]*') > backUPs.tgz
100MB 0:00:50 [3.88MB/s] [>..........................] 20% ETA 0:04:50

Так же, можно составлять команды из несколько копий pv:

# tar -cf - backUPs | pv -cN tar -s $(du -sb ./backUPs | grep -o '[0-9]*') | gzip | pv -cN gzip > backUPs.tgz
tar: 97.1MB 0:00:08 [12.3MB/s] [>......................] 0% ETA 1:50:26
gzip: 13.1MB 0:00:08 [1.6MB/s] [....<=>................]

Можно выводить прогресс-бар в виде цифр (в столбик), например:

$ tar -czf - backUPs | pv -n > backUPs.tgz
2
4
6
8
10
12
......
100

Такс, например, вам нужно ограничить скорость изменять скорость передачи данных через pv утилиту. Например, я использовал -L для ограничения скорости передачи данных до  4МБ/с:

$ tar -czf - backUPs | pv -L 4m > backUPs.tgz
30MiB 0:00:08 [4.17MiB/s] [         <=>               ]

Как я уже описывал разные опции, но опишу опции еще раз:

  • -c — Данная опция не выводит информацию друг поверх друга.
  • -N — Называем шкалу определенным именем.

Можно поигратся и выполнить:

# pv /dev/urandom > /dev/null
66MB 0:00:44 [ 6.8MB/s] [...<=>............................]

Чтобы узнать как быстро компьютер читает с /dev/zero, выполните:

$ pv /dev/zero > /dev/null

Обнуление диска, можно выполнить следющим образом:

# pv < /dev/zero > /dev/sda

Симуляция ввода:

$ echo "You could simulate some text here" | pv -qL 10

Чтобы проверить тест пропускной способности сети ssh, выполните:

$ yes | pv | ssh $your_host_here "cat > /dev/null"

Или:

$ pv /dev/zero|ssh $your_host_here 'cat > /dev/null'

И так, команда что выше, подключается к хосту через ssh и отображает скорость передачи в реальном времени, направляя все переданные данные в /dev/null.

Пример использования pv и dd утилиты:

# dd if=/dev/sdc bs=4096 | pv -s 2G | sudo dd bs=4096 of=~/USB_BLACK_BACKUP.IMG

Чтобы поиграться, выполните:

$ curl -s http://artscene.textfiles.com/vt100/movglobe.vt | pv -q -L 9600

Используя инструмент pv и dialog, вы можете создать панель выполнения следующим образом:

# tar -czf - ./home/captain/backups/ | (pv -n > backup.tgz) 2>&1 | dialog --gauge "Progress" 10 70

Работа pv + mysql в Unix/Linux

Создать mysqldump можно так:

$ pv my_DB.sql.gz | gunzip | mysql -uroot -p my_DB

Или:

$ mysqldump -uroot -p my_DB | pv | gzip -9 >m y_DB.sql.gz

Влить созданный mysqldump можно так:

$ zcat my_DB.sql.gz | pv -cN zcat | mysql -uroot -p my_DB

Более нагляднее, будет:

$ zcat my_DB.sql.gz | pv --progress --size `gzip -l %s | sed -n 2p | awk '{print $2}'` | mysql -uroot -p my_DB

Чтобы сделать его еще приятнее, вы можете добавить progres NAME, например:

# zcat my_DB.sql.gz | pv --progress --size `gzip -l %s | sed -n 2p | awk '{print $2}'` --name ' Importing.. ' | mysql -uroot -p my_DB

Вот  и все, статья «Утилита pv — прогресс bar для консольных утилит в Unix/Linux» завершена.


Установка packer в Unix/Linux

$
0
0

Установка packer в Unix/Linux

Packer прост в использовании и автоматизирует создание любого типа образа машин. Он охватывает современное управление конфигурацией, используя автоматические скрипты для установки и настройки программного обеспечения на ваших образах, созданных упаковщиком. Т.е packer — это инструмент для создания одинаковых образов ОС для различных платформ из одного описания.

Установка packer в CentOS/Fedora/RedHat

Если у вас еще используется 32-битная ОС, то вы можете использовать следующую ссылку чтобы скачать ПО:

# cd /usr/local/src && curl -O https://releases.hashicorp.com/packer/1.1.3/packer_1.1.3_linux_386.zip

Если у вас используется 64-битная ОС, то вы можете использовать следующую ссылку чтобы скачать ПО:

# cd /usr/local/src && curl -O https://releases.hashicorp.com/packer/1.1.3/packer_1.1.3_linux_amd64.zip

Если у вас используется ARM, то вы можете использовать следующую ссылку чтобы скачать ПО:

# cd /usr/local/src && curl -O https://releases.hashicorp.com/packer/1.1.3/packer_1.1.3_linux_arm.zip

Если у вас используется ARM64, то вы можете использовать следующую ссылку чтобы скачать ПО:

# cd /usr/local/src && curl -O https://releases.hashicorp.com/packer/1.1.3/packer_1.1.3_linux_arm64.zip

PS: На момент написания статьи, я использовал самую новую версию данной утилиты. Данный продукт довольно быстро развиваеться и за ним нужно следить и скачивать самую новую версию (если есть необходимость). На официальном сайте можно скачать актуальную версию.

Установка packer в Debian/Ubuntu

Если у вас еще используется 32-битная ОС, то вы можете использовать следующую ссылку чтобы скачать ПО:

# cd /usr/local/src && curl -O https://releases.hashicorp.com/packer/1.1.3/packer_1.1.3_linux_386.zip

Если у вас используется 64-битная ОС, то вы можете использовать следующую ссылку чтобы скачать ПО:

# cd /usr/local/src && curl -O https://releases.hashicorp.com/packer/1.1.3/packer_1.1.3_linux_amd64.zip

Если у вас используется ARM, то вы можете использовать следующую ссылку чтобы скачать ПО:

# cd /usr/local/src && curl -O https://releases.hashicorp.com/packer/1.1.3/packer_1.1.3_linux_arm.zip

Если у вас используется ARM64, то вы можете использовать следующую ссылку чтобы скачать ПО:

# cd /usr/local/src && curl -O https://releases.hashicorp.com/packer/1.1.3/packer_1.1.3_linux_arm64.zip

PS: На момент написания статьи, я использовал самую новую версию данной утилиты. Данный продукт довольно быстро развиваеться и за ним нужно следить и скачивать самую новую версию (если есть необходимость). На официальном сайте можно скачать актуальную версию.

Установка packer в Mac OS X

Для скачивания ПО, можно использовать следующу команду:

# cd /usr/local/src && curl -O https://releases.hashicorp.com/packer/1.1.3/packer_1.1.3_darwin_amd64.zip

PS: На момент написания статьи, я использовал самую новую версию данной утилиты. Данный продукт довольно быстро развиваеться и за ним нужно следить и скачивать самую новую версию (если есть необходимость). На официальном сайте можно скачать актуальную версию.

Установка packer в FreeBSD

Если у вас еще используется 32-битная ОС, то вы можете использовать следующую ссылку чтобы скачать ПО:

# cd /usr/local/src && curl -O https://releases.hashicorp.com/packer/1.1.3/packer_1.1.3_freebsd_386.zip

Если у вас используется 64-битная ОС, то вы можете использовать следующую ссылку чтобы скачать ПО:

# cd /usr/local/src && curl -O https://releases.hashicorp.com/packer/1.1.3/packer_1.1.3_freebsd_amd64.zip

Если у вас используется ARM, то вы можете использовать следующую ссылку чтобы скачать ПО:

# cd /usr/local/src && curl -O https://releases.hashicorp.com/packer/1.1.3/packer_1.1.3_freebsd_arm.zip

PS: На момент написания статьи, я использовал самую новую версию данной утилиты. Данный продукт довольно быстро развиваеться и за ним нужно следить и скачивать самую новую версию (если есть необходимость). На официальном сайте можно скачать актуальную версию.

Установка packer в OpenBSD

Если у вас еще используется 32-битная ОС, то вы можете использовать следующую ссылку чтобы скачать ПО:

# cd /usr/local/src && curl -O https://releases.hashicorp.com/packer/1.1.3/packer_1.1.3_openbsd_386.zip

Если у вас используется 64-битная ОС, то вы можете использовать следующую ссылку чтобы скачать ПО:

# cd /usr/local/src && curl -O https://releases.hashicorp.com/packer/1.1.3/packer_1.1.3_openbsd_amd64.zip

PS: На момент написания статьи, я использовал самую новую версию данной утилиты. Данный продукт довольно быстро развиваеться и за ним нужно следить и скачивать самую новую версию (если есть необходимость). На официальном сайте можно скачать актуальную версию.

Установка packer в Solaris

Для скачивания ПО, можно использовать следующу команду:

# cd /usr/local/src && curl -O https://releases.hashicorp.com/packer/1.1.3/packer_1.1.3_solaris_amd64.zip

PS: На момент написания статьи, я использовал самую новую версию данной утилиты. Данный продукт довольно быстро развиваеться и за ним нужно следить и скачивать самую новую версию (если есть необходимость). На официальном сайте можно скачать актуальную версию.

Установка packer для других Unix/Linux ОС

Можно попробовать скомпилировать данное ПО. Я работу не проверял, но разработчики выкладуют исходный код на гитхабе и его можно попробовать заюзать.

# cd /usr/local/src && git clone https://github.com/hashicorp/packer.git

И дальше следовать инструкциям.

Настройка packer в Unix/Linux

Скачать то архив упели, но нужно его еще и расспаковать и подготовить к работе.

# cd /usr/local/src; unzip packer_*.zip && rm -f unzip packer_*.zip

Перенесем файл:

# mv /usr/local/src/packer /usr/local/bin/

PS: Если не прописан PATH для /usr/local/bin — стоит прописать его в .bash_profile!

Для установки packer, я написал скрипт:

# vim install_packer.sh

Который имеет следующий код:

#!/bin/bash -x

# CREATED:
# vitaliy.natarov@yahoo.com
#
# Unix/Linux blog:
# http://linux-notes.org
# Vitaliy Natarov
#

function install_packer () {
	#
	if [ -f /etc/centos-release ] || [ -f /etc/redhat-release ] ; then
		#update OS
		yum update &> /dev/null -y && yum upgrade &> /dev/null -y
		#	
		if ! type -path "wget" > /dev/null 2>&1; then yum install wget &> /dev/null -y; fi
		if ! type -path "curl" > /dev/null 2>&1; then yum install curl &> /dev/null -y; fi	
		if ! type -path "unzip" > /dev/null 2>&1; then yum install unzip &> /dev/null -y; fi
		if [ -z "`rpm -qa | grep redhat-lsb-core`" ]; then 
			yum install redhat-lsb-core &> /dev/null -y 
		fi
    	OS=$(lsb_release -ds|cut -d '"' -f2|awk '{print $1}')
    	OS_MAJOR_VERSION=$(sed -rn 's/.*([0-9]).[0-9].*/\1/p' /etc/redhat-release)
		OS_MINOR_VERSION=$(cat /etc/redhat-release | cut -d"." -f2| cut -d " " -f1)
		Bit_OS=$(uname -m | sed 's/x86_//;s/i[3-6]86/32/')
		echo "$OS-$OS_MAJOR_VERSION.$OS_MINOR_VERSION with $Bit_OS bit arch"
		#
		site="https://releases.hashicorp.com/packer/"
		Latest_packer_version=$(curl -s "$site" --list-only | grep -E "packer_" | head -n1| cut -d ">" -f2| cut -d "<" -f1| cut -c8-)
		URL_with_latest_packer_package=$site$Latest_packer_version
		#
		if [ "`uname -m`" == "x86_64" ]; then
 			Latest_packer_package=$(curl -s "$URL_with_latest_packer_package/" --list-only |grep -E "packer_" | grep -E "linux_amd64"|cut -d ">" -f2| cut -d "<" -f1)
 			Current_link_to_archive=$URL_with_latest_packer_package/$Latest_packer_package
 		elif [ "`uname -m`" == "i386|i686" ]; then
 			Latest_packer_package=$(curl -s "$URL_with_latest_packer_package/" --list-only |grep -E "packer_" | grep -Ev "(SHA256SUMS|windows)"| grep -E "linux_386"|cut -d ">" -f2| cut -d "<" -f1)
 			Current_link_to_archive=$URL_with_latest_packer_package/$Latest_packer_package	
 		fi	
 		echo $Current_link_to_archive
		cd /usr/local/src/ && wget $Current_link_to_archive &> /dev/null
		unzip $Latest_packer_package
		rm -rf /usr/local/src/$Latest_packer_package*
		yes|mv -f /usr/local/src/packer /usr/local/bin/packer
		chmod +x /usr/local/bin/packer
	
	elif [ -f /etc/fedora_version ]; then

		if ! type -path "wget" > /dev/null 2>&1; then apt-get install wget &> /dev/null -y; fi
		if ! type -path "curl" > /dev/null 2>&1; then apt-get install curl &> /dev/null -y; fi	
		if ! type -path "unzip" > /dev/null 2>&1; then apt-get install unzip &> /dev/null -y; fi
	
		echo "Fedora";
		OS=$(lsb_release -ds|cut -d '"' -f2|awk '{print $1}')
    	OS_MAJOR_VERSION=`sed -rn 's/.*([0-9])\.[0-9].*/\1/p' /etc/fedora_version`
		OS_MINOR_VERSION=`sed -rn 's/.*[0-9].([0-9]).*/\1/p' /etc/fedora_version`
		Bit_OS=$(uname -m | sed 's/x86_//;s/i[3-6]86/32/') 
		echo "$OS-$OS_MAJOR_VERSION.$OS_MINOR_VERSION($CODENAME) with $Bit_OS bit arch"
		#
		site="https://releases.hashicorp.com/packer/"
		Latest_packer_version=$(curl -s "$site" --list-only | grep -E "packer_" | head -n1| cut -d ">" -f2| cut -d "<" -f1| cut -c8-)
		URL_with_latest_packer_package=$site$Latest_packer_version	
		#
		if [ "`uname -m`" == "x86_64" ]; then
 			Latest_packer_package=$(curl -s "$URL_with_latest_packer_package/" --list-only |grep -E "packer_" | grep -E "linux_amd64"|cut -d ">" -f2| cut -d "<" -f1)
 			Current_link_to_archive=$URL_with_latest_packer_package/$Latest_packer_package
 		elif [ "`uname -m`" == "i386|i686" ]; then
 			Latest_packer_package=$(curl -s "$URL_with_latest_packer_package/" --list-only |grep -E "packer_" | grep -Ev "(SHA256SUMS|windows)"| grep -E "linux_386"|cut -d ">" -f2| cut -d "<" -f1)
 			Current_link_to_archive=$URL_with_latest_packer_package/$Latest_packer_package	
 		fi	
 		echo $Current_link_to_archive
		cd /usr/local/src/ && wget $Current_link_to_archive &> /dev/null
		unzip $Latest_packer_package
		rm -rf /usr/local/src/$Latest_packer_package*
		yes|mv -f /usr/local/src/packer /usr/local/bin/packer
		chmod +x /usr/local/bin/packer
		# 
	elif [ -f /etc/debian_version ]; then
		#update OS
		apt-get update &> /dev/null -y && apt-get upgrade &> /dev/null -y
		yes| apt-get install apt-transport-https &> /dev/null
		#
		if ! type -path "wget" > /dev/null 2>&1; then yes| apt-get install wget &> /dev/null; fi
		if ! type -path "curl" > /dev/null 2>&1; then yes| apt-get install curl &> /dev/null; fi
		if ! type -path "unzip" > /dev/null 2>&1; then yes| apt-get install unzip &> /dev/null; fi	
		#
    	echo "Debian/Ubuntu/Kali Linux";
    	OS=$(lsb_release -ds|cut -d '"' -f2|awk '{print $1}')
    	OS_MAJOR_VERSION=`sed -rn 's/.*([0-9])\.[0-9].*/\1/p' /etc/debian_version`
		OS_MINOR_VERSION=`sed -rn 's/.*[0-9].([0-9]).*/\1/p' /etc/debian_version`
		Bit_OS=$(uname -m | sed 's/x86_//;s/i[3-6]86/32/')
    	#
		CODENAME=`cat /etc/*-release | grep "VERSION="`
		CODENAME=${CODENAME##*\(}
		CODENAME=${CODENAME%%\)*}
		echo "$OS-$OS_MAJOR_VERSION.$OS_MINOR_VERSION($CODENAME) with $Bit_OS bit arch"
 		#
		site="https://releases.hashicorp.com/packer/"
		Latest_packer_version=$(curl -s "$site" --list-only | grep -E "packer_" | head -n1| cut -d ">" -f2| cut -d "<" -f1| cut -c8-)
		URL_with_latest_packer_package=$site$Latest_packer_version
		#	
		if [ "`uname -m`" == "x86_64" ]; then
			Latest_packer_package=$(curl -s "$URL_with_latest_packer_package/" --list-only |grep -E "packer_" | grep -E "linux_amd64"|cut -d ">" -f2| cut -d "<" -f1)
 			Current_link_to_archive=$URL_with_latest_packer_package/$Latest_packer_package
 		elif [ "`uname -m`" == "i386|i686" ]; then
 			Latest_packer_package=$(curl -s "$URL_with_latest_packer_package/" --list-only |grep -E "packer_" | grep -Ev "(SHA256SUMS|windows)"| grep -E "linux_386"|cut -d ">" -f2| cut -d "<" -f1)
 			Current_link_to_archive=$URL_with_latest_packer_package/$Latest_packer_package	
 		fi	
 		echo $Current_link_to_archive
		cd /usr/local/src/ && wget $Current_link_to_archive &> /dev/null
		unzip $Latest_packer_package
		rm -rf /usr/local/src/$Latest_packer_package*
		yes|mv -f /usr/local/src/packer /usr/local/bin/packer
		chmod +x /usr/local/bin/packer
	elif [ -f /usr/sbin/system_profiler ]; then
		OS=$(uname)
		Mac_Ver=$(sw_vers -productVersion | awk -F '.' '{print $1 "." $2}')
		Bit_OS=$(uname -m | sed 's/x86_//;s/i[3-6]86/32/')
		echo "MacOS: $OS-$Mac_Ver with $Bit_OS bit arch"
		which -s brew
		if [[ $? != 0 ]] ; then
    		# Install Homebrew
    		ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
		else
			# update homebrew
    		brew update && brew upgrade
		fi
		Latest_packer_package=$(curl -s "$URL_with_latest_packer_package/" --list-only |grep -E "packer_" | grep -E "darwin_amd64"|cut -d ">" -f2| cut -d "<" -f1)
 		Current_link_to_archive=$URL_with_latest_packer_package/$Latest_packer_package
 		echo $Current_link_to_archive
		cd /usr/local/src/ && wget $Current_link_to_archive &> /dev/null
		unzip $Latest_packer_package
		rm -rf /usr/local/src/$Latest_packer_package*
		yes|mv -f /usr/local/src/packer /usr/local/bin/packer
		chmod +x /usr/local/bin/packer
	else
    	OS=$(uname -s)
    	VER=$(uname -r)
    	echo 'OS=' $OS 'VER=' $VER
	fi
}
install_packer
echo "========================================================================================================";
echo "================================================FINISHED================================================";
echo "========================================================================================================";

Запустить установку можно следующим образом:

# bash install_packer.sh

Проверялось на Debian 8, CentOS 6/7 и на Mac OS X.

Использование packer в Unix/Linux

Создадим файл:

# vim first_test_with_packer.json

Пример кода:

{
  "variables": {
    "aws_access_key": "",
    "aws_secret_key": ""
  },
  "builders": [{
    "type": "amazon-ebs",
    "access_key": "{{user `aws_access_key`}}",
    "secret_key": "{{user `aws_secret_key`}}",
    "region": "us-east-1",
    "source_ami_filter": {
      "filters": {
      "virtualization-type": "hvm",
      "name": "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*",
      "root-device-type": "ebs"
      },
      "owners": ["099720109477"],
      "most_recent": true
    },
    "instance_type": "t2.micro",
    "ssh_username": "ubuntu",
    "ami_name": "first_test_with_packer {{timestamp}}"
  }]
}

Проверяем валидацию темплейта:

$ packer validate first_test_with_packer.json
Template validated successfully.

Создаем образ:

$ packer build \
-var 'aws_access_key=YOUR ACCESS KEY' \
-var 'aws_secret_key=YOUR SECRET KEY' \
first_test_with_packer.json

Вот и все, статья «Установка packer в Unix/Linux» завершена.

Разрешение доступа с определенных IP для Proftpd в Unix/Linux

$
0
0

Разрешение доступа с определенных IP для Proftpd в Unix/Linux

Хотел бы сохранить заметку «Разрешение доступа с определенных IP для Proftpd в Unix/Linux» и в ней описать как можно запретить доступ к директориям моего FTP — сервера (Proftpd) для определенных IP- адресов, но к некоторым оставить доступ.

Установка Proftpd в Unix/Linux

Я описывал процесс установки на различные ОС тут:

Установка Proftpd на Debian/Ubuntu/Mint

Установка ProFTPD на CentOS

Установка Proftpd на FreeBSD из исходников

Так же, будет полезно знать:

Скачивать и закачивать файлы по FTP используя консоль

Настройка Proftpd в Unix/Linux

Отредактируем конфигурационный файл Proftpd.

Для FreeBSD он будет лежать:

# vim /usr/local/etc/proftpd.conf

Для CentOS/RedHat/Fedora он лежит:

# vim /etc/proftpd.conf

Для Debian или Ubuntu:

# vim /etc/proftpd/proftpd.conf

Я добавлю в класс ournetwork, некоторые строки с ограничением доступа, например:

<Class mynetwork>
From xx.xx.xx.xx/27
From your_IP-address/mask
From xx.xx.xx.xx/24
From xx.xx.xx.xx/32
From 31.13.45.123/16
</Class>

После этого в директории к которой нам необходимо закрыть доступ, пишем следующее:

<Limit LOGIN READ DIRS>
AllowClass mynetwork
DenyAll
</Limit>

Собственно, сейчас я запретил доступ всем, но предоставил доступ только с определенных подсетей! После чего необходимо перезапустить сервер proftpd.

FreeBSD:

# /usr/local/etc/rc.d/proftpd restart

Linux:

# service proftpd restart

Вот и все, статья «Разрешение доступа с определенных IP для Proftpd в Unix/Linux» завершена.

Удалить пустые строки с файла в Unix/Linux

$
0
0

Удалить пустые строки с файла в Unix/Linux

Иногда, у нас имеются файлы и в них много пустых строк — это не очень удобно (по крайней мере для чтения). Файлы можно отредактировать вручную, если файл имеет несколько пустых строк, но если файл имеет тысячи пустых строк, это трудно сделать вручную. Используйте один из следующих методов для удаления пустых строк из файла.

-=== СПОСОБ 1 — Использование утилиты SED ===-

Sed  потоковый редактор.  С помощью этой утилиты, можно легко удалить все пустые строки. Используйте одну из следующих команд sed для удаления пустых строк из файла.

Где:

  • main.txt — Это исходный файл, из которого нужно удалить пустые строки.
  • output_file.txt — Будет служить файлом без пустых строк.

# sed '/^$/d' main.txt > out.txt

Или:

# sed -i '/^$/d' main.txt

-=== СПОСОБ 2 — Использование perl ===-

И так, чтобы удалить пустые строки в файлу (у меня это main.txt), используйте:

# perl -i -n -e "print if /S/" main.txt

-=== СПОСОБ 3 — Использование утилиты AWK ===-

Используйте команду awk для удаления пустых строк из файла.

Где:

  • main.txt — Это исходный файл, из которого нужно удалить пустые строки.
  • output_file.txt — Будет служить файлом без пустых строк.

И так, запускаем:

# awk 'NF > 0' main.txt > out.txt

-=== СПОСОБ 4 — Использование утилиты CAT ===-

Используйте команду cat для удаления пустых строк из файла.

Где:

  • main.txt — Это исходный файл, из которого нужно удалить пустые строки.
  • output_file.txt — Будет служить файлом без пустых строк.

И так, запускаем:

$ cat main.txt | grep -Ev "^$" > out.txt

-=== СПОСОБ 4 — Использование утилиты TR ===-

Используйте команду cat для удаления пустых строк из файла.

Где:

  • main.txt — Это исходный файл, из которого нужно удалить пустые строки.
  • output_file.txt — Будет служить файлом без пустых строк.

$ tr -s '\n' < main.txt > out.txt

Если появятся еще идеи. Я дополню данную тему!

Вот и все, статья «Удалить пустые строки с файла в Unix/Linux» завершена.

Работа с .deb файлами в Debian/Ubuntu

$
0
0

Работа с .deb файлами в Debian/Ubuntu

Хочу написать замутку по работу с deb пакетами для новичков или тех, кто подзабыл использование той или иной команды. Тема не новая, но взята для добавления материала на сайт.

Установить .deb файлы в Debian/Ubuntu

Чтобы установить «your_package» пакет, используйте следующую команду:

# dpkg -i your_package.deb

Или, можно использовать:

# dpkg --install your_package.deb

Так же, можно использовать «-R» опцию для установки всех .deb пакетов в папке (рекурсивно), например:

# dpkg -i -R /home/captain/deb_packages/

Или, можно использовать:

# dpkg -i --recursive /home/captain/deb_packages

Можно использовать утилиту APT:

# apt install your_package.deb

Идем дальше.

Удалить .deb файлы в Debian/Ubuntu

Чтобы удалить «your_package» пакет, используйте следующую команду:

# dpkg -r your_package.deb

Вот и все, статья «Установить .deb файлы через консоль в Debian/Ubuntu» завершена.

Установка lynis в Unix/Linux

$
0
0

Установка lynis в Unix/Linux

Lynis — это инструмент для аудита безопасности в Unix и Linux ОС. Он выполняет глубокие проверки безопасности, практически без настройки. Обычно используется системными администраторами, специалистами по безопасности и аудиторами для оценки защиты Unix/Linux систем. Он работает на самом хосте, поэтому он выполняет более обширные проверки безопасности, чем сканеры уязвимостей.

Поддерживаемые ОС

Lynis работает практически во всех Unix системах, включая:

  • AIX;
  • FreeBSD;
  • HP-UX;
  • Linux;
  • Mac OS X;
  • NetBSD;
  • OpenBSD;
  • Solaris;
  • Raspberry PI;
  • QNAP
  • И другие.

Установка lynis на CentOS/RedHat/Fedora

-=== СПОСОБ 1 — Использовать установщик yum===-

Установка очень простая и примитивная:

# yum install lynis -y

-=== СПОСОБ 2 — Использовать git===-

Выполняем:

# git clone https://github.com/CISOfy/lynis-sdk && ./lynis-devkit build rpm

-=== СПОСОБ 3 — Использовать репозиторий===-

Установим вспомогательные пакеты:

# yum update ca-certificates curl nss openssl -y

Создаем репо-файл:

# vim /etc/yum.repos.d/cisofy-lynis.repo

И, вставляем в него:

[lynis]
name=CISOfy Software - Lynis package
baseurl=https://packages.cisofy.com/community/lynis/rpm/
enabled=1
gpgkey=https://packages.cisofy.com/keys/cisofy-software-rpms-public.key
gpgcheck=1

Следующий шаг — установка Lynis:

# yum makecache fast lynis -y

Как-то так.

Установка lynis на Debian/Ubuntu

-=== СПОСОБ 1 — Использовать установщик apt-get===-

Установка очень простая и примитивная:

# apt-get install lynis -y

-=== СПОСОБ 2 — Использовать git===-

Выполняем:

# git clone https://github.com/CISOfy/lynis-sdk && ./lynis-devkit build rpm

-=== СПОСОБ 3 — Использовать репозиторий===-

Скачиваем ключ:

# apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C80E383C3DE9F082E01391A0366C67DE91CA5D5F

Или:

# wget -O - https://packages.cisofy.com/keys/cisofy-software-public.key | apt-key add -

Установим вспомогательные пакеты:

# apt install apt-transport-https -y

Использование программного обеспечения на английском языке? Затем настройте APT, чтобы пропустить загрузку переводов. Это экономит полосу пропускания и предотвращает дополнительную нагрузку на серверы репозитория:

$ echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/99disable-translations

Далее, добавляем репозиторий:

Версия Команда
Debian 7 echo «deb https://packages.cisofy.com/community/lynis/deb/ wheezy main» > /etc/apt/sources.list.d/cisofy-lynis.list
Debian 8 echo «deb https://packages.cisofy.com/community/lynis/deb/ jessie main» > /etc/apt/sources.list.d/cisofy-lynis.list
Debian 9 echo «deb https://packages.cisofy.com/community/lynis/deb/ stretch main» > /etc/apt/sources.list.d/cisofy-lynis.list
Др. Debian echo «deb https://packages.cisofy.com/community/lynis/deb/ stable main» > /etc/apt/sources.list.d/cisofy-lynis.list
 Ubuntu 16.04  echo «deb https://packages.cisofy.com/community/lynis/deb/ xenial main» > /etc/apt/sources.list.d/cisofy-lynis.list
Др Ubuntu echo «deb https://packages.cisofy.com/community/lynis/deb/ stable main» > /etc/apt/sources.list.d/cisofy-lynis.list

Обновите локальную базу данных пакетов новыми данными репозитория:

# apt update -y

Выполняем установку:

# apt install lynis -y

Как-то так.

Установка lynis на MacOS X

-=== СПОСОБ 1 — Использовать установщик brew===-

Устанавливаем homebrew, если не знаете как, можно ознакомиться тут:

Установка homebrew в macOS

После чего выполняем поиск (для подтверждения наличия пакета в ОС):

$ brew search lynis

И если есть, выполняем установку:

$ brew install lynis

-=== СПОСОБ 2 — Использовать git===-

Я опишу процесс установки ниже.

Установка lynis в других Unix/Linux ОС

Исходный код можно скачать следующим образом:

# mkdir /usr/local/lynis && cd /usr/local/lynis && wget https://cisofy.com/files/lynis-2.5.7.tar.gz && tar -xvf lynis-*.tar.gz

Используйте следующую команду для запуска сканирования:

# ./lynis --check-all

Можно скачать с github:

# git clone https://github.com/CISOfy/Lynis

И выполняем:

$ cd lynis; ./lynis audit system

Использование lynis в Unix/Linux

Lynis выполняет сотни отдельных тестов, чтобы определить состояние безопасности системы. Сама проверка безопасности состоит в выполнении набора шагов от инициализации программы до его отчета:

  1. Определяет операционную систему.
  2. Поиск доступных инструментов и утилит.
  3. Проверка Lynis обновлений.
  4. Запуск тестов для включенных плагинов.
  5. Запуск тестов безопасности для каждой категории.
  6. Состояние отчета проверки безопасности.

Во время сканирования технические данные о сканировании хранятся в лог-файл. В то же время результаты (предупреждения, предложения, сбор данных) хранятся в файле отчета.

Оппортунистическое сканирование

Сканирование Lynis является оппортунистическим: оно использует то, что может найти.

Например, если он видит, что вы используете Apache, он будет выполнять начальный раунд тест связанныq с Apache. Если во время сканирования Apache, он также обнаружит SSL/TLS конфигурацию, то он будет выполнять дополнительные шаги для аудита. При этом он будет собирать обнаруженные сертификаты, чтобы впоследствии их можно было отсканировать.

Углубленное сканирование безопасности

Выполняя оппортунистическое сканирование, инструмент может работать практически без зависимостей. Чем больше он найдет, тем глубже будет аудит. Другими словами, Lynis всегда будет выполнять сканирование, настроенное для вашей системы.

Плагины для Lynis

  • Docker Containers.
  • File Integrity.
  • File sytems.
  • Firewalls.
  • Memory.
  • Processes plugin.
  • Software plugin.

Для подробной информации, используйте:

# man lynis

Выполним полную проверку системы в «тихом» режиме (иначе после каждого блока проверок придется подтверждать действия вводом с клавиатуры):

# lynis -c -Q

По завершению сканирования, внимательно изучаем отчет. Желательно в первую очередь исправить все Warnings и по мере возможности, выполнить рекомендации секции Suggestions. Также порадовал параметр Hardening index, который отображает числовое значение уровня защищенности сервера.

Некоторые полезные опции:

  • —checkall, -c : Запуск сканирования.
  • —check-update : Проврка обновлений для Lynis.
  • —cronjob : Запускает Lynis как cronjob (включает в себя «-c» и «-Q» опции).
  • —help, -h : Показывает помощь.
  • —quick, -Q : Не ждите ввода пользователя, кроме ошибок.
  • —version, -V : Выводит Lynis версию.

Создание Lynis Cronjobs

Если вы хотите создать ежедневный отчет о проверке своей системы, вам нужно установить для него задание cron:

# crontab -e

Добавьте следующее задание cron с параметром -crontab, все специальные символы будут проигнорированы из вывода, и сканирование будет полностью автоматизировано:

00 12 * * * root lynis -c -Q --auditor "automated" --cronjob

Данная задание будет выполнятся каждый день, в 12.00 и будут вести отчет в /var/log/lynis.log файл.

Обновление Lynis

Если вы хотите обновить lynis, просто введите следующую команду, чтобы загрузить и установить последнюю версию lynis:

# lynis --check-update

Вот и все, статья «Установка lynis в Unix/Linux» завершена.

Создание Fork Bomb в Unix/Linux

$
0
0

Создание Fork Bomb в Unix/Linux

Концепция Fork Bomb — коварная маленькая программа, которая порождает себя n-раз, отбросив цепную реакцию (рекурсия) и тем самым быстро исчерпав ресурсы системы.

Примеры создания  Fork Bomb в Unix/Linux

WARNING! Эти примеры могут привести к сбою вашего компьютера в случае его выполнения.

Примеры создания  Fork Bomb с использованием bash

И так, код выглядит так:

# :(){ :|:& };:

Где:

  • :() — Определение функции.
  • {  — Открытие функции.
  • :|: — Далее, загружает копию функции «:» в память тем самым, будет вызывать само себя с использованием техники программирования ( так называемая рекурсия) и передает результат на другой вызов функции.
  • ‘:’ — Худшая часть — функция, вызываемая два раза, чтобы «бомбить» вашу систему.
  • & — Помещает вызов функции в фоновом режиме, чтобы fork (дочерний процесс) не мог «умереть» вообще, тем самым это начнет есть системные ресурсы.
  • } — Закрытие функции.
  • ; — Завершите определение функции. Т.е является разделителем команд, (такой как и &&).
  • : — Запускает функцию которая порождает fork bomb().

Это рабочий код, но не очень читабельный. Вот пример нормального, читаемого кода:

#!/usr/bin/env bash -x

bomb() {
   bomb | bomb &
   };
bomb

Идем дальше.

Примеры создания  Fork Bomb с использованием perl

Пример встроенной оболочки с использованием интерпретатора Perl:

# perl -e "fork while fork" &

Примеры создания  Fork Bomb с использованием Python

Пример кода:

import os
while True: 
os.fork()

Примеры создания  Fork Bomb с использованием Ruby

И так, вот код:

#!/usr/bin/ruby
loop { fork { __FILE__ } }

Примеры создания  Fork Bomb с использованием C/C++

Код будет выглядеть:

#include <unistd.h>

int main(void)
{
while(1)
fork();
}

Примеры Defusing Fork Bomb в Unix/Linux

Defusing — так званое разминирование fork bomb. Из-за их характера, такие бомбы трудно оставновить после их запуска. Чтобы остановить такую бомбу, нужно  завершить все рабочих копий, чего может быть трудно достичь. Одна из проблем заключается в том, что данная команда не может быть выполнена из-за того, что таблица процессов полностью забита. Вторая серьезная проблема заключается в том,  на момент поиска процессов для прекрашения потратилось время за которое могло создатся еще пару форков программы.

Для удаления такой бомбы, можно использовать одну из перечисленных команд:

# killall -STOP processWithBombName
# killall -KILL processWithBombName

Когда у системы мало свободных PID (в Linux максимальное количество PID-ов можно получить получено из /proc/sys/kernel/pid_max), «разрядка» form bomb-ы становится более сложной:

# killall -9 processWithBombName

Можно получить ошибку:

bash: fork: Cannot allocate memory

В этом случае разрядка бомбы возможна только в том случае, если хотя бы одна оболочка открыта. Процессы могут не разветвляться, но можно выполнить любую программу из текущей оболочки. Как правило, возможна только одна попытка.

Команда «killall -9» не выполняется непосредственно из оболочки, потому что команда не является атомарной и не удерживает блокировки в списке процессов, поэтому к тому времени когда она закончится, fork bomb наплодит еще ПИДов. Поэтому нужно запустить несколько процессов killall, например:

# while :; do killall -9 processWithBombName; done

Еще пример, — т.к таблица процессов достапна в Linux через ФС (/proc), то можно обезвредить данный форк бомбы с помощью встроенных функций bash, которые не требуют развертывания новых процессов.

Следующий пример идентифицирует процессы, связанные с нарушением и приостанавливает их, чтобы предотвратить данный форк, до того момента, пока они убиты по одному за раз. Это позволяет избежать состояния гонки других примеров, которые могут потерпеть неудачу, если нарушающие процессы могут развиваться быстрее, чем они убиты:

# cd /proc && for p in [0-9]*; do read cmd < "$p/cmdline"; if [[ $cmd = processWithBombName ]]; then kill -s STOP "$p" || kill -s KILL "$p"; fi; done

Как-то так!

Надеюсь это было увлекательно и познавательно, особенно — если об этом не знали. А у меня все, статья «Создание Fork Bomb в Unix/Linux» завершена.

Запуск GUI-приложения в Docker

$
0
0

Запуск GUI-приложения в Docker

Хочу поведать историю о том, как я запустил GUI-приложение в Docker. некоторые спросят, зачем? Ну есть много причин, вот некоторые из них:

  • Нет нужного пакета/утилиты под твою ОС.
  • Проверить что получится.

Запуск GUI-приложения в Docker

Для начала, установим вспомогательное ПО:

Установка docker machine в Unix/Linux

Установка Docker на Debian/Ubuntu

Установка Docker на CentOS/RedHat/Fedora

Установка docker-compose в Unix/Linux

-=== Запуск mysql-workbench в Docker ===-

После чего, я создам машину для тестов, буду использовать docker-machine:

$ docker-machine create --driver virtualbox --virtualbox-cpu-count "2" --virtualbox-memory "2048" --virtualbox-disk-size "20000" mysql-workbench

Потом выполняю:

$ docker-machine env mysql-workbench

И:

$ eval $(docker-machine env mysql-workbench)

Машина создана, подключаемся к ней:

$ docker-machine ssh mysql-workbench

Внутри созданной докер-машины, создаем:

# vim Dockerfile

И прописываем:

FROM debian
RUN apt-get update
RUN apt-get install -qqy x11-apps mysql-workbench libcanberra-gtk-module packagekit-gtk3-module
ENV DISPLAY :0
CMD /usr/bin/mysql-workbench

Где нужно изменить «ENV DISPLAY :0» строку на свой «DISPLAY», чтобы узнать его, выполните:

$ echo $DISPLAY

Получите вывод (Если у вас MacOS X):

/private/tmp/com.apple.launchd.6iXsMbPJbh/org.macosforge.xquartz:0

Получите вывод (Если у вас Linux. Проверял на CentOS 6):

:0.0

Ну что, создаем контейнер:

$ docker build -t workbench - < Dockerfile

Запускаем контейнер и прокидываем в него сокет. Контейнер автоматически стартует MySQL-Workbench при запуске:

$ docker run --privileged -v /tmp/.X11-unix/X0:/tmp/.X11-unix/X0 workbench

PS: Можно прописать переменную:

$ export XSOCK=/tmp/.X11-unix/X0

Потом запуск будет проходить вот так:

$ docker run --privileged -v $XSOCK:$XSOCK workbench

Честно сказать, у меня не получилось запустить данный контейнер на моем macbook, получил ошибку:

(mysql-workbench-bin:19): Gtk-WARNING **: cannot open display: unix/private/tmp/com.apple.launchd.6iXsMbPJbh/org.macosforge.xquartz:0

Дубль 2, пробую выполнить все тоже, но на CentOS 6:

[root@puppet-agent captain]# docker run --privileged -v /tmp/.X11-unix/X0:/tmp/.X11-unix/X0 workbench
No protocol specified

(mysql-workbench-bin:20): Gtk-WARNING **: cannot open display: :0
[root@puppet-agent captain]# xhost +local:root
non-network local connections being added to access control list
[root@puppet-agent captain]# xhost +local:captain
non-network local connections being added to access control list

ИЛИ, для всех юзеров:

# xhost +localhost

Но это не верное решение, берем свой eth0 ИП:

# xhost + $ip

Так же, пробросим переменную для дисплея:

# export DISPLAY=:0.0

После этого, запускаю:

[root@puppet-agent captain]# docker run --privileged -v /tmp/.X11-unix/X0:/tmp/.X11-unix/X0 workbench

Вылезли другие ошибки… Посидел пару часов, я исправил ошибки на маке (описание решения, в самом низу статьи), ну а сейчас — я запускаю контейнер:

$ docker run -it -e DISPLAY=$ip:0 -v /tmp/.X11-unix:/tmp/.X11-uni workbench

Или (Но 1-й вариант лучше как по мне):

$ docker run --privileged --name firefox -e DISPLAY=$ip:0 -v /tmp/.X11-unix:/tmp/.X11-unix workbench

Получаю:

Запуск mysql-workbench в Docker

Шикарно! Все заработало!

-=== Запуск FireFox в Docker ===-

Существует несколько различных вариантов запуска GUI-приложений внутри Docker контейнера:

  • С использованием SSH с пересылкой X11
  • С использованием SSH с пересылкой VNC
  • Разделение сокетов между хостом и докер-контейнером

Самый простой способ — заключается в том, чтобы разделить мой сокет X11 с контейнером и использовать его напрямую. Идея довольно проста, и вы можете легко попробовать попробовать запустить контейнер Firefox, используя следующий файл Docker:

FROM ubuntu:14.04

RUN apt-get update && apt-get install -y firefox libcanberra-gtk-module packagekit-gtk3-module

# Replace 1000 with your user / group id
RUN export uid=1000 gid=1000 && \
mkdir -p /home/developer && \
echo "developer:x:${uid}:${gid}:Developer,,,:/home/developer:/bin/bash" >> /etc/passwd && \
echo "developer:x:${uid}:" >> /etc/group && \
echo "developer ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/developer && \
chmod 0440 /etc/sudoers.d/developer && \
chown ${uid}:${gid} -R /home/developer

USER developer
ENV HOME /home/developer
CMD /usr/bin/firefox

Запускаем:

$ docker build -t firefox .

Запускаем контейнер:

docker run -ti --rm \
-e DISPLAY=$DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix \
firefox

И вот что получилось:

Запуск FireFox в Docker

Данный пример приводился на CentOS 6, но у меня есть еще MacOS X и я бы хотел все же подружить все это дело!

Ставим пакет для MacOS X:

$ brew install caskroom/cask/xquartz

Запускаем:

$ open -a XQuartz

Открываем натройки, переходим во вкладку «security» и выставляем все галочки (2 шт):

Настройка Security в XQuartz

Идем далее:

$ ip=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}')
$ xhost + $ip

И, запускаем:

$ docker run -it -e DISPLAY=$ip:0 -v /tmp/.X11-unix:/tmp/.X11-uni firefox

Хочу добавить следующее, я много перерыл в интернете, но мало что полезного нашел. И да, вот как у меня выглядят конфигы ssh.

# cat /etc/ssh/ssh_config | grep -Ev "(#|^$)"

 Host *
   ForwardAgent yes
   ForwardX11 yes
Host *
	SendEnv LANG LC_*
Host *
    XAuthLocation /opt/X11/bin/xauth

И:

# cat /etc/ssh/sshd_config | grep -Ev "(#|^$)"

AuthorizedKeysFile	.ssh/authorized_keys
UsePAM yes
X11Forwarding yes
X11DisplayOffset 10
AcceptEnv LANG LC_*
Subsystem	sftp	/usr/libexec/sftp-server
XAuthLocation /opt/X11/bin/xauth

Приведу еще пример.

-=== Запуск spotify в Docker ===-

Выполняем:

$ ip=$(ifconfig eth1 | grep inet | awk '$1=="inet" {print $2}'| cut -c6-)
$ xhost + $ip

PS: У меня тут используется несколько интерфейсов, но я взял ИП с eth1.

Не буду собирать контейнер с Dockerfile, возьму готовый имедж:

$ # docker run --privileged --name spotify -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix jess/spotify

Я тут пробросил звуковое устройство во внутрь самого контейнера.

Запуск spotify в Docker

Вот это шайтаны додумались)))

На маке я пока не понял как это сделать 🙁

-=== Запуск wireshark в Docker ===-

Выполняем:

$ ip=$(ifconfig eth1 | grep inet | awk '$1=="inet" {print $2}'| cut -c6-)
$ xhost + $ip

PS: У меня тут используется несколько интерфейсов, но я взял ИП с eth1.

Не буду собирать контейнер с Dockerfile, возьму готовый имедж:

$ docker run -ti --net=host --privileged --name wireshark1 -v $HOME:/root:rw -e XAUTHORITY=/root/.Xauthority -e DISPLAY=$ip:0 manell/wireshark

Получаем:

Запуск wireshark в Docker

Работает даже!

Вот и все, статья «Запуск GUI-приложения в Docker» завершена.


Перезапуск SSH/SSHd в Mac OS X

$
0
0

Перезапуск SSH/SSHd в Mac OS X

Решил создать заметку по перезапуску SSH в MacOS X. Для меня это было впервые, но тут нет ничего сложного…

-=== СПОСОБ 1.1 — Использовать launchctl утилиту ===-

Чтобы перезапустить ssh/sshd службу в Mac OS X, выполните следующие команды:

# launchctl stop com.openssh.sshd && launchctl start com.openssh.sshd

После этого, выполнится перезапуск службы.

Это есть один из самый правильных и наилучших способов  выполнить перезапуск службы.

-=== СПОСОБ 1.2 — Использовать launchctl утилиту ===-

Выполняем остановку SSH утилиты:

$ sudo launchctl unload /System/Library/LaunchDaemons/ssh.plist

И, собственно — запускаем ее сново:

$ sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist

После этого, выполнится перезапуск службы.

Это есть один из самый правильных и наилучших способов  выполнить перезапуск службы.

-=== СПОСОБ 2 — Использовать перезапуск ОС ===-

Так же, можно выполнить:

# launchctl reboot com.openssh.sshd

Или:

# osascript -e 'tell app "System Events" to restart'

Или:

# reboot

PS: Компьютер будет немедленно перезагружен. ОСТОРОЖНО!

Вот и все, статья  «Перезапуск SSH/SSHd в Mac OS X» завершена.

Утилита xhost в Unix/Linux

$
0
0

Утилита xhost в Unix/Linux

Xhost это утилита для изменения параметров доступа к X-серверу из пакета X11-xserver-utils. Данная утилита, является частью безопасности X11. Она управляет списком удаленного сервера, который может установить соединение с локальным X сервером. Так же, данная программа, используется для добавления и удаления хостов или пользователей в список, разрешенный для подключения к X-серверу.

В случае с хостами это обеспечивает рудиментарную форму контроля конфиденциальности и безопасности. Этого достаточно для рабочей станции в одмнотользовательском (single user, not multi user) режиме.

Установка xhost в Unix/Linux

Иногда, данная утилита не присутствует в ОС и по этому, нужно ее установить.

Установка xhost в DEB ОС

Выполняем установку:

# apt-get install x11-xserver-utils x11-utils

Для поиска можно использовать:

# apt-cache search xhost
x11-xserver-utils - X server utilities

Как-то так.

Установка xhost в RPM ОС

Выполняем установку:

# yum install xorg-x11-server-utils -y

Дополнительные пакеты:

# yum install -y xorg-x11-app*
# yum groupinstall -y 'X Window System'
# yum install -y xorg-x11-xauth xorg-x11-fonts-* xorg-x11-utils xterm
# yum -y groupinstall fonts

Для поиска можно использовать:

# yum whatprovides "*/xhost"

Как-то так.

Установка xhost в MacOS X

Выполняем установку homebrew — Установка homebrew на Mac OS X и после чего, выполняем:

$ brew install Caskroom/cask/xquartz

Как-то так.

Использование xhost в Unix/Linux

Данная утилита имеет следующий синтаксис:

$ xhost [[+−] remote_host_name ...]

Опции:

  • -help — Служит командой для вывода помощи по командам и опциям.
  • +name — Добавляет «name» (название IP или хостнейма) в список, кто имеет право подключаться к X-серверу.
  • -name — Удаляет «name» (название IP или хостнейма) со списка тех, кто имеет право подключаться к X-серверу.
  • +  — Контроль доступа к X-серверу отключен; разрешение всем и отовсюду.
  • —  — Контроль доступа к X-серверу включен; разрешение только по списку.
  • <ничего>  — Если аргументов не указано то выводится информации о текущем состоянии разрешения подключений.

Выведем информацию о текущем состоянии разрешений пользователей или хостов на подключение:

$ xhost

Разрешить полный доступ к X-серверу (всем и отовюсду):

# xhost +

Запретить доступ к X-серверу (разрешение только по списку):

# xhost -

Разрешить запуск графических программ от имени root на локальной машине:

# xhost local:root

Разрешить запуск графических программ от имени root на локальной машине:

# xhost local:root

Или:

# xhost +si:localuser:root

Разрешить запуск графических программ с 192.168.13.113 на локальной машине:

# xhost + 192.168.13.113

Запретить запуск графических программ с 192.168.13.113 на локальной машине:

# xhost - 192.168.13.113

Можно указать вот так:

  • 192.168.13.113:0 Нулевой дисплей на компьютере Sky
  • 192.168.13.113:0.1 Первый экран нулевого дисплея данного компьютера
  • 192.168.13.113:3 Третий дисплей данного компьютера

Чаще всего имя дисплея — это или просто «:0.0», или «компьютер:0.0». Чтобы узнать какой дисплей используется в системе, выполните:

$ echo $DISPLAY

Чтобы установить DISPLAY переменную, выполните (bash):

$ DISPLAY=192.168.13.113:0.0; export DISPLAY

Чтобы установить DISPLAY переменную, выполните (bash):

$ setenv DISPLAY 192.168.13.113:0.0

xhost + — огромная дыра в безопасности, поскольку она дает каждому доступ к вашим ресурсам X-сервера (не только вашему дисплею, но также и вашу мышь и клавиатуру), поэтому каждый может читать или изменять то, что вы набираете/нажимаете. Плохая привычка использовать «xhost +». Даже когда вы используете «xhost + localhost», вы открываете доступ всем людям кто на localhost-е.  Тогда, как быть и что исользовать? Простейшим способом является ssh-туннелирование.

$ ssh -X oracle@localhost
Last login: Fri Max 2 11:33:55 2017 from localhost

$ if xterm -e true; then echo success; fi
success

Другой способ это — использовать cookie X:

$ xauth extract ~/my-x-cookie $DISPLAY<
$ setfacl -m u:oracle:r ~/my-x-cookie
$ su - oracle -c "DISPLAY=$DISPLAY bash"
Password:

$ if xterm -e true; then echo success; fi
Xlib: connection to ":0.0" refused by server
Xlib: No protocol specified

xterm Xt error: Can't open display: :0.0

$ xauth merge ~lsc/my-x-cookie
xauth: creating new authority file ~oracle/.Xauthority

$ if xterm -e true; then echo success; fi
success

Можно создать алиас:

alias oracle='
xauth extract $HOME/my-x-cookie $DISPLAY;
setfacl -m u:oracle:r $HOME/my-x-cookie;
su - oracle -c "export DISPLAY=$DISPLAY;
xauth merge $HOME/my-x-cookie;
bash"'

Вот и все, статья «Утилита xhost в Unix/Linux» подошла к завершению.

Настройка X11 forwarding используя ssh в Unix/Linux

$
0
0

Настройка X11 forwarding используя ssh в Unix/Linux

X11 forwarding — это механизм, позволяющий отображать на локальном клиентском компьютере графические интерфейсы X11 программ, запущенных на удаленном Unix/Linux сервере. SSH имеет возможность безопасного туннелирования X11 соединений, так что сеансы X11 forwarding-а шифруются и инкапсулируются. Если вы хотите настроить X11 forwarding через SSH, то данная тема именно для вас.

Установка ПО для настройки X11 forwarding используя ssh в Unix/Linux

Для X11 forwarding-а на удаленном сервере не требуется полная система X11. Однако, серверу необходимо установить xauth. xauth — это утилита, которая поддерживает конфигурации Xauthority, используемые сервером и клиентом для аутентификации сеансов X11. Чтобы установить xauth, выполните следующие действия на удаленном сервере.

Установка xauth в Debian/Ubuntu

И так, выполняем команду:

# apt-get install xauth -y

Переходим к настройке.

Установка xauth в CentOS/RedHat

И так, выполняем команду:

# yum install -y xorg-x11-xauth xorg-x11-utils xorg-x11-fonts-* xorg-x11-apps xorg-x11-server-Xorg

Установка xauth в Fedora

И так, выполняем команду:

# dnf install xorg-x11-xauth

Установка xauth для других Unix/Linux ОС

Можно создать docker контейнер и запустить его.

Переходим к настройке.

Настройка X11 forwarding используя ssh в Unix/Linux

Открываем файл:

# vim /etc/ssh/sshd_config

И прописываем (приводим к виду):

X11Forwarding yes
X11DisplayOffset 10

Так же, можно прописать:

X11UseLocalhost no

Перезапуск SSH сервера:

  • Если используете Debian 6, Ubuntu или Linux Mint:
    # /etc/init.d/ssh restart
  • Если используете Debian 7, CentOS/RHEL 7, Fedora
    # systemctl restart ssh.service
  • Если используете CentOS/RHEL 6
    $ sudo service sshd restart

Вышеупомянутая настройка, позволяет X11 форвардинг на хост сервера. Если вы хотели бы включить X11 forwarding для отдельного пользователя, вы можете использовать пользовательский файл конфигурации ssh (т. е. $HOME/.ssh/config). Таким образом, вы можете использовать переадресацию X11 только тогда, когда вы используете ssh для учетной записи пользователя. Открываем:

$ vim $HOME/.ssh/config

И прописываем:

ForwardX11 yes

Мой файл выглядит следующим образом:

IdentityFile ~/.ssh/id_rsa
Host *
    UseKeychain yes
    ForwardX11 no
    ServerAliveInterval 15
    ForwardAgent yes
    ForwardX11Trusted yes

    GatewayPorts yes

Если используете Vagrant,  то внутри его, можно пробросить следующие опции:

config.ssh.forward_agent = true
config.ssh.forward_x11 = true

Ну и далее запускаем все это дело.

Использование X11 forwarding через ssh в Unix/Linux

На локальном хосте должна быть установлена система с X11, чтобы отображать удаленные программы. Для того чтобы выполнить форвардинг, выполните:

$ ssh -X remote_ssh_user@remote_server

Например:

$ ssh -X -v root@66.66.66.66

После входа в систему вы можете запускать любую X11 программу на удаленном сервере, как обычно, и ее отображение будет отображаться на локальной клиентской машине.

Можно еще опции, передавать через коммандную строку:

$ ssh -o ForwardX11=yes user_name@your_remote_server

Безопастность при использовании X11 forwarding через ssh

Обычно, не рекомендуется всегда работать с «ForwardX11 yes». Поэтому, если вы хотите использовать свои SSH-соединения с пвыщенной безопасностью, лучше всего сделать следующее:

  • Не прописывать «ForwardX11 yes» в ваш «$HOME/.ssh/confi»g файл.
  • Используйте «ForwardingX11» только когда вам это необходимо, используя «ssh -X your_user@your_server».
  • Если вы можете, полностью отключите «X11Forwarding» на вашем сервере.

Вот и все, статья «Настройка X11 forwarding используя ssh в Unix/Linux» завершена.

Ошибка «X11 forwarding request failed on channel 0»в Unix/Linux

$
0
0

Ошибка «X11 forwarding request failed on channel 0» в Unix/Linux

При использования SSH, получил ошибку «X11 forwarding request failed on channel 0». Поискав в интернете, я нашел решение. Решил сделать заметку и себе на сайт.

-=== СПОСОБ 1 ===-

По соображениям безопасности сервер OpenSSH по умолчанию связывает сервер пересылки X11 с локальным адресом обратной связи и устанавливает имя хоста в переменной среды DISPLAY на «localhost». В соответствии с этой настройкой, некоторые X11 клиенты не могут правильно обрабатывать пересылку X11, что вызывает сообщение об ошибке. Чтобы устранить эту проблему, откроем файл:

# vim /etc/ssh/sshd_config

Находим следующие строки и приводим к такому виду:

X11Forwarding yes
X11UseLocalhost no

Перезапуск SSH сервера:

  • Если используете Debian 6, Ubuntu или Linux Mint:
    # /etc/init.d/ssh restart
  • Если используете Debian 7, CentOS/RHEL 7, Fedora
    # systemctl restart ssh.service
  • Если используете CentOS/RHEL 6
    $ sudo service sshd restart

Если это не помогло, можно попробовать 2-й вариант решения данной проблемы.

-=== СПОСОБ 2 ===-

Ошибка форвардинга X11 может также произойти, если удаленный хост на котором работает сервер SSH, отключен IPv6. По этому, откроем файл:

# vim /etc/ssh/sshd_config

И, добавляем строку:

AddressFamily inet

Перезапуск SSH сервера:

  • Если используете Debian 6, Ubuntu или Linux Mint:
    # /etc/init.d/ssh restart
  • Если используете Debian 7, CentOS/RHEL 7, Fedora
    # systemctl restart ssh.service
  • Если используете CentOS/RHEL 6
    $ sudo service sshd restart

Вот и все, статья ‘Ошибка «X11 forwarding request failed on channel 0» в Unix/Linux’ завершена.

Установка socat в Unix/Linux

$
0
0

Установка socat в Unix/Linux

socat — инструмент командной строки, который позволяет переадресовывать сокеты c хостовой машины, на клиентскую. Данная утилита устанавливает два потока двунаправленного байта и передает данные между ними.

Утилита socat используется для:

  • TCP порт forwarder-а.
  • Тестирование безопасности.
  • Shell интерфейс для UNIX-сокетов.
  • Реле IP6.
  • Для перенаправления TCP-ориентированных программ на последовательную линию.
  • Логически подключать последовательные линии на разных компьютерах.
  • Устанавливает относительно безопасную среду (su и chroot) для запуска bash скриптов клиента или сервера с сетевыми подключениями.

Установка socat в Debian/Ubuntu

Выполняем установку:

# apt-get install socat -y

Для удаления socat используется следующая команда:

# apt-get remove socat

Следующая команда используется для удаления пакета socat вместе со своими зависимостями:

# apt-get remove --auto-remove socat

Это позволит удалить socat и все его зависимые пакеты, которые больше не нужны в системе.

Полностью удалить socat со всеми конфигурационными файлами можно одним из следующих способов:

  • Следующая команда должна использоваться с осторожностью, поскольку она удаляет все файлы конфигурации и данные:
    # apt-get purge socat
  • или вы также можете использовать следующую команду:
    # apt-get purge --auto-remove socat

Выше команда удалит все файлы конфигурации и данные, связанные с пакетом socat. Можно переходить к использованию.

Установка socat в Redhat/Fedora/CentOS

Выполняем установку:

# yum install socat -y

Можно переходить к использованию.

Установка socat в MacOS X

Для начала, у становим homebrew, я описывал процесс в статье — Установка homebrew на Mac OS X и после чего, выполняем поиск пакета:

$ brew search socat

Ну, теперь можно и поставить ПО следующим образом:

$ brew install socat

Можно переходить к использованию.

Использование socat в Unix/Linux

Я запускаю socat следующим образом:

$ socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"

Получаем ИП-шку локальной машины:

$ ip=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}') &amp;&amp; echo "My IP is: $ip"

Разрешить локальной машине «разговаривать» с XQuartz:

$ xhost + ${ip}

Запускаем:

$ docker run --rm -it -e DISPLAY=${ip}:0 -v /tmp/.X11-unix:/tmp/.X11-unix --name firefox jess/firefox

Все это было нужно для запуска графических утилит внутри docker контейнера:

Запуск GUI-приложения в Docker

Утилита xhost в Unix/Linux

Настройка X11 forwarding используя ssh в Unix/Linux

Т.е socat — пробрасывает сокет с хоста на клиенсткую машину.

Еще примеры…

Перенаправление TCP портов

Чтобы вуполнить перенаправление 80-го порта на 192.168.13.225, используем:

# socat TCP-LISTEN:80,fork TCP:192.168.13.225:80 &amp;

И так, все TCP4 соединения которые будет находится на 80-му порту, будут перенаправлены на 192.168.13.225. Проверим что вышло:

# netstat -natpl | grep 80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      75881/socat

И процесс:

# ps -aux | grep socat | grep -Ev "grep"
root      75881  0.0  0.1  51836  2488 pts/1    S    20:51   0:00 socat TCP-LISTEN:80,fork TCP:192.168.13.225:80

Подключение к удаленному SSH серверу

Вы можете подключиться к удаленному ssh серверу (например — Your_remote_server) с использованием pty для связи между socat и ssh, что делает его ssh управляющим tty (ctty); и делает его pty владельцем новой группы процессов (setsid), поэтому ssh принимает пароль из утилиты socat:

$ (sleep 5; echo Your_password; sleep 5; echo date; sleep 1) |socat - EXEC:'ssh -o StrictHostKeyChecking=no Your_remote_username@Your_remote_server',pty,setsid,ctty

Где:

  • Your_password — пароль от пользователя «your_remote_username».
  • Your_remote_username — Удаленный пользователь.
  • Your_remote_server — Удаленный сервер.

Получение информации о Haproxy

Давайте получим информацию о запущенном процессе HAProxy ( pid, SLA и тд и тп):

# echo "show info" | socat unix-connect:/var/tmp/haproxy stdio

Перенаправление TCP портов (каждая сторона привязана к другому локальному IP-адресу) (bind)

В этом примере обрабатывается почти произвольное количество параллельных/последовательных подключений путем fork’ing-а нового процесса после каждого приема соединений. Он обеспечивает небольшую безопасность, не дожидаясь пользователя после разветвления; он разрешает только соединения из частной сети (10.0.0.0/8); из-за reuseaddr, он обеспечивает немедленный перезапуск после завершения мастер-процесса, даже если некоторые дочерние сокеты не полностью закрыты. С помощью -lmlocal2, socat регистрируется в stderr, пока не будет успешно достигнуто принятие цикла. Дальнейшее ведение (лог) направляется в syslog с объектом local2:

# socat -d -d -lmlocal2 \
TCP4-LISTEN:80,bind=myaddr1,su=nobody,fork,range=10.0.0.0/8,reuseaddr \
TCP4:192.168.13.225:80,bind=myaddr2

Копируем данные между STDIN и STDOUT

Вот пример:

# socat -v STDIN STDOUT
test
&gt; 2018/01/04 21:36:11.357493  length=5 from=0 to=4
test
test
It's working......
&lt; 2018/01/04 21:36:31.501174  length=19 from=0 to=18
It's working......
It's working......

Т.е socat копирует все что вы написали (STDIN) и выводит на вывод (STDOUT).

Слушаем TCP сокет, запускаем shell, шлем месагу, «засыпаем» на некоторое время и дисконектимся

На сервере, выполняем:

#socat tcp-l:7777,reuseaddr,fork system:'echo hello; sleep 5; echo goodbye',nofork

Т.к это один сервер (у меня), чтобы проверить что вышло, я запускаю телнет на клиенсткой машине:

# telnet localhost 7777

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
hello
goodbye

Connection closed by foreign host.

Так же, можно тоже самое сделать с socat утилитой, например:

# socat tcp:localhost:7777 -
hello
goodbye

Запускаем удаленные команды через socat

На сервере, запускаем:

# socat TCP-LISTEN:1234,reuseaddr EXEC:/bin/bash

Чтобы запустить данную команду на заднем плане (в бэкграунде), юзаем:

# socat TCP-LISTEN:1234,reuseaddr EXEC:/bin/bash &amp;

Проверяем:

# socat - TCP:localhost:1234

Т.е данная команда, симулирует команду (netcat).

Разрешить несколько подключений c клиентов к удаленным оболочкам shell:

# socat TCP-LISTEN:1234,reuseaddr,fork EXEC:/bin/bash

Использование де-мультиплексных входных данных от нескольких TCP/IP клиентов к одному выходному потоку (STDOUT)

Запускаем команду на сервере:

# socat TCP-LISTEN:1234,reuseaddr -

На клиенте (1-м):

# echo "client A" | socat - TCP:localhost:1234

На клиенте (2-м):

# echo "client B" | socat - TCP:localhost:1234

После выполнения команды на клиенте, вы на стороне сервера должны получить следующий вывод:

client A

client B

Создание своего файл сервера (файловая шара) с использованием socat

На сервере, выполняем:

# socat tcp-l:1236,reuseaddr,fork file:my_file.txt

Этим, я разшарил файл на серверной стороне.

На стороне клиента, выполняем:

# socat tcp:localhost:1236 file:copied_my_file.txt,create

Это позволит скачать и сохранить файл.

Можно слать файлы прям с сервера на клиент:

# socat TCP:your_hostname_machine:port_machine filename

Или, можно выполнить что-то типа:

# socat TCP-LISTEN:80,reuseaddr,fork,crlf SYSTEM:"echo HTTP/1.0 200; echo Content-Type\: text/plain; echo Connection\: close; echo" &amp;
# socat tcp:localhost:80 file:copied_my_file.txt,create

Подключение к процессу (здесь удаленный shell) через socat

Обычно socat отключается, когда один из подключенных адресов или клиентов закрывает соединение. Это имеет недостаток, что при следующем подключении вы будете подключены к новому запущенному процессу при использовании «system:» или «exec :». Но есть обходной путь — использовать пайп.

На стороне сервера, создаем pipe:

# rm -f myfifo; mkfifo myfifo

Потом, выполняем:

# cat myfifo | /bin/sh -i 2&gt;&amp;1 | socat -v tcp-listen:1234,fork,reuseaddr - &gt; myfifo

На стороне клиента, выполняем:

# socat - tcp:localhost:1234

Получить время с указанного сервера

Например:

# socat TCP:time.nist.gov:13 -

Выполнение команд на web-сервере с использованием socat

Например:

# socat -d -d READLINE,history=$HOME/.http_history \
TCP4:Your_domain_name:www,crnl

Вы можете редактировать текущую строку в стиле bash (READLINE) и использовать файл истории .http_history; socat выводит сообщения о прогрессе (-d -d). Порт указан по имени службы (www), и используются правильные символы завершения сети (crnl) вместо NL.

Простой TCP порт форвардер

Пример:

# socat TCP4-LISTEN:www TCP4:www.your_domain_name:www

Устанавливает простую переадресацию TCP портов. С TCP4-LISTEN он прослушивает локальный «www» порт до тех пор, пока не произойдет соединение, а затем подключится к удаленному хосту (TCP4) и начнет передачу данных. Он не будет принимать второе соединение.

Однонаправленная передача данных с socat

Выполняем:

# socat -u /tmp/readdata,seek-end=0,ignoreeof -

Это пример однонаправленной передачи данных (-u). Socat передает данные из файла /tmp/readdata (неявный адрес GOPEN), начиная с его конца (seek-end = 0 позволяет socat начинать чтение c конца файла, использовать seek = 0) в режиме «tail -f» (ignoreeof). «Файл» также может быть прослушивающим сокером домена UNIX (тогда не используйте опцию поиска).

Простой сборщик сообщений с socat

Выполняем:

# socat -u TCP4-LISTEN:3334,reuseaddr,fork \
OPEN:/tmp/in.log,creat,append

Реализует простой сборщик сообщений на основе сети. Для каждого клиента, подключенного к порту 3334, создается новый дочерний процесс (опция fork). Все данные, отправленные клиентами, добавляются к файлу /tmp/in.log. Если файл не существует, socat создает его. Опция reuseaddr позволяет немедленно перезапустить серверный процесс.

Подключение к FTP с socat

Команда:

# socat READLINE,noecho='[Pp]assword:' EXEC:'ftp your_ftp_server',pty,setsid,ctty

Идем дальше…

Создание больших файлов с socat

Выполним:

# echo |socat -u - file:/tmp/My_file_name_here,create,largefile,seek=500000000000

Данная команда, создает разреженный файл (My_file_name_here) размером 500ГБ (для этого служит seek опция); Так же, требуется тип файловой системы, который поддерживает это действие (ext2, ext3, reiserfs, jfs; not minix, vfat). Операция записи (1 байта) может занять много времени (reiserfs: несколько минут, ext2: «нет»), и полученный файл займет указанное место на диске, но только с его inod-ами (reiserfs: 2MB; ext2: 16KB).

Боримся с флудом с утилитой socat

Выполняем команду:

# socat - tcp:www.your_domain_here:80,readbytes=1000

Данная команда подключается к серверу (на 80-й порт) и предотвращает появлению flood-а.

Зеркальная файловая система

На сервере выполняем:

# dd if=/dev/sda1 | socat - openssl:your_sink_host:9999

Где:

  • your_sink_host — хост для синка.

На клиенте, выполняем:

# socat openssl-listen:9999 | dd of=/dev/sda66

Создание pg_dump-а и отправка его на сервер без записи на диск с socat

На сервере выполняем:

# pg_dump -C dbname | bzip2 | socat - openssl:sink:8443

На клиенте, выполняем:

# socat openssl-listen:8443 &gt; dbname.sql

Отправка UDP пакетов на указанные порты

Выполянем:

# for PORT in {1001..65535}; do echo "READ YOUR CONSTITUTION, NOT OUR EMAIL." | socat - UDP4-DATAGRAM:Your_domain_here:$PORT; sleep .1; done

А на этом, у меня все. Статья «Установка socat в Unix/Linux» завершена.

Защита от Meltdown|Spectre в Unix/Linux

$
0
0

Защита от Meltdown|Spectre в Unix/Linux

Meltdown нарушает самую фундаментальную изоляцию между пользовательскими приложениями и операционной системой. Эта атака позволяет программе получать доступ к памяти, а также к скрытым возможностям других программ и операционной системы. Если ваш компьютер имеет уязвимый процессор и запускает незагруженную операционную систему, небезопасно работать с конфиденциальной информацией без утечки информации. Это относится как к персональным компьютерам (ПК), так и к облачной инфраструктуре.

Spectre нарушает изоляцию между различными приложениями. Это позволяет злоумышленнику обманывать программы и выполнять утечку данных.

Защита от Meltdown|Spectre в Unix/Linux

Микрокод — это код для процессора (его прошивка), поставляемая Intel или AMD. Ядро Linux может обновлять прошивку процессора без обновления BIOS во время загрузки. Микрокод процессора хранится в ОЗУ, а ядро обновляет микрокод во время каждой загрузки.

И так, проверим статус микрокода:

$ dmesg | grep microcode

Обратите внимание, что вполне возможно, что для вашего процессора нет обновления микрокода. В этом случае он будет выглядеть следующим образом:

[ 0.952699] microcode: sig=0x306a9, pf=0x10, revision=0x1c
[ 0.952773] microcode: Microcode Update Driver: v2.2.

Исправление для CentOS/RedHat/Fedora:

# yum install microcode_ctl linux-firmware -y

Исправление для Debian/Ubuntu:

# apt install intel-microcode -y

Исправление для Mac OS X:

Пока Apple не выпустила обновление (10.01.2018).

После обновления, выполняем ребут ОС:

$ sudo reboot

Потом,смотрим что получилось:

# dmesg | grep 'microcode'

Получаем что-то типа:

[    0.000000] microcode: microcode updated early to revision 0x1c, date = 2015-02-26
[    1.604672] microcode: sig=0x306a9, pf=0x10, revision=0x1c
[    1.604976] microcode: Microcode Update Driver: v2.01 &lt;tigran@aivazian.fsnet.co.uk&gt;, Peter Oruba

Вот и все, статья «Защита от Meltdown|Spectre в Unix/Linux» завершена.

Работа с AWS IAM и Terraform в Unix/Linux

$
0
0

Работа с AWS IAM и Terraform в Unix/Linux

AWS IAM (Identity and Access Management) — это веб-сервис, который дает возможность контролировать доступ к ресурсам AWS. Вы используете IAM для контроля того, кто аутентифицирован и авторизован (имеет разрешения) для использования ресурсов. Когда вы сначала создаете учетную запись AWS, вы начинаете с единого идентификатора входа, который имеет полный доступ ко всем услугам и ресурсам AWS в рамках учетной записи.  Этот идентификатор называется пользователем учетной записи в AWS, и к нему можно получить доступ, выполнив вход с адресом электронной почты и паролем, который использовался для создания учетной записи.

Рекомендуется не использовать root пользователя для выполнения ваших повседневных задач, даже административных. Он служит только для создания аккаунтов в 1-й раз, а потом не используется (для наилучшей безопастности).

Установка terraform в Unix/Linux

Установка крайне примитивная и я описал как это можно сделать тут:

Установка terraform в Unix/Linux

Так же, в данной статье, я создал скрипт для автоматической установки данного ПО. Он был протестирован на CentOS 6/7, Debian 8 и на Mac OS X. Все работает должным образом!

Работа с AWS IAM и Terraform в Unix/Linux

У меня есть папка terraform, в ней у меня будут лежать провайдеры с которыми я буду работать. Т.к в этом примере я буду использовать AWS, то создам данную папку и перейду в нее. Далее, в этой папке, стоит создать:

$ mkdir examples modules

В папке examples, я буду хранить так званые «плейбуки» для разварачивания различных служб, например — zabbix-server, grafana, web-серверы и так далее. В modules директории, я буду хранить все необходимые модули.

Начнем писать модуль, но для этой задачи, я создам папку:

$  mkir modules/iam

Переходим в нее:

$ cd modules/iam

Открываем файл:

$ vim iam.tf

В данный файл, вставляем:

#---------------------------------------------------
# Instance Profile
#---------------------------------------------------
resource "aws_iam_instance_profile" "profile" {
    name = "${var.name}-profile-${var.environment}-${var.region}"
    role = "${aws_iam_role.role.name}"
}
#----------------------------------------------------
# IAM Role
#----------------------------------------------------
resource "aws_iam_role" "role" {
  name        = "${var.name}-role-${var.environment}-${var.region}"
  description = "IMA ${var.name}-role-${var.environment}-${var.region} role"
  path        = "/"
  assume_role_policy ="${data.aws_iam_policy_document.role-policy-document.json}"
}
data "aws_iam_policy_document" "role-policy-document" {
  "statement" {
    effect = "Allow"

    principals {
      identifiers = [
        "${var.aws_iam_role-principals}",
      ]

      type = "Service"
    }

    actions = [
      "sts:AssumeRole",
    ]
  }
}
#----------------------------------------------------
# IAM Policy
#----------------------------------------------------
resource "aws_iam_policy" "policy" {
  name        = "${var.name}-policy-${var.environment}-${var.region}"
  description = "AIM ${var.name}-policy-${var.environment}-${var.region} policy"
  policy      = "${data.aws_iam_policy_document.policy-document.json}"
}
data "aws_iam_policy_document" "policy-document" {
  "statement" {
    effect = "Allow"

    resources = [
      "${var.aws_iam_policy-resources}",
    ]

    actions = [
      "${var.aws_iam_policy-actions}",
    ]
  }
}
#----------------------------------------------------
# IAM Policy Attachment
#----------------------------------------------------
resource "aws_iam_policy_attachment" "iam_policy_attachment" {
  name        = "${var.name}-iam_policy_attachment-${var.environment}-${var.region}"
  roles       = ["${aws_iam_role.role.name}"]
  policy_arn  = "${aws_iam_policy.policy.arn}"
}

Что тут описано…. Я поделил данный файл на 4 части:

  • Instance Profile — Прописываем пропиль инстанса.
  • IAM Role — Создаем IAM роль.
  • IAM Policy — Задаем полиси для созданной IAM роли.
  • IAM Policy Attachment — Прикрепляем созданную роль, полиси к инстансу.

Открываем файл:

$ vim variables.tf

И прописываем:

#-----------------------------------------------------------
# Global or/and default variables
#-----------------------------------------------------------
variable "name" {
  description = "Name to be used on all resources as prefix"
  default     = "TEST-AIM"
}

variable "region" {
  description = "The region where to deploy this code (e.g. us-east-1)."
  default     = "us-east-1"
}
#---------------------------------------------------------------
# Custom variables
#---------------------------------------------------------------
variable "environment" {
    description = "environment for service"
    default     = "PROD"
}
variable "aws_iam_role-principals" {
  type        = "list"
  description = "List of allowed actions."
}
variable "aws_iam_policy-resources" {
  type        = "list"
  description = "List of allowed actions."
  default     = ["*"]
}
variable "aws_iam_policy-actions" {
  type        = "list"
  description = "List of allowed actions."
  # default     = ["*"]

}

Собственно в этом файле храняться все переменные. Спасибо кэп!

Открываем последний файл:

$ vim outputs.tf

и в него вставить нужно следующие строки:

output "instance_profile_uid" {
    value = "${aws_iam_instance_profile.profile.unique_id}"
}
output "role_arn" {
    value = "${aws_iam_role.role.arn}"
}

output "role_name" {
    value = "${aws_iam_role.role.name}"
}

output "policy_name" {
    value = "${aws_iam_policy.policy.name}"
}
output "AWS region" {
    value = "${var.region}"
}

output "role_id" {
  value = "${aws_iam_role.role.id}"
}

Данный файл служит для того, чтобы выводить нужные значения на экран вашего экрана.

Переходим теперь в папку aws/examples и создадим еще одну папку для проверки написанного чуда:

$ mkdir aim &amp;&amp; cd $_

Внутри созданной папки открываем файл:

$ vim main.tf

И вставим в него следующий код:

#
# MAINTAINER Vitaliy Natarov "vitaliy.natarov@yahoo.com"
#
terraform {
  required_version = "&gt; 0.9.0"
}
provider "aws" {
    region  = "us-east-1"
    # access_key = "${var.aws_access_key}"
    # secret_key = "${var.aws_secret_key}"
    #
}

module "aim" {
    source                          = "../../modules/iam"
    name                            = "TEST-AIM"
    region                          = "us-east-1"
    environment                     = "PROD"

    aws_iam_role-principals         = [
        "ec2.amazonaws.com",
    ]
    aws_iam_policy-actions           = [
        "cloudwatch:GetMetricStatistics",
        "logs:DescribeLogStreams",
        "logs:GetLogEvents",
        "elasticache:Describe*",
        "rds:Describe*",
        "rds:ListTagsForResource",
        "ec2:DescribeAccountAttributes",
        "ec2:DescribeAvailabilityZones",
        "ec2:DescribeSecurityGroups",
        "ec2:DescribeVpcs",
  ]
}

Все уже написано и готово к использованию. Ну что, начнем тестирование. В папке с вашим плейбуком, выполняем:

$ terraform init

Этим действием я инициализирую проект. Затем, подтягиваю модуль:

$ terraform get

PS: Для обновление изменений в самом модуле, можно выполнять:

$ terraform get -update

Запускем прогон:

$ terraform plan

Вывод будет такой:

Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

data.aws_iam_policy_document.role-policy-document: Refreshing state...
data.aws_iam_policy_document.policy-document: Refreshing state...

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  + module.aim.aws_iam_instance_profile.profile
      id:                    &lt;computed&gt;
      arn:                   &lt;computed&gt;
      create_date:           &lt;computed&gt;
      name:                  "TEST-AIM-profile-PROD-us-east-1"
      path:                  "/"
      role:                  "TEST-AIM-role-PROD-us-east-1"
      roles.#:               &lt;computed&gt;
      unique_id:             &lt;computed&gt;

  + module.aim.aws_iam_policy.policy
      id:                    &lt;computed&gt;
      arn:                   &lt;computed&gt;
      description:           "AIM TEST-AIM-policy-PROD-us-east-1 policy"
      name:                  "TEST-AIM-policy-PROD-us-east-1"
      path:                  "/"
      policy:                "{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Sid\": \"\",\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"rds:ListTagsForResource\",\n        \"rds:Describe*\",\n        \"logs:GetLogEvents\",\n        \"logs:DescribeLogStreams\",\n        \"elasticache:Describe*\",\n        \"ec2:DescribeVpcs\",\n        \"ec2:DescribeSecurityGroups\",\n        \"ec2:DescribeAvailabilityZones\",\n        \"ec2:DescribeAccountAttributes\",\n        \"cloudwatch:GetMetricStatistics\"\n      ],\n      \"Resource\": \"*\"\n    }\n  ]\n}"

  + module.aim.aws_iam_policy_attachment.iam_policy_attachment
      id:                    &lt;computed&gt;
      name:                  "TEST-AIM-iam_policy_attachment-PROD-us-east-1"
      policy_arn:            "${aws_iam_policy.policy.arn}"
      roles.#:               "1"
      roles.2598150538:      "TEST-AIM-role-PROD-us-east-1"

  + module.aim.aws_iam_role.role
      id:                    &lt;computed&gt;
      arn:                   &lt;computed&gt;
      assume_role_policy:    "{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Sid\": \"\",\n      \"Effect\": \"Allow\",\n      \"Action\": \"sts:AssumeRole\",\n      \"Principal\": {\n        \"Service\": \"ec2.amazonaws.com\"\n      }\n    }\n  ]\n}"
      create_date:           &lt;computed&gt;
      description:           "IMA TEST-AIM-role-PROD-us-east-1 role"
      force_detach_policies: "false"
      name:                  "TEST-AIM-role-PROD-us-east-1"
      path:                  "/"
      unique_id:             &lt;computed&gt;


Plan: 4 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

Мне вывело что все у меня хорошо и можно запускать деплой:

$ terraform apply

Вывод будет:

data.aws_iam_policy_document.role-policy-document: Refreshing state...
data.aws_iam_policy_document.policy-document: Refreshing state...

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  + module.aim.aws_iam_instance_profile.profile
      id:                    &lt;computed&gt;
      arn:                   &lt;computed&gt;
      create_date:           &lt;computed&gt;
      name:                  "TEST-AIM-profile-PROD-us-east-1"
      path:                  "/"
      role:                  "TEST-AIM-role-PROD-us-east-1"
      roles.#:               &lt;computed&gt;
      unique_id:             &lt;computed&gt;

  + module.aim.aws_iam_policy.policy
      id:                    &lt;computed&gt;
      arn:                   &lt;computed&gt;
      description:           "AIM TEST-AIM-policy-PROD-us-east-1 policy"
      name:                  "TEST-AIM-policy-PROD-us-east-1"
      path:                  "/"
      policy:                "{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Sid\": \"\",\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"rds:ListTagsForResource\",\n        \"rds:Describe*\",\n        \"logs:GetLogEvents\",\n        \"logs:DescribeLogStreams\",\n        \"elasticache:Describe*\",\n        \"ec2:DescribeVpcs\",\n        \"ec2:DescribeSecurityGroups\",\n        \"ec2:DescribeAvailabilityZones\",\n        \"ec2:DescribeAccountAttributes\",\n        \"cloudwatch:GetMetricStatistics\"\n      ],\n      \"Resource\": \"*\"\n    }\n  ]\n}"

  + module.aim.aws_iam_policy_attachment.iam_policy_attachment
      id:                    &lt;computed&gt;
      name:                  "TEST-AIM-iam_policy_attachment-PROD-us-east-1"
      policy_arn:            "${aws_iam_policy.policy.arn}"
      roles.#:               "1"
      roles.2598150538:      "TEST-AIM-role-PROD-us-east-1"

  + module.aim.aws_iam_role.role
      id:                    &lt;computed&gt;
      arn:                   &lt;computed&gt;
      assume_role_policy:    "{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Sid\": \"\",\n      \"Effect\": \"Allow\",\n      \"Action\": \"sts:AssumeRole\",\n      \"Principal\": {\n        \"Service\": \"ec2.amazonaws.com\"\n      }\n    }\n  ]\n}"
      create_date:           &lt;computed&gt;
      description:           "IMA TEST-AIM-role-PROD-us-east-1 role"
      force_detach_policies: "false"
      name:                  "TEST-AIM-role-PROD-us-east-1"
      path:                  "/"
      unique_id:             &lt;computed&gt;


Plan: 4 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

module.aim.aws_iam_policy.policy: Creating...
  arn:         "" =&gt; "&lt;computed&gt;"
  description: "" =&gt; "AIM TEST-AIM-policy-PROD-us-east-1 policy"
  name:        "" =&gt; "TEST-AIM-policy-PROD-us-east-1"
  path:        "" =&gt; "/"
  policy:      "" =&gt; "{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Sid\": \"\",\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"rds:ListTagsForResource\",\n        \"rds:Describe*\",\n        \"logs:GetLogEvents\",\n        \"logs:DescribeLogStreams\",\n        \"elasticache:Describe*\",\n        \"ec2:DescribeVpcs\",\n        \"ec2:DescribeSecurityGroups\",\n        \"ec2:DescribeAvailabilityZones\",\n        \"ec2:DescribeAccountAttributes\",\n        \"cloudwatch:GetMetricStatistics\"\n      ],\n      \"Resource\": \"*\"\n    }\n  ]\n}"
module.aim.aws_iam_role.role: Creating...
  arn:                   "" =&gt; "&lt;computed&gt;"
  assume_role_policy:    "" =&gt; "{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Sid\": \"\",\n      \"Effect\": \"Allow\",\n      \"Action\": \"sts:AssumeRole\",\n      \"Principal\": {\n        \"Service\": \"ec2.amazonaws.com\"\n      }\n    }\n  ]\n}"
  create_date:           "" =&gt; "&lt;computed&gt;"
  description:           "" =&gt; "IMA TEST-AIM-role-PROD-us-east-1 role"
  force_detach_policies: "" =&gt; "false"
  name:                  "" =&gt; "TEST-AIM-role-PROD-us-east-1"
  path:                  "" =&gt; "/"
  unique_id:             "" =&gt; "&lt;computed&gt;"
module.aim.aws_iam_policy.policy: Creation complete after 1s (ID: arn:aws:iam::316963130188:policy/TEST-AIM-policy-PROD-us-east-1)
module.aim.aws_iam_role.role: Creation complete after 1s (ID: TEST-AIM-role-PROD-us-east-1)
module.aim.aws_iam_instance_profile.profile: Creating...
  arn:         "" =&gt; "&lt;computed&gt;"
  create_date: "" =&gt; "&lt;computed&gt;"
  name:        "" =&gt; "TEST-AIM-profile-PROD-us-east-1"
  path:        "" =&gt; "/"
  role:        "" =&gt; "TEST-AIM-role-PROD-us-east-1"
  roles.#:     "" =&gt; "&lt;computed&gt;"
  unique_id:   "" =&gt; "&lt;computed&gt;"
module.aim.aws_iam_policy_attachment.iam_policy_attachment: Creating...
  name:             "" =&gt; "TEST-AIM-iam_policy_attachment-PROD-us-east-1"
  policy_arn:       "" =&gt; "arn:aws:iam::316963130188:policy/TEST-AIM-policy-PROD-us-east-1"
  roles.#:          "" =&gt; "1"
  roles.2598150538: "" =&gt; "TEST-AIM-role-PROD-us-east-1"
module.aim.aws_iam_instance_profile.profile: Creation complete after 2s (ID: TEST-AIM-profile-PROD-us-east-1)
module.aim.aws_iam_policy_attachment.iam_policy_attachment: Creation complete after 3s (ID: TEST-AIM-iam_policy_attachment-PROD-us-east-1)

Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

Как видно с вывода, — все прошло гладко! Чтобы удалить созданное творение, можно выполнить:

$ terraform destroy

Вот и все на этом. Данная статья «Работа с AWS IAM и Terraform в Unix/Linux» завершена.


Установка libnotify в Unix/Linux

$
0
0

Установка libnotify в Unix/Linux

Команда notify-send позволяет отправлять уведомления пользователю. Очень прикольная утилита и сейчас я расскажу как ее использовать.

Полезное чтиво:

Установка GUI на Arch Linux

Установка GUI на Debian/Ubuntu/Mint

Установка GUI на RedHat/CentOS/Fedora

Установка libnotify в Debian/Ubuntu

Вам необходимо установить следующий пакет на Debian/Ubuntu Linux с помощью apt-get команды:

$ sudo apt-get install libnotify-bin

Установка libnotify в CentOS/RedHat

Вам необходимо установить следующий пакет на CentOS/RHEL с помощью yum команды:

# yum install libnotify -y

Установка libnotify в Fedora

Вам необходимо установить следующий пакет на Fedora с помощью dnf команды:

$ sudo dnf install libnotify

Установка libnotify в Arch Linux

Для установки libnotify выполните команду:

# pacman -S libnotify

Установка libnotify в MacOS X

Первое что нужно сделать, — установить homebrew и потом, выполнить поиск пакета:

$ brew search libnotify

Для установки, выполните:

$ brew install libnotify

Использование libnotify в Unix/Linux

Приведу пример, если выполнить в коммандной строке следующее:

$ notify-send "Test notifi-send command"

Получаем следующее:

Использование notify-send

Вот еще пример:

$ notify-send --urgency normal --expire-time=10000 -i typing-monitor -h int:x:500 -h int:y:500 "Пора сделать перерыв" "Глазам нужен отдых"

Данный пример, довольно полезен и можно добавить в крон на 45 или 60 минут.

Хотя на MacOS X имеется данный пакет, я не смог запустить такое сообщение на данной ОС. Исправить можно следующим образом, — поставить другой пакет:

$ brew install terminal-notifier

И пример:

$ echo 'Piped Message Data!' | terminal-notifier -sound default

Для получения дополнительной информации об использовании утилиты notify-send, смотрим помощь:

$ man notify-send

А на этом, у меня все. Статья «Установка libnotify в Unix/Linux» завершена.

Исправляем ошибку «PolicyKit failing to start with error: polkit.service: main process exited, code=exited, status=1/FAILURE»

$
0
0

Исправляем ошибку «PolicyKit failing to start with error: polkit.service: main process exited, code=exited, status=1/FAILURE»

При работе с zabbix на CentOS 7, получил ошибку:

PolicyKit failing to start with error: polkit.service: main process exited, code=exited, status=1/FAILURE

Можете получить, что-то типа:

dbus-daemon: dbus[996]: [system] Activating via systemd: service name='org.freedesktop.PolicyKit1' unit='polkit.service'
dbus[996]: [system] Activating via systemd: service name='org.freedesktop.PolicyKit1' unit='polkit.service'
systemd: Starting Authorization Manager...
systemd: polkit.service: main process exited, code=exited, status=1/FAILURE
systemd: Failed to start Authorization Manager.
systemd: Unit polkit.service entered failed state.
dbus-daemon: dbus[996]: [system] Failed to activate service 'org.freedesktop.PolicyKit1': timed out
dbus[996]: [system] Failed to activate service 'org.freedesktop.PolicyKit1': timed out

Исправление данной ошибки следующее:

Убедитесь, что пользователь и группа присутствует в polkitd. Скопируйте/вставьте следующие 2 составные команды в терминал, чтобы проверить и условно создать пользователя/группу:

$ getent group polkitd >/dev/null && echo -e "\e[1;32mpolkitd group already exists\e[0m" || { groupadd -r polkitd && echo -e "\e[1;33mAdded missing polkitd group\e[0m" || echo -e "\e[1;31mAdding polkitd group FAILED\e[0m"; }
getent passwd polkitd >/dev/null && echo -e "\e[1;32mpolkitd user already exists\e[0m" || { useradd -r -g polkitd -d / -s /sbin/nologin -c "User for polkitd" polkitd && echo -e "\e[1;33mAdded missing polkitd user\e[0m" || echo -e "\e[1;31mAdding polkitd user FAILED\e[0m"; }

Сбросьте пермишены и права пользователя/группы для всех файлов, предоставленных пакетами polkit и polkit-pkla-compat. Скопируйте/вставьте следующую составную команду в терминал, чтобы проверить и условно сбросить пользователя/группу (perms & ownership):

$ rpm -Va polkit\* && echo -e "\e[1;32mpolkit* rpm verification passed\e[0m" || { echo -e "\e[1;33mResetting polkit* rpm user/group ownership & perms\e[0m"; rpm --setugids polkit polkit-pkla-compat; rpm --setperms polkit polkit-pkla-compat; }

Выполните ребут. Необходимо перезагрузить машину, чтобы убедиться, что все изменения вступят в силу и что polkit подключился к шине dbus:

# shutdown -r now

PS: У меня без ребута все норм стало, но ребут позволит убедится что все норм после перезагрузки ОС!

Вот и все, статья «Исправляем ошибку «PolicyKit failing to start with error: polkit.service: main process exited, code=exited, status=1/FAILURE»» завершена.

Работа с AWS VPC и Terraform в Unix/Linux

$
0
0

Работа с AWS VPC и Terraform в Unix/Linux

Amazon Virtual Private Cloud (Amazon VPC) – это логически изолированный раздел облака AWS, в котором можно запускать ресурсы AWS в созданной пользователем виртуальной сети. Пользователь полностью контролирует свою среду виртуальной сети, в том числе может выбирать собственный диапазон IP-адресов, создавать подсети, а также настраивать таблицы маршрутизации и сетевые шлюзы. Для обеспечения удобного и безопасного доступа к ресурсам и приложениям в VPC можно использовать как IPv4, так и IPv6.
Сетевую конфигурацию Amazon VPC можно легко настроить по своему усмотрению. Например, для веб-серверов можно создать публичную подсеть с выходом в Интернет, а внутренние системы, такие как базы данных или серверы приложений, расположить в частной подсети без доступа к Интернету. Можно использовать многоуровневую систему безопасности, состоящую из групп безопасности и сетевых списков контроля доступа (NACL), чтобы контролировать доступ к инстансам Amazon EC2 в каждой подсети.

Кроме того, можно создать подключение между корпоративным центром обработки данных и VPC с помощью аппаратной частной виртуальной сети (VPN) и использовать облако AWS для расширения возможностей корпоративного ЦОД.

Установка terraform в Unix/Linux

Установка крайне примитивная и я описал как это можно сделать тут:

Установка terraform в Unix/Linux

Так же, в данной статье, я создал скрипт для автоматической установки данного ПО. Он был протестирован на CentOS 6/7, Debian 8 и на Mac OS X. Все работает должным образом!

Чтобы получить помощь по использованию команд, выполните:

$ terraform
Usage: terraform [--version] [--help] <command> [args]

The available commands for execution are listed below.
The most common, useful commands are shown first, followed by
less common or more advanced commands. If you're just getting
started with Terraform, stick with the common commands. For the
other commands, please read the help and docs before usage.

Common commands:
    apply              Builds or changes infrastructure
    console            Interactive console for Terraform interpolations
    destroy            Destroy Terraform-managed infrastructure
    env                Workspace management
    fmt                Rewrites config files to canonical format
    get                Download and install modules for the configuration
    graph              Create a visual graph of Terraform resources
    import             Import existing infrastructure into Terraform
    init               Initialize a Terraform working directory
    output             Read an output from a state file
    plan               Generate and show an execution plan
    providers          Prints a tree of the providers used in the configuration
    push               Upload this Terraform module to Atlas to run
    refresh            Update local state file against real resources
    show               Inspect Terraform state or plan
    taint              Manually mark a resource for recreation
    untaint            Manually unmark a resource as tainted
    validate           Validates the Terraform files
    version            Prints the Terraform version
    workspace          Workspace management

All other commands:
    debug              Debug output management (experimental)
    force-unlock       Manually unlock the terraform state
    state              Advanced state management

Приступим к использованию!

Работа с AWS VPC и Terraform в Unix/Linux

AWS VPC — виртуальное частное облако, которое в основном обеспечивает способ структурирования вашей собственной сети так, как вы хотите. Прежде чем погрузиться, давайте определим некоторые базовые концепции VPC:

  • CIDR – Classless Intern-Domain Routing, определяет диапазон адресов, который будет представлять наш VPC .
  • Subnets — Подсети, я покажу как можно создать публичные, приватные сети, что будет означать, что общедоступная подсеть может быть доступна из Интернета и частные подсетей не могут быть доступны из Интернета.
  • Internet Gateway — Интернет-шлюз — это компонент VPC, который обеспечивает связь между вашим VPC и Интернетом.
  • Nat Gateway (Network Address Translation Gateway) — Сетевой шлюз перевода адресов используется, чтобы позволить экземплярам в частных подсетях подключаться к Интернету, но наоборот невозможно, например, это предотвратит запуск интернет-соединения с экземплярами в частных подсетях.
  • Route Table — В таблице маршрутов в основном содержатся правила относительно того, куда должны идти пакеты.
  • Elastic EIP — EIP будет ассоциироваться с NAT Gateway, поэтому в основном эластичный IP является статическим IP-адресом, связанным с вашей учетной записью AWS, например, вы можете использовать EIP для экземпляра с частным IP-адресом, чтобы экземпляр был доступен из Интернета.
  • Route Association Table — Служит для связи своих подсетей с указанными таблицами маршрутов, поэтому правила, определенные в этой таблице маршрутов, будут применяться к подсетям.

Terraform решает проблему взаимодействия с различными инфраструктурными сервисами (AWS, Digital Ocean, OpenStack и т. Д.) И предоставляет для нее унифицированный формат конфигурации.

Вот несколько важных моментов:

  • .tf  — Расширение для конфигурационных файлов, которые обеспечевают полную конфигурацию. Это дает удобный способ разбить конфигурацию на тематические разделы (Например: vpc, iam, ec2 и тд и тп. Пример для AWS провайдера).
  • .tfstate — Содержит последнее известное состояние инфраструктуры. А так же, «.tfstate.backup «служит для его бэкапа.
  • .tfvars — Содержат значения для объявленных переменных, обычно называемых: terraform.tfvars.

Чтобы записать все имеющиеся переменные в файл, используем:

$ terraform plan -var-file terraform.tfvars

Чтобы запустить инфраструктуру с созданными переменными, запустим:

$ terraform apply -var-file terraform.tfvars

И чтобы удалить, запустим:

$ terraform destroy -var-file terraform.tfvars

Существует два способа настройки групп безопасности AWS в Terraform. Вы можете определить правила, связанные с ресурсом aws_security_group, или вы можете определить дополнительные дискретные ресурсы aws_security_group_rule.

Мой первый инстинкт заключался в том, чтобы определить «базовую» группу безопасности, используя встроенные правила, а затем расширить ее с помощью внешних правил. Плохая идея. Об этом позже.

Однако для двух действительных вариантов есть важные последствия, и я обнаружил, что они не были ясны на момент написания (около Terraform v0.9.11). После небольшого исследования и экспериментов у меня появилось гораздо больше пониманий.

Создание VPC с помощью terraform

Давайте создадим VPC, например:

#---------------------------------------------------
# Create VPC
#---------------------------------------------------
resource "aws_vpc" "aws_vpc" {
    cidr_block                          = "${var.vpc_cidr}"
    instance_tenancy                    = "default"
    enable_dns_support                  = "true"
    enable_dns_hostnames                = "true"
    assign_generated_ipv6_cidr_block    = "false"
    enable_classiclink                  = "false"
    tags {
        Name            = "my-vpc"
    }
}

И так, чтоже я тут написал:

  • resources — Представляет собой нотацию Terraform для создания ресурсов.
  • aws_vpc —  Терраформ «функция» которая позволяет работать с AWS VPC. В данном случае служит для создания нового VPC.
  • aws_vpc — это имя, присвоенное VPC, к которому можно будет обратится, чтобы получить такую вещь, как vpc_id или main_route_table_id.
  • cidr_block — Диапазон адресов для VPC.
  • instance_tenancy — Если указать «default», то ваш экземпляр будет работать на общем оборудовании. Если указать «dedicated», то ваш экземпляр будет работать на однопользовательском оборудовании.
  • Если указать «host», то ваш экземпляр будет работать на выделенном хосте, который является изолированным сервером с конфигурациями, которые вы можете контролировать.
  • enable_dns_support —  Если установлено значение true, будет включена поддержка DNS для VPC, поэтому это укажет на то, что DNS будет поддерживаться для VPC.
  • enable_dns_hostname — Указывает, будут ли экземпляры, запущенные в VPC, получить имена хостов DNS.
  • assign_generated_ipv6_cidr_block — Сгенерировать ipv6 для VPC.
  • enable_classiclink — Позволяет связать ваш экземпляр EC2-Classic с VPC в вашей учетной записи в том же регионе.
  • tags — Теги полезны, если вы хотите классифицировать свои ресурсы.

Создание security group с помощью terraform

Вот как выглядит определение встроенной группы безопасности:

resource "aws_security_group" "allow_all" {
  name        = "allow_all"
  description = "Allow all inbound traffic"

  ingress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    from_port           = 0
    to_port             = 0
    protocol            = "-1"
    ipv6_cidr_blocks    = ["::/0"]
  }    
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
  egress {
      from_port           = 0
      to_port             = 0
      protocol            = "-1"
      ipv6_cidr_blocks    = ["::/0"]
    }

}

В примере что выше, есть два правила: правило для входящего (ingress) и исходящего (egress) соединения, определенное внутри блока ресурсов aws_security_group.

Расмотрим что тут написано более подробно:

  • resource — Представляет собой нотацию Terraform для создания ресурсов.
  • aws_security_group — Так званая функция, которая позволяет работать с SG и управлять ими через terraform.
  • allow_all — Название  (так званый алиас) для  aws_security_group функции. Служит для полуение дополнительной информации.
  • name — Используется для имени SG.
  • description — Просто описание данного блока.
  • ingress/egress — Входящее/Исходящее соединение для указанных портов.
  • from_port — Входящее/Исходящее соединение для указанного порта с хоста.
  • to_port — Входящее/Исходящее соединение для указанного порта на хоста.
  • protocol — Указываем протокол которые будет использоваться для входящего/исходящего соединения.
  • cidr_blocks — Диапазон адресов для SG.

Вот как одна и та же идея может быть выражена с использованием внешних правил через ресурс aws_security_group_rule:

resource "aws_security_group" "allow_all" {
  name        = "allow_all"
  description = "Allow all inbound traffic"
}

resource "aws_security_group_rule" "ingress_ipv4" {
  type        = "ingress"
  from_port   = 0
  to_port     = 0
  protocol    = -1
  cidr_blocks = ["0.0.0.0/0"]

  security_group_id = "${aws_security_group.allow_all.id}"
}
resource "aws_security_group_rule" "ingress_ipv6" {
  type                = "ingress"
  from_port           = 0
  to_port             = 0
  protocol            = -1
  ipv6_cidr_blocks    = ["::/0"]

  security_group_id = "${aws_security_group.allow_all.id}"
}
resource "aws_security_group_rule" "egress_ipv4" {
  type        = "egress"
  from_port   = 0
  to_port     = 0
  protocol    = -1
  cidr_blocks = ["0.0.0.0/0"]

  security_group_id = "${aws_security_group.allow_all.id}"
}
resource "aws_security_group_rule" "egress_ipv6" {
  type                = "egress"
  from_port           = 0
  to_port             = 0
  protocol            = -1
  ipv6_cidr_blocks    = ["::/0"]

  security_group_id = "${aws_security_group.allow_all.id}"
}

Группа безопасности и каждое ее правило определяются как дискретный ресурс и тесно связанные друг с другом через security_group_id атрибут. Для каждого порта прописывать правила — нормально и можно, но если у вам имеется 10 портов, — это уже не прикольно! По этому, делаем следующее:

variable "allowed_ports" {
    description = "Allowed ports from/to host"
    type        = "list"
    default     = ["80", "443", "8080", "8443"]
}
#---------------------------------------------------
# Create security group
#---------------------------------------------------
resource "aws_security_group" "aws_security_group" {
    name        = "aws_security_group"
    description = "Security Group aws_security_group"
    lifecycle {
        create_before_destroy = true
    }
    # allow traffic for TCP 22
    ingress {
        from_port   = 22
        to_port     = 22
        protocol    = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
    }
    # allow traffic from  TCP 22
    egress {
        from_port   = 22
        to_port     = 22
        protocol    = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
    }
}
#---------------------------------------------------
# Add security group rules (one more way)
#---------------------------------------------------
resource "aws_security_group_rule" "ingress_ports" {
    type                = "ingress"
    count               = "${length(var.allowed_ports)}"
    security_group_id   = "${aws_security_group.aws_security_group.id}"
    from_port           = "${element(var.allowed_ports, count.index)}"
    to_port             = "${element(var.allowed_ports, count.index)}"
    protocol            = "tcp"
    cidr_blocks         = ["0.0.0.0/0"]
}
resource "aws_security_group_rule" "egress_ports" {
    type                = "egress"
    count               = "${length(var.allowed_ports)}"
    security_group_id   = "${aws_security_group.aws_security_group.id}"
    from_port           = "${element(var.allowed_ports, count.index)}"
    to_port             = "${element(var.allowed_ports, count.index)}"
    protocol            = "tcp"
    cidr_blocks         = ["0.0.0.0/0"]
}

PS: Я на данном этапе, не выношу переменные в отдельный файл. В самом конце этой темы, я приведу полную конфигурацию всех файлов….

Создание private network с помощью terraform

Создадим приватную сеть:

#---------------------------------------------------
# Add AWS subnet (private)
#---------------------------------------------------
resource "aws_subnet" "aws_subnet_private" {
    cidr_block              = "172.31.64.0/20"
    vpc_id                  = "${aws_vpc.aws_vpc.id}"
    map_public_ip_on_launch = "false"
    availability_zone       = "us-east-1a"
    tags {
        Name            = "aws_subnet_private"
    }
}

Расмотрим что тут имеется:

  • resource — Представляет собой нотацию Terraform для создания ресурсов.
  • aws_subnet — Так званая функция, которая позволяет работать с subnet и управлять ими через terraform.
  • aws_subnet_private — Название  (так званый алиас) для  aws_subnet функции. Служит для полуение дополнительной информации.
  • cidr_block — Диапазон адресов.
  • vpc_id — Идентификационный номер созданной VPC.
  • map_public_ip_on_launch — (Необязательно) Укажите true, чтобы указать, что экземплярам, запущенным в подсети, должен быть присвоен общедоступный IP-адрес. Значение по умолчанию — false.
  • availability_zone — Зона (регион) для разварацивания subnet-а.
  • tags — Теги полезны, если вы хотите классифицировать свои ресурсы.

Идем дальше….

Создание public network с помощью terraform

Создадим публичную сеть:

#---------------------------------------------------
# Add AWS subnet (public)
#---------------------------------------------------
resource "aws_subnet" "aws_subnet_public" {
    cidr_block              = "172.31.80.0/20"
    vpc_id                  = "${aws_vpc.aws_vpc.id}"
    map_public_ip_on_launch = "false"
    availability_zone       = "us-east-1a"
    tags {
        Name            = "aws_subnet_public"
    }
}

Расмотрим что тут имеется:

  • resource — Представляет собой нотацию Terraform для создания ресурсов.
  • aws_subnet — Так званая функция, которая позволяет работать с subnet и управлять ими через terraform.
  • aws_subnet_public — Название  (так званый алиас) для  aws_subnet функции. Служит для полуение дополнительной информации.
  • cidr_block — Диапазон адресов.
  • vpc_id — Идентификационный номер созданной VPC.
  • map_public_ip_on_launch — (Необязательно) Укажите true, чтобы указать, что экземплярам, запущенным в подсети, должен быть присвоен общедоступный IP-адрес. Значение по умолчанию — false.
  • availability_zone — Зона (регион) для разварацивания subnet-а.
  • tags — Теги полезны, если вы хотите классифицировать свои ресурсы.

Продолжаем….

Создание internet gateway с помощью terraform

Так же, создам интернет гетвей:

#---------------------------------------------------
# Add AWS internet gateway
#---------------------------------------------------
resource "aws_internet_gateway" "aws_internet_gateway" {
    vpc_id = "${aws_vpc.aws_vpc.id}"
    tags {
        Name            = "internet-gateway"
    }
}

Где:

  • aws_internet_gateway: Обозначение Terraform для создания ресурса интернет-шлюза в AWS.

Создание route для internet с помощью terraform

Следующим щагом будет создание роута для интернета:

resource "aws_route_table" "aws_route_table" {
    vpc_id = "${aws_vpc.aws_vpc.id}"
    route {
        cidr_block = "0.0.0.0/0"
        gateway_id = "${aws_internet_gateway.aws_internet_gateway.id}"
    }
    tags {
        Name            = "aws_internet_gateway-default"
        Environment     = "${var.environment}"
        Orchestration   = "${var.orchestration}"
        Createdby       = "${var.createdby}"
    }
}
resource "aws_route_table_association" "aws_route_table_association" {
    subnet_id       = "${aws_subnet.aws_subnet_private.id}"
    route_table_id  = "${aws_route_table.aws_route_table.id}"
}

Или, можно еще сделать следующее:

resource "aws_route" "internet_access" {
  route_table_id         = "${aws_vpc.aws_vpc.main_route_table_id}"
  destination_cidr_block = "0.0.0.0/0"
  gateway_id             = "${aws_internet_gateway.aws_internet_gateway.id}"
}

Где:

  • aws_route — Обозначение Terraform для создания Route ресурса в AWS.
  • internet_access — Название, присвоенное маршруту (route)
  • route_table_id — Идентификатор таблицы маршрута, который содержит правила, указывающие, как должны быть маршрутизированы пакеты, мы назначим основной идентификатор таблицы маршрутизации vpc, в AWS, когда вы создали VPC, у вас будет таблица основных маршрутов по умолчанию.
  • destination_cidr_block — Диапазон адресов.
  • gateway_id — Идентификатор шлюза, где все пакеты в Интернете должны быть маршрутизированы, если вы помните, что интернет-шлюз позволяет VPC взаимодействовать с Интернетом.

Создание  Elastic IP (EIP) с помощью terraform

Мы создадим этот IP-адрес, чтобы назначить ему NAT-шлюз:

#---------------------------------------------------
# CREATE EIP
#---------------------------------------------------
resource "aws_eip" "aws_eip" {
    vpc         = true
    depends_on = ["aws_internet_gateway.aws_internet_gateway"]
}

Пояснения:

  • aws_eip — Обозначение Terraform для создания ресурса EIP в AWS.
  • aws_eip — Имя, присвоенное ресурсу EIP.
  • vpc — Если значение true, то EIP присвоится к VPC.
  • depend_on — Условная переменная, которая говорит, что в этом случае ресурс EIP должен быть создан только после того, как Интернет-шлюз уже создан.

Создание  NAT Gateway с помощью terraform

Убедитесь, что вы создали nat в подсети, подключенной к Интернету (общедоступная подсетьб — public network):

#---------------------------------------------------
# CREATE NAT
#---------------------------------------------------
resource "aws_nat_gateway" "aws_nat_gateway" {
    allocation_id = "${aws_eip.aws_eip.id}"
    subnet_id = "${aws_subnet.aws_subnet_public.id}"
    depends_on = ["aws_internet_gateway.aws_internet_gateway"]
}

Где:

  • aws_nat_gateway — Обозначение Terraform для создания ресурса NAT Gateway в AWS.
  • aws_nat_gateway — Имя, присвоенное ресурсу NAT.
  • allocation_id — NAT должен иметь EIP-адрес (статический IP-адрес).
  • subnet_id — Идентификатор подсети, в котором будет создан ресурс NAT.

Создание private route table и the route to the internet с помощью terraform

Это позволит всем трафику из частных подсетей (privat network) ходить в интернет через NAT-шлюз (трансляция сетевых адресов, — NAT):

#---------------------------------------------------
# Create private route table and the route to the internet
#---------------------------------------------------
resource "aws_route_table" "aws_route_table" {
    vpc_id = "${aws_vpc.aws_vpc.id}"
    route {
        cidr_block = "0.0.0.0/0"
        gateway_id = "${aws_internet_gateway.aws_internet_gateway.id}"
    }
    tags {
        Name            = "aws_internet_gateway-default"
        Environment     = "${var.environment}"
        Orchestration   = "${var.orchestration}"
        Createdby       = "${var.createdby}"
    }
}

Создание Route Table Associations с помощью terraform

Теперь свяжем подсети с разными таблицами маршрутов:

#---------------------------------------------------
# Route Table Associations
#---------------------------------------------------
# private
resource "aws_route_table_association" "aws_route_table_association_private" {
    subnet_id       = "${aws_subnet.aws_subnet_private.id}"
    route_table_id  = "${aws_route_table.aws_route_table_private.id}"
}
# public
resource "aws_route_table_association" "aws_route_table_association_public" {
    subnet_id = "${aws_subnet.aws_subnet_public.id}"
    route_table_id = "${aws_vpc.aws_vpc.main_route_table_id}"
}

Это я привел некоторые примеры по использованию. Я придерживаюсь того, чтобы все и всегда сортировать (стараюсь так делать), т.е придерживатся так званого стандарта (который придумываю я сам для своих нужд), по этому я расскажу как я делаю.

У меня есть папка terraform, в ней у меня будут лежать провайдеры с которыми я буду работать. Т.к в этом примере я буду использовать AWS, то создам данную папку и перейду в нее. Далее, в этой папке, стоит создать:

$ mkdir examples modules

В папке examples, я буду хранить так званые «плейбуки» для разварачивания различных служб, например — zabbix-server, grafana, web-серверы и так далее. В modules директории, я буду хранить все необходимые модули.

Начнем писать модуль, но для этой задачи, я создам папку:

$  mkir modules/vpc

Переходим в нее:

$ cd modules/vpc

Открываем файл:

$ vim vpc.tf

В данный файл, вставляем:

#---------------------------------------------------
# Create VPC
#---------------------------------------------------
resource "aws_vpc" "aws_vpc" {
    cidr_block                          = "${var.vpc_cidr}"
    instance_tenancy                    = "${var.instance_tenancy}"
    enable_dns_support                  = "${var.enable_dns_support}"
    enable_dns_hostnames                = "${var.enable_dns_hostnames}"
    assign_generated_ipv6_cidr_block    = "${var.assign_generated_ipv6_cidr_block}"
    enable_classiclink                  = "${var.enable_classiclink}"
    tags {
        Name            = "${var.name}-vpc-${var.environment}"
        Environment     = "${var.environment}"
        Orchestration   = "${var.orchestration}"
        Createdby       = "${var.createdby}"
    }
}
#---------------------------------------------------
# Create security group
#---------------------------------------------------
resource "aws_security_group" "aws_security_group" {
    name                = "${var.name}-sg-${var.environment}"
    description         = "Security Group ${var.name}-${var.environment}"
    vpc_id              = "${aws_vpc.aws_vpc.id}"
    tags {
        Name            = "${var.name}-sg-${var.environment}"
        Environment     = "${var.environment}"
        Orchestration   = "${var.orchestration}"
        Createdby       = "${var.createdby}"
    }
    lifecycle {
        create_before_destroy = true
    }
    # allow traffic for TCP 22 to host
    ingress {
        from_port   = 22
        to_port     = 22
        protocol    = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
    }
    # allow traffic for TCP 22 from host
    egress {
        from_port   = 22
        to_port     = 22
        protocol    = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
    }
}
#---------------------------------------------------
# Add security group rules (one more way)
#---------------------------------------------------
resource "aws_security_group_rule" "ingress_ports" {
    type                = "ingress"
    count               = "${length(var.allowed_ports)}"
    security_group_id   = "${aws_security_group.aws_security_group.id}"
    from_port           = "${element(var.allowed_ports, count.index)}"
    to_port             = "${element(var.allowed_ports, count.index)}"
    protocol            = "tcp"
    cidr_blocks         = ["0.0.0.0/0"]
}
resource "aws_security_group_rule" "egress_ports" {
    type                = "egress"
    count               = "${length(var.allowed_ports)}"
    security_group_id   = "${aws_security_group.aws_security_group.id}"
    from_port           = "${element(var.allowed_ports, count.index)}"
    to_port             = "${element(var.allowed_ports, count.index)}"
    protocol            = "tcp"
    cidr_blocks         = ["0.0.0.0/0"]
}
#---------------------------------------------------
# Add AWS subnet (private)
#---------------------------------------------------
resource "aws_subnet" "aws_subnet_private" {
    count                   = "${length(var.private_subnet_cidr)}"
    cidr_block              = "${element(var.private_subnet_cidr, count.index)}"
    vpc_id                  = "${aws_vpc.aws_vpc.id}"
    map_public_ip_on_launch = "false"
    count                   = "${length(var.availability_zone)}"
    availability_zone       = "${element(var.availability_zone, count.index)}"
    tags {
        Name            = "aws_subnet_private"
        Environment     = "${var.environment}"
        Orchestration   = "${var.orchestration}"
        Createdby       = "${var.createdby}"
    }
}
#---------------------------------------------------
# Add AWS subnet (public)
#---------------------------------------------------
resource "aws_subnet" "aws_subnet_public" {
    count                   = "${length(var.public_subnet_cidr)}"
    cidr_block              = "${element(var.public_subnet_cidr, count.index)}"
    vpc_id                  = "${aws_vpc.aws_vpc.id}"
    map_public_ip_on_launch = "true"
    count                   = "${length(var.availability_zone)}"
    availability_zone       = "${element(var.availability_zone, count.index)}"
    tags {
        Name            = "aws_subnet_public"
        Environment     = "${var.environment}"
        Orchestration   = "${var.orchestration}"
        Createdby       = "${var.createdby}"
    }
}
#---------------------------------------------------
# Add AWS internet gateway
#---------------------------------------------------
resource "aws_internet_gateway" "aws_internet_gateway" {
    vpc_id = "${aws_vpc.aws_vpc.id}"
    tags {
        Name            = "internet-gateway to ${var.name}-vpc-${var.environment}"
        Environment     = "${var.environment}"
        Orchestration   = "${var.orchestration}"
        Createdby       = "${var.createdby}"
    }
}
resource "aws_route" "internet_access" {
    route_table_id         = "${aws_vpc.aws_vpc.main_route_table_id}"
    destination_cidr_block = "0.0.0.0/0"
    gateway_id             = "${aws_internet_gateway.aws_internet_gateway.id}"
}
#---------------------------------------------------
# CREATE EIP
#---------------------------------------------------
resource "aws_eip" "aws_eip" {
    vpc         = true
    depends_on = ["aws_internet_gateway.aws_internet_gateway"]
}
#---------------------------------------------------
# CREATE NAT
#---------------------------------------------------
resource "aws_nat_gateway" "aws_nat_gateway" {
    allocation_id = "${aws_eip.aws_eip.id}"
    subnet_id = "${aws_subnet.aws_subnet_public.id}"
    depends_on = ["aws_internet_gateway.aws_internet_gateway"]
}
#---------------------------------------------------
# Create private route table and the route to the internet
#---------------------------------------------------
resource "aws_route_table" "aws_route_table_private" {
    vpc_id = "${aws_vpc.aws_vpc.id}"
    #route {
    #    cidr_block = "0.0.0.0/0"
    #    gateway_id = "${aws_internet_gateway.aws_internet_gateway.id}"
    #}
    tags {
        Name            = "aws_internet_gateway-default"
        Environment     = "${var.environment}"
        Orchestration   = "${var.orchestration}"
        Createdby       = "${var.createdby}"
    }
}
resource "aws_route" "private_route" {
    route_table_id  = "${aws_route_table.aws_route_table_private.id}"
	destination_cidr_block = "0.0.0.0/0"
	nat_gateway_id = "${aws_nat_gateway.aws_nat_gateway.id}"
}
#---------------------------------------------------
# Route Table Associations
#---------------------------------------------------
# private
resource "aws_route_table_association" "aws_route_table_association_private" {
    subnet_id       = "${aws_subnet.aws_subnet_private.id}"
    route_table_id  = "${aws_route_table.aws_route_table_private.id}"
}
# public
resource "aws_route_table_association" "aws_route_table_association_public" {
    subnet_id = "${aws_subnet.aws_subnet_public.id}"
    route_table_id = "${aws_vpc.aws_vpc.main_route_table_id}"
}

Открываем файл:

$ vim variables.tf

И прописываем:

#-----------------------------------------------------------
# Global or/and default variables
#-----------------------------------------------------------
variable "name" {
  description = "Name to be used on all resources as prefix"
  default     = "TEST"
}
variable "instance_tenancy" {
    description = "instance tenancy"
    default     = "default"
}
variable "enable_dns_support" {
    description = "Enabling dns support"
    default     = "true"
}
variable "enable_dns_hostnames" {
    description = "Enabling dns hostnames"
    default     = "true"
}
variable "assign_generated_ipv6_cidr_block" {
    description = "Enabling dns hostnames"
    default     = "true"
}
variable "enable_classiclink" {
    description = "Enabling classiclink"
    default     = "false"
}
variable "environment" {
    description = "Environment for service"
    default     = "PROD"
}
variable "orchestration" {
    description = "Type of orchestration"
    default     = "Terraform"
}
variable "createdby" {
    description = "Created by"
    default     = "Vitaliy Natarov"
}
#---------------------------------------------------------------
# Custom variables
#---------------------------------------------------------------
variable "allowed_ports" {
  description = "Allowed ports from/to host"
  type        = "list"
}
variable "vpc_cidr" {
    description = "CIDR for the whole VPC"
    #type        = "list"
    #default     = []
}
variable "public_subnet_cidr" {
    description = "CIDR for the Public Subnet"
    type        = "list"
    default     = []
}
variable "private_subnet_cidr" {
    description = "CIDR for the Private Subnet"
    type        = "list"
    default     = []
}
variable "availability_zone" {
    description = "A list of Availability zones in the region"
    type        = "list"
    default     = []
}
#variable "enable_internet_gateway" {
#    description = "Allow Internet GateWay to/from public network"
#    default     = "false"
#}
#variable "enable_nat_gateway" {
#    description = "Allow Nat GateWay to/from private network"
#    default     = "false"
#}
#variable "enable_eip" {
#    description = "Allow creation elastic eip"
#    default     = "false"
#}

Собственно в этом файле храняться все переменные. Спасибо кэп!

Открываем последний файл:

$ vim outputs.tf

и в него вставить нужно следующие строки:

output "aws_security_group" {
  value = "${aws_security_group.aws_security_group.id}"
}
output "security_group_id" {
  value = "${aws_security_group.aws_security_group.id}"
}

output "vpc-id" {
    value = "${aws_vpc.aws_vpc.id}"
}

output "vpc-publicsubnet" {
    value = "${aws_subnet.aws_subnet_public.*.cidr_block}"
    #value = "${aws_subnet.aws_subnet_public.cidr_block}"
}

output "vpc-publicsubnet-id" {
    value = "${aws_subnet.aws_subnet_public.*.id}"
    #value = "${aws_subnet.aws_subnet_public.id}"
}

output "vpc-privatesubnet" {
    value   = "${aws_subnet.aws_subnet_private.*.cidr_block}"
    #value = "${aws_subnet.aws_subnet_private.cidr_block}"
}

output "vpc-privatesubnet-id" {
    value = "${aws_subnet.aws_subnet_private.*.id}"
    #value = "${aws_subnet.aws_subnet_private.id}"
}

Данный файл служит для того, чтобы выводить нужные значения на экран вашего экрана.

Переходим теперь в папку aws/examples и создадим еще одну папку для проверки написанного чуда:

$ mkdir vpc && cd $_

Внутри созданной папки открываем файл:

$ vim main.tf

И вставим в него следующий код:

#
# MAINTAINER Vitaliy Natarov "vitaliy.natarov@yahoo.com"
#
terraform {
  required_version = "> 0.9.0"
}
provider "aws" {
    region  = "us-east-1"
    # alias = "us-east-1"
    shared_credentials_file = "${pathexpand("~/.aws/credentials")}"
     # access_key = "${var.aws_access_key}"
     # secret_key = "${var.aws_secret_key}"
}

module "vpc" {
    source                              = "../../modules/vpc"
    name                                = "main"
    environment                         = "PROD"
    # VPC
    instance_tenancy                    = "dedicated"
    enable_dns_support                  = "true"
    enable_dns_hostnames                = "true"
    assign_generated_ipv6_cidr_block    = "false"
    enable_classiclink                  = "false"
    vpc_cidr                            = "172.31.0.0/16"
    private_subnet_cidr                 = ["172.31.64.0/20"]
    public_subnet_cidr                  = ["172.31.80.0/20"]
    availability_zone                   = ["us-east-1a", "us-east-1b"]
    allowed_ports                       = ["80", "3272", "8888", "8444"]
    #enable_internet_gateway             = "true"
    #enable_nat_gateway                  = "true"
    #enable_eip                          = "true"
}

В этом файле, имеется:

  • required_version = «> 0.9.0» — служит для указания версии ПО с которой будет работать ваш модуль.
  • provider — Собственно, — это провайдер с которым вы будете работать и разварачивать структуру. Сушествует довольно большое количество. В моем примере, используется AWS.
  • region — Представляет собой географическое местоположение aws, в котором будут созданы ваши ресурсы.
  • access_key — Ваш access_key будет использоваться Terraform для выполнения какой-либо задачи на вашей учетной записи AWS от вашего имени.
  • secret_key — Ваш secret_key, будет использоваться Terraform для выполнения какой-либо задачи на вашей учетной записи AWS от вашего имени.

Нашел прикольную фишку, можно прописать:

provider "aws" {
    region  = "us-east-1"
    alias = "us-east-1"
    shared_credentials_file = "${pathexpand("~/.aws/credentials")}"
}

Где:

  • region — Регион для разварачивания структуры.
  • alias — Алиас на данный (указанный) провайдер.
  • shared_credentials_file — Креды для подключения к AWS через терраформ.

И в своих модулях прописывать (например):

resource "aws_vpc" "us-east-1" {
    provider = "aws.us-east-1"
    enable_dns_support = true
    enable_dns_hostnames = true
    assign_generated_ipv6_cidr_block = true
    cidr_block = "10.0.0.0/16"
}

Тоже облегчает жизнь…. Идем дельше….

Все уже написано и готово к использованию. Ну что, начнем тестирование. В папке с вашим плейбуком, выполняем:

$ terraform init

Этим действием я инициализирую проект. Затем, подтягиваю модуль:

$ terraform get

PS: Для обновление изменений в самом модуле, можно выполнять:

$ terraform get -update

Запускем прогон:

$ terraform plan

ИЛИ:

$ terraform plan -out tera

Мне вывело что все у меня хорошо и можно запускать деплой:

$ terraform apply

Открываем AWS аккаунт и смотрим что вышло.

Созданная AWS VPC через terraform:

Созданная AWS VPC через terraform

Созданные подсети через терраформ:

Созданные подсети через терраформ

И так далее….

Чтобы визуализировать представление плана выполнения, запустите следующую команду:

$ terraform graph | dot -Tpng > graph.png

Данная команда сохранит вывод в PNG файл, чтобы просто посмотреть вывод, выполните:

$ terraform graph

Чтобы удалить созданное творение, можно выполнить:

$ terraform destroy

Вот и все на этом. Данная статья «Работа с AWS EC2 и Terraform в Unix/Linux» завершена.

Работа с AWS EC2 и Terraform в Unix/Linux

$
0
0

Работа с AWS EC2 и Terraform в Unix/Linux

Amazon Elastic Compute Cloud (Amazon EC2) – это веб-сервис, предоставляющий безопасные масштабируемые вычислительные ресурсы в облаке. Он помогает разработчикам, облегчая проведение крупномасштабных вычислений в облаке.

Простой веб-интерфейс сервиса Amazon EC2 позволяет получить доступ к вычислительным ресурсам и настроить их с минимальными трудозатратами. Он предоставляет пользователям полный контроль над ресурсами, которые они могут запускать в зарекомендовавшей себя вычислительной среде Amazon. Сокращая до нескольких минут процесс настройки и запуска новых инстансов серверов, сервис Amazon EC2 позволяет быстро масштабировать вычислительные ресурсы с учетом изменяющихся требований. Amazon EC2 меняет экономическую составляющую процесса вычислений, предоставляя возможность платить только за используемые ресурсы. Amazon EC2 позволяет разработчикам избегать распространенных ошибочных сценариев и создавать отказоустойчивые приложения.

Установка terraform в Unix/Linux

Установка крайне примитивная и я описал как это можно сделать тут:

Установка terraform в Unix/Linux

Так же, в данной статье, я создал скрипт для автоматической установки данного ПО. Он был протестирован на CentOS 6/7, Debian 8 и на Mac OS X. Все работает должным образом!

Чтобы получить помощь по использованию команд, выполните:

$ terraform
Usage: terraform [--version] [--help] <command> [args]

The available commands for execution are listed below.
The most common, useful commands are shown first, followed by
less common or more advanced commands. If you're just getting
started with Terraform, stick with the common commands. For the
other commands, please read the help and docs before usage.

Common commands:
    apply              Builds or changes infrastructure
    console            Interactive console for Terraform interpolations
    destroy            Destroy Terraform-managed infrastructure
    env                Workspace management
    fmt                Rewrites config files to canonical format
    get                Download and install modules for the configuration
    graph              Create a visual graph of Terraform resources
    import             Import existing infrastructure into Terraform
    init               Initialize a Terraform working directory
    output             Read an output from a state file
    plan               Generate and show an execution plan
    providers          Prints a tree of the providers used in the configuration
    push               Upload this Terraform module to Atlas to run
    refresh            Update local state file against real resources
    show               Inspect Terraform state or plan
    taint              Manually mark a resource for recreation
    untaint            Manually unmark a resource as tainted
    validate           Validates the Terraform files
    version            Prints the Terraform version
    workspace          Workspace management

All other commands:
    debug              Debug output management (experimental)
    force-unlock       Manually unlock the terraform state
    state              Advanced state management

Приступим к использованию!

Работа с AWS EC2 и Terraform в Unix/Linux

У меня есть папка terraform, в ней у меня будут лежать провайдеры с которыми я буду работать. Т.к в этом примере я буду использовать AWS, то создам данную папку и перейду в нее. Далее, в этой папке, стоит создать:

$ mkdir examples modules

В папке examples, я буду хранить так званые «плейбуки» для разварачивания различных служб, например — zabbix-server, grafana, web-серверы и так далее. В modules директории, я буду хранить все необходимые модули.

Начнем писать модуль, но для этой задачи, я создам папку:

$  mkir modules/ec2

Переходим в нее:

$ cd modules/ec2

Открываем файл:

$ vim ec2.tf

В данный файл, вставляем:

#---------------------------------------------------
# Define SSH key pair for our instances
#---------------------------------------------------
#
#
resource "aws_key_pair" "key_pair" {
  key_name = "${var.name}-key_pair"
  public_key = "${file("${var.key_path}")}"
}
#---------------------------------------------------
# Create AWS Instance
#---------------------------------------------------
resource "aws_instance" "instance" {
    count                       = "${var.number_of_instances}"

    ami                         = "${lookup(var.ami, var.region)}"
    instance_type               = "${var.ec2_instance_type}"
    #user_data                   = "${var.user_data}"
     #user_data                  = "${file("bootstrap.sh")}"
    key_name                    = "${var.key_name}"
    subnet_id                   = "${var.subnet_id}"
    vpc_security_group_ids      = ["${var.vpc_security_group_ids}"]
    monitoring                  = "${var.monitoring}"
    iam_instance_profile        = "${var.iam_instance_profile}"

    # Note: network_interface can't be specified together with associate_public_ip_address
    #network_interface           = "${var.network_interface}"
    associate_public_ip_address = "${var.enable_associate_public_ip_address}"
    private_ip                  = "${var.private_ip}"
    ipv6_address_count          = "${var.ipv6_address_count}"
    ipv6_addresses              = "${var.ipv6_addresses}"

    source_dest_check                    = "${var.source_dest_check}"
    disable_api_termination              = "${var.disable_api_termination}"
    instance_initiated_shutdown_behavior = "${var.instance_initiated_shutdown_behavior}"
    placement_group                      = "${var.placement_group}"
    tenancy                              = "${var.tenancy}"

    ebs_optimized          = "${var.ebs_optimized}"
    volume_tags            = "${var.volume_tags}"
    root_block_device {
        volume_size = "${var.disk_size}"
    #    volume_type = "gp2"
    }
    ebs_block_device       = "${var.ebs_block_device}"
    ephemeral_block_device = "${var.ephemeral_block_device}"

    lifecycle {
        create_before_destroy = true
        # Due to several known issues in Terraform AWS provider related to arguments of aws_instance:
        # (eg, https://github.com/terraform-providers/terraform-provider-aws/issues/2036)
        # we have to ignore changes in the following arguments
        ignore_changes = ["private_ip", "vpc_security_group_ids", "root_block_device"]
    }
    tags {
        Name            = "${lower(var.name)}-ec2-${lower(var.environment)}-${count.index+1}"
        Environment     = "${var.environment}"
        Orchestration   = "${var.orchestration}"
        Createdby       = "${var.createdby}"
    }
    ##############################################
    # Provisioning
    #############################################
    #user_data                   = "${file("install.sh")}"
    # OR
    #provisioner "remote-exec" {
    #    inline = [
    #        "sudo yum update -y",
    #        "sudo yum upgrade -y",
    #        "uname -a"
    #    ]
    #    connection {
    #        timeout   = "5m"
    #        user      = "centos"
    #    }
    #}
}

#resource "null_resource" "rerun" {
#    triggers {
#      rerun = "${uuid()}"
#    }
#    connection {
#        user = "centos"
#        private_key = "${file("${var.private_key}")}"
#        host = "${aws_instance.instance.public_ip}"
#    }
#    provisioner "remote-exec" {
#      inline = [
#        "sudo yum  update -y"
#      ]
#    }
#}

Открываем файл:

$ vim variables.tf

И прописываем:

#-----------------------------------------------------------
# Global or/and default variables
#-----------------------------------------------------------
variable "name" {
  description = "Name to be used on all resources as prefix"
  default     = "TEST-EC2"
}
variable "region" {
  description = "The region where to deploy this code (e.g. us-east-1)."
  default     = "us-east-1"
}
variable "environment" {
    description = "Environment for service"
    default     = "PROD"
}
variable "orchestration" {
    description = "Type of orchestration"
    default     = "Terraform"
}
variable "createdby" {
    description = "Created by"
    default     = "Vitaliy Natarov"
}
variable "ami" {
    description = "I added only 3 regions to show the map feature but you can add all"
    type        = "map"
    default     = {
        us-east-1 = "ami-46c1b650"
        us-west-2 = "ami-46c1b650"
        eu-west-1 = "ami-6e28b517"
    }
}
#---------------------------------------------------------------
# Custom variables
#---------------------------------------------------------------
variable "key_name" {
    description = "The key name to use for the instance"
    default     = ""
}
variable "number_of_instances" {
    description = "Number of instances to make"
    default     = "1"
}
variable "ec2_instance_type" {
    description = "Type of instance t2.micro, m1.xlarge, c1.medium etc"
    default     = "t2.micro"
}
variable "disk_size" {
    description = "disk size for EC2 instance"
    default     = 8
}
variable "tenancy" {
  description = "The tenancy of the instance (if the instance is running in a VPC). Available values: default, dedicated, host."
  default     = "default"
}
variable "ebs_optimized" {
  description = "If true, the launched EC2 instance will be EBS-optimized"
  default     = false
}
variable "disable_api_termination" {
  description = "If true, enables EC2 Instance Termination Protection"
  default     = false
}
variable "instance_initiated_shutdown_behavior" {
  description = "Shutdown behavior for the instance" # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/terminating-instances.html#Using_ChangingInstanceInitiatedShutdownBehavior
  default     = ""
}
variable "key_path" {
    description = "Key path to your RSA|DSA key"
    default     = "/Users/captain/.ssh/id_rsa.pub"
}
variable "private_key" {
    description = "Private key"
    default     = "/Users/captain/.ssh/id_rsa"
}
variable "enable_associate_public_ip_address" {
    description = "Enabling associate public ip address"
    default     = "true"
}
variable "source_dest_check" {
    description = " (Optional) Controls if traffic is routed to the instance when the destination address does not match the instance. Used for NAT or VPNs. Defaults true."
    default     = "false"
}
variable "subnet_id" {
    description = "Public subnet ID"
    #type        = "list"
}
variable "vpc_security_group_ids" {
    description = " SG for EC2"
    type        = "list"
}
variable "monitoring" {
    description = "If true, the launched EC2 instance will have detailed monitoring enabled"
    default     = false
}
variable "user_data" {
    description = "The user data to provide when launching the instance"
    default     = ""
}
variable "iam_instance_profile" {
    description = "The IAM Instance Profile to launch the instance with. Specified as the name of the Instance Profile."
    default     = ""
}
variable "placement_group" {
    description = "The Placement Group to start the instance in"
    default     = ""
}
variable "private_ip" {
    description = "Private IP address to associate with the instance in a VPC"
    default     = ""
}
variable "ipv6_address_count" {
    description = "A number of IPv6 addresses to associate with the primary network interface. Amazon EC2 chooses the IPv6 addresses from the range of your subnet."
    default     = 0
}
variable "ipv6_addresses" {
    description = "Specify one or more IPv6 addresses from the range of the subnet to associate with the primary network interface"
    default     = []
}
variable "volume_tags" {
    description = "A mapping of tags to assign to the devices created by the instance at launch time"
    default     = {}
}
variable "root_block_device" {
    description = "Customize details about the root block device of the instance. See Block Devices below for details"
    default     = []
}
variable "ebs_block_device" {
    description = "Additional EBS block devices to attach to the instance"
    default     = []
}
variable "ephemeral_block_device" {
    description = "Customize Ephemeral (also known as Instance Store) volumes on the instance"
    default     = []
}
variable "network_interface" {
    description = "Customize network interfaces to be attached at instance boot time"
    default     = []
}

Собственно в этом файле храняться все переменные. Спасибо кэп!

Открываем последний файл:

$ vim outputs.tf

и в него вставить нужно следующие строки:

# Output the IDs of the EC2 instances created
output "instance_ids" {
    value = ["${aws_instance.instance.*.id}"]
}
output "availability_zone" {
  description = "List of availability zones of instances"
  value       = ["${aws_instance.instance.*.availability_zone}"]
}
output "key_name" {
  description = "List of key names of instances"
  value       = ["${aws_instance.instance.*.key_name}"]
}
output "public_dns" {
  description = "List of public DNS names assigned to the instances. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC"
  value       = ["${aws_instance.instance.*.public_dns}"]
}

output "public_ip" {
  description = "List of public IP addresses assigned to the instances, if applicable"
  value       = ["${aws_instance.instance.*.public_ip}"]
}

output "network_interface_id" {
  description = "List of IDs of the network interface of instances"
  value       = ["${aws_instance.instance.*.network_interface_id}"]
}

output "primary_network_interface_id" {
  description = "List of IDs of the primary network interface of instances"
  value       = ["${aws_instance.instance.*.primary_network_interface_id}"]
}

output "private_dns" {
  description = "List of private DNS names assigned to the instances. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC"
  value       = ["${aws_instance.instance.*.private_dns}"]
}

output "private_ip" {
  description = "List of private IP addresses assigned to the instances"
  value       = ["${aws_instance.instance.*.private_ip}"]
}

output "security_groups" {
  description = "List of associated security groups of instances"
  value       = ["${aws_instance.instance.*.security_groups}"]
}

output "vpc_security_group_ids" {
  description = "List of associated security groups of instances, if running in non-default VPC"
  value       = ["${aws_instance.instance.*.vpc_security_group_ids}"]
}

output "subnet_id" {
  description = "List of IDs of VPC subnets of instances"
  value       = ["${aws_instance.instance.*.subnet_id}"]
}

output "tags" {
  description = "List of tags of instances"
  value       = ["${aws_instance.instance.*.tags}"]
}
output "key_pair_id" {
    description = "key_pair_id"
    value       = "aws_key_pair.key_pair.id"
}

Так же, может понадобится:

$ cat install.sh

#!/bin/bash -x

# CREATED:
# vitaliy.natarov@yahoo.com
#
# Unix/Linux blog:
# http://linux-notes.org
# Vitaliy Natarov
#
# Set some colors for status OK, FAIL and titles
SETCOLOR_SUCCESS="echo -en \\033[1;32m"
SETCOLOR_FAILURE="echo -en \\033[1;31m"
SETCOLOR_NORMAL="echo -en \\033[0;39m"

SETCOLOR_TITLE="echo -en \\033[1;36m" #Fuscia
SETCOLOR_TITLE_GREEN="echo -en \\033[0;32m" #green
SETCOLOR_NUMBERS="echo -en \\033[0;34m" #BLUE

yum update -y
yum upgrade -y

Данный файл служит для того, чтобы выводить нужные значения на экран вашего экрана.

Переходим теперь в папку aws/examples и создадим еще одну папку для проверки написанного чуда:

$ mkdir ec2 && cd $_

Внутри созданной папки открываем файл:

$ vim main.tf

И вставим в него следующий код:

#
# MAINTAINER Vitaliy Natarov "vitaliy.natarov@yahoo.com"
#
terraform {
  required_version = "> 0.9.0"
}
provider "aws" {
    region  = "us-east-1"
}
module "iam" {
    source                          = "../../modules/iam"
    name                            = "TEST-AIM2"
    region                          = "us-east-1"
    environment                     = "PROD"

    aws_iam_role-principals         = [
        "ec2.amazonaws.com",
    ]
    aws_iam_policy-actions           = [
        "cloudwatch:GetMetricStatistics",
        "logs:DescribeLogStreams",
        "logs:GetLogEvents",
        "elasticache:Describe*",
        "rds:Describe*",
        "rds:ListTagsForResource",
        "ec2:DescribeAccountAttributes",
        "ec2:DescribeAvailabilityZones",
        "ec2:DescribeSecurityGroups",
        "ec2:DescribeVpcs",
        "ec2:Owner",
    ]
}
module "vpc" {
    source                              = "../../modules/vpc"
    name                                = "main"
    environment                         = "PROD"
    # VPC
    instance_tenancy                    = "default"
    enable_dns_support                  = "true"
    enable_dns_hostnames                = "true"
    assign_generated_ipv6_cidr_block    = "false"
    enable_classiclink                  = "false"
    vpc_cidr                            = "172.31.0.0/16"
    private_subnet_cidrs                = ["172.31.64.0/20"]
    public_subnet_cidrs                 = ["172.31.0.0/20"]
    availability_zones                  = ["us-east-1a", "us-east-1b"]
    enable_all_egress_ports             = "true"
    allowed_ports                       = ["9300", "3272", "8888", "8444"]

    map_public_ip_on_launch             = "true"

    #Internet-GateWay
    enable_internet_gateway             = "true"
    #NAT
    enable_nat_gateway                  = "false"
    single_nat_gateway                  = "false"
    #VPN
    enable_vpn_gateway                  = "false"
    #DHCP
    enable_dhcp_options                 = "false"
    # EIP
    enable_eip                          = "false"
}
module "ec2" {
    source                              = "../../modules/ec2"
    name                                = "TEST-Machine"
    region                              = "us-east-1"
    environment                         = "PROD"
    ec2_instance_type                   = "t2.micro"
    enable_associate_public_ip_address  = "true"
    disk_size                           = "8"
    tenancy                             = "${module.vpc.instance_tenancy}"
    iam_instance_profile                = "${module.iam.instance_profile_id}"
    subnet_id                           = "${element(module.vpc.vpc-publicsubnet-ids, 0)}"
    #subnet_id                           = "${element(module.vpc.vpc-privatesubnet-ids, 0)}"
    #subnet_id                           = ["${element(module.vpc.vpc-privatesubnet-ids)}"]
    vpc_security_group_ids              = ["${module.vpc.security_group_id}"]

    monitoring                          = "true"
    #depends_on = [
    #    "module.vpc",
    #    "module.iam"
    #]
}

PS: Тут имеются вспомогательные модули. Я описывал работу тут:

Работа с AWS IAM и Terraform в Unix/Linux

Работа с AWS VPC и Terraform в Unix/Linux

Все уже написано и готово к использованию. Ну что, начнем тестирование. В папке с вашим плейбуком, выполняем:

$ terraform init

Этим действием я инициализирую проект. Затем, подтягиваю модуль:

$ terraform get

PS: Для обновление изменений в самом модуле, можно выполнять:

$ terraform get -update

Запускем прогон:

$ terraform plan

Мне вывело что все у меня хорошо и можно запускать деплой:

$ terraform apply

Как видно с вывода, — все прошло гладко! Чтобы удалить созданное творение, можно выполнить:

$ terraform destroy

Чуть позже, я опубликую весь материал на github аккаунты для удобства использования. Но об этом позже.

Вот и все на этом. Данная статья «Работа с AWS EC2 и Terraform в Unix/Linux» завершена.

Работа с AWS ASG(auto scaling group) и Terraform в Unix/Linux

$
0
0

Работа с AWS ASG(auto scaling group) и Terraform в Unix/Linux

Auto Scaling позволяет поддерживать доступность приложений на неизменно высоком уровне и динамически масштабировать ресурсы Amazon EC2 как в сторону увеличения, так и в сторону уменьшения в автоматическом режиме, в зависимости от заданных условий. Auto Scaling можно использовать для управления группой инстансов Amazon EC2, чтобы поддерживать работоспособность и доступность группы и гарантировать, что в любой момент времени используется необходимое количество инстансов Amazon EC2. Можно также использовать Auto Scaling для динамического масштабирования инстансов EC2, чтобы автоматически увеличивать количество инстансов Amazon EC2 во время пиковых нагрузок для поддержания производительности и снижать объем используемых ресурсов в периоды затишья для сокращения затрат. Auto Scaling хорошо подходит как для приложений со стабильными схемами нагрузки, так и для приложений, уровень использования которых изменяется ежечасно, ежедневно или еженедельно. Помимо Auto Scaling для Amazon EC2 можно использовать возможность Application Auto Scaling для автоматического масштабирования ресурсов других сервисов AWS, включая Amazon ECS, группы спотовых инстансов Amazon EC2, кластеры Amazon EMR, группы инстансов AppStream 2.0 и Amazon DynamoDB.

Установка terraform в Unix/Linux

Установка крайне примитивная и я описал как это можно сделать тут:

Установка terraform в Unix/Linux

Так же, в данной статье, я создал скрипт для автоматической установки данного ПО. Он был протестирован на CentOS 6/7, Debian 8 и на Mac OS X. Все работает должным образом!

Чтобы получить помощь по использованию команд, выполните:

$ terraform
Usage: terraform [--version] [--help] <command> [args]

The available commands for execution are listed below.
The most common, useful commands are shown first, followed by
less common or more advanced commands. If you're just getting
started with Terraform, stick with the common commands. For the
other commands, please read the help and docs before usage.

Common commands:
    apply              Builds or changes infrastructure
    console            Interactive console for Terraform interpolations
    destroy            Destroy Terraform-managed infrastructure
    env                Workspace management
    fmt                Rewrites config files to canonical format
    get                Download and install modules for the configuration
    graph              Create a visual graph of Terraform resources
    import             Import existing infrastructure into Terraform
    init               Initialize a Terraform working directory
    output             Read an output from a state file
    plan               Generate and show an execution plan
    providers          Prints a tree of the providers used in the configuration
    push               Upload this Terraform module to Atlas to run
    refresh            Update local state file against real resources
    show               Inspect Terraform state or plan
    taint              Manually mark a resource for recreation
    untaint            Manually unmark a resource as tainted
    validate           Validates the Terraform files
    version            Prints the Terraform version
    workspace          Workspace management

All other commands:
    debug              Debug output management (experimental)
    force-unlock       Manually unlock the terraform state
    state              Advanced state management

Приступим к использованию!

Работа с AWS ELB и Terraform в Unix/Linux

У меня есть папка terraform, в ней у меня будут лежать провайдеры с которыми я буду работать. Т.к в этом примере я буду использовать AWS, то создам данную папку и перейду в нее. Далее, в этой папке, стоит создать:

$ mkdir examples modules

В папке examples, я буду хранить так званые «плейбуки» для разварачивания различных служб, например — zabbix-server, grafana, web-серверы и так далее. В modules директории, я буду хранить все необходимые модули.

Начнем писать модуль, но для этой задачи, я создам папку:

$  mkir modules/asg

Переходим в нее:

$ cd modules/asg

Открываем файл:

$ vim asg.tf

В данный файл, вставляем:

#---------------------------------------------------
# Create AWS ASG
#---------------------------------------------------
resource "aws_autoscaling_group" "asg" {
    count                       = "${var.create_asg}"
    launch_configuration        = "${var.create_lc ? element(aws_launch_configuration.lc.*.name, 0) : var.launch_configuration}"
    #name                        = "${var.name}-asg-${var.environment}"
    name_prefix                 = "${var.name}-asg-"
    #Have got issue with availability_zones usage. So, I skip this parameter.
    #availability_zones          = ["${split(",", (lookup(var.availability_zones, var.region)))}"]
    max_size                    = "${var.asg_max_size}"
    min_size                    = "${var.asg_min_size}"
    vpc_zone_identifier         = ["${var.vpc_zone_identifier}"]
    desired_capacity            = "${var.desired_capacity}"

    health_check_grace_period   = "${var.health_check_grace_period}"
    health_check_type           = "${var.health_check_type}"
    load_balancers              = ["${var.load_balancers}"]

    min_elb_capacity            = "${var.min_elb_capacity}"
    wait_for_elb_capacity       = "${var.wait_for_elb_capacity}"
    target_group_arns           = ["${var.target_group_arns}"]
    default_cooldown            = "${var.default_cooldown}"
    force_delete                = "${var.force_delete}"
    termination_policies        = "${var.termination_policies}"
    suspended_processes         = "${var.suspended_processes}"
    placement_group             = "${var.placement_group}"
    enabled_metrics             = ["${var.enabled_metrics}"]
    metrics_granularity         = "${var.metrics_granularity}"
    wait_for_capacity_timeout   = "${var.wait_for_capacity_timeout}"
    protect_from_scale_in       = "${var.protect_from_scale_in}"

    tags = [
        {
            key                 = "Name"
            value               = "${data.template_file.instances_index.rendered}"
            propagate_at_launch = true
        },
        {
            key                 = "Environment"
            value               = "${var.environment}"
            propagate_at_launch = true
        },
        {
            key                 = "Orchestration"
            value               = "${var.orchestration}"
            propagate_at_launch = true
        },
        {
            key                 = "Createdby"
            value               = "${var.createdby}"
            propagate_at_launch = true
        },
    ]

    depends_on  = ["aws_launch_configuration.lc"]
}
#---------------------------------------------------
# Data for ASG
#---------------------------------------------------
data "template_file" "instances_index" {
    count       = "${var.asg_max_size}"
    template    = "${var.name}-${var.environment}-${count.index+1}"
}
#---------------------------------------------------
# Launch AWS configuration
#---------------------------------------------------
resource "aws_launch_configuration" "lc" {
    count                       = "${var.create_lc}"
    #name                        = "${var.name}-lc-${var.environment}"
    name_prefix                 = "${var.name}-lc-"
    image_id                    = "${lookup(var.ami, var.region)}"
    instance_type               = "${var.ec2_instance_type}"
    security_groups             = ["${var.security_groups}"]
    iam_instance_profile        = "${var.iam_instance_profile}"

    key_name                    = "${var.key_name}"
    user_data                   = "${var.user_data}"
    associate_public_ip_address = "${var.enable_associate_public_ip_address}"

    enable_monitoring           = "${var.monitoring}"

    placement_tenancy           = "${var.placement_tenancy}"
    #placement_tenancy does not work with spot_price
    #spot_price                  = "${var.spot_price}"

    ebs_optimized               = "${var.ebs_optimized}"
    ebs_block_device            = "${var.ebs_block_device}"
    ephemeral_block_device      = "${var.ephemeral_block_device}"
    root_block_device           = "${var.root_block_device}"

    lifecycle {
        create_before_destroy = "true" #"${var.enable_create_before_destroy}"
    }

}
#---------------------------------------------------
# Add autoscaling policy rules
#---------------------------------------------------
resource "aws_autoscaling_policy" "scale_up" {
    count                   = "${var.enable_autoscaling_schedule ? 1 : 0}"
    name                    = "${var.name}-asg_policy-${var.environment}-scale_up"
    scaling_adjustment      = "${var.asg_size_scale}"
    adjustment_type         = "${var.adjustment_type}"
    cooldown                = "${var.default_cooldown}"
    autoscaling_group_name  = "${aws_autoscaling_group.asg.name}"

    lifecycle {
        create_before_destroy = true
    }

    depends_on  = ["aws_autoscaling_group.asg"]
}
resource "aws_autoscaling_policy" "scale_down" {
    count                   = "${var.enable_autoscaling_schedule ? 1 : 0}"
    name                    = "${var.name}-asg_policy-${var.environment}-scale_down"
    scaling_adjustment      = "-${var.asg_size_scale}"
    adjustment_type         = "${var.adjustment_type}"
    cooldown                = "${var.default_cooldown}"
    autoscaling_group_name  = "${aws_autoscaling_group.asg.name}"

    lifecycle {
        create_before_destroy = true
    }

    depends_on  = ["aws_autoscaling_group.asg"]
}
#---------------------------------------------------
# ASW ASG Scale-up/Scale-down
#---------------------------------------------------
resource "aws_autoscaling_schedule" "scale_out_during_business_hours" {
    count                   = "${var.enable_autoscaling_schedule ? 1 : 0}"
    scheduled_action_name   = "scale-out-during-business-hours"
    min_size                = "${var.asg_min_size}"
    max_size                = "${var.asg_size_scale}"
    desired_capacity        = "${var.asg_size_scale}"
    recurrence              = "${var.asg_recurrence_scale_up}"
    autoscaling_group_name  = "${aws_autoscaling_group.asg.name}"

    depends_on              = ["aws_autoscaling_group.asg"]
}
resource "aws_autoscaling_schedule" "scale_in_at_night" {
    count                   = "${var.enable_autoscaling_schedule ? 1 : 0}"
    scheduled_action_name   = "scale-in-at-night"
    min_size                = "${var.asg_min_size}"
    max_size                = "${var.asg_size_scale}"
    desired_capacity        = "${var.asg_min_size}"
    recurrence              = "${var.asg_recurrence_scale_down}"
    autoscaling_group_name  = "${aws_autoscaling_group.asg.name}"

    depends_on              = ["aws_autoscaling_group.asg"]
}

Открываем файл:

$ vim variables.tf

И прописываем:

#-----------------------------------------------------------
# Global or/and default variables
#-----------------------------------------------------------
variable "name" {
  description = "Name to be used on all resources as prefix"
  default     = "TEST-ASG"
}
variable "region" {
  description = "The region where to deploy this code (e.g. us-east-1)."
  default     = "us-east-1"
}
variable "environment" {
    description = "Environment for service"
    default     = "STAGE"
}
variable "orchestration" {
    description = "Type of orchestration"
    default     = "Terraform"
}
variable "createdby" {
    description = "Created by"
    default     = "Vitaliy Natarov"
}
variable "create_lc" {
    description = "Whether to create launch configuration"
    default     = true
}
variable "create_asg" {
    description = "Whether to create autoscaling group"
    default     = true
}
# Launch configuration
variable "launch_configuration" {
    description = "The name of the launch configuration to use (if it is created outside of this module)"
    default     = ""
}
variable "ec2_instance_type" {
    description = "Type of instance t2.micro, m1.xlarge, c1.medium etc"
    default     = "t2.micro"
}
variable "iam_instance_profile" {
    description = "The IAM Instance Profile to launch the instance with. Specified as the name of the Instance Profile."
    default     = ""
}
variable "key_name" {
    description = "The key name to use for the instance"
    default     = ""
}
variable "security_groups" {
  description = "A list of security group IDs to assign to the launch configuration"
  type        = "list"
}
variable "enable_associate_public_ip_address" {
    description = "Enabling associate public ip address (Associate a public ip address with an instance in a VPC)"
    default     = false
}
variable "user_data" {
    description = "The user data to provide when launching the instance"
    default     = ""
}
variable "monitoring" {
    description = "If true, the launched EC2 instance will have detailed monitoring enabled"
    default     = false
}
variable "ebs_optimized" {
    description = "If true, the launched EC2 instance will be EBS-optimized"
    default     = false
}
variable "root_block_device" {
    description = "Customize details about the root block device of the instance. See Block Devices below for details"
    default     = []
}
variable "ebs_block_device" {
    description = "Additional EBS block devices to attach to the instance"
    default     = []
}
variable "ephemeral_block_device" {
    description = "Customize Ephemeral (also known as Instance Store) volumes on the instance"
    default     = []
}
variable "spot_price" {
    description = "The price to use for reserving spot instances"
    default     = 0
}
variable "placement_tenancy" {
    description = "The tenancy of the instance. Valid values are 'default' or 'dedicated'"
    default     = "default"
}
variable "availability_zones" {
    description = "Availability zones for AWS ASG"
    type        = "map"
    default     = {
        us-east-1      = "us-east-1b,us-east-1c,us-east-1d,us-east-1e"
        us-east-2      = "us-east-2a,eu-east-2b,eu-east-2c"
        us-west-1      = "us-west-1a,us-west-1c"
        us-west-2      = "us-west-2a,us-west-2b,us-west-2c"
        ca-central-1   = "ca-central-1a,ca-central-1b"
        eu-west-1      = "eu-west-1a,eu-west-1b,eu-west-1c"
        eu-west-2      = "eu-west-2a,eu-west-2b"
        eu-central-1   = "eu-central-1a,eu-central-1b,eu-central-1c"
        ap-south-1     = "ap-south-1a,ap-south-1b"
        sa-east-1      = "sa-east-1a,sa-east-1c"
        ap-northeast-1 = "ap-northeast-1a,ap-northeast-1c"
        ap-southeast-1 = "ap-southeast-1a,ap-southeast-1b"
        ap-southeast-2 = "ap-southeast-2a,ap-southeast-2b,ap-southeast-2c"
        ap-northeast-1 = "ap-northeast-1a,ap-northeast-1c"
        ap-northeast-2 = "ap-northeast-2a,ap-northeast-2c"
    }
}
variable "ami" {
    description = "I added only 3 regions to show the map feature but you can add all"
    type        = "map"
    default     = {
        us-east-1 = "ami-46c1b650"
        us-west-2 = "ami-46c1b632"
        eu-west-1 = "ami-6e28b517"
    }
}
variable "enable_create_before_destroy" {
    description = "Create before destroy"
    default     = "true"
}
# Autoscaling group
variable "asg_max_size" {
    description = "Max size of instances to making autoscaling"
    default     = "1"
}
variable "asg_size_scale" {
    description = "Size of instances to making autoscaling(up/down)"
    default     = "1"
}
variable "asg_min_size" {
    description = "Min size of instances to making autoscaling"
    default     = "1"
}
variable "adjustment_type" {
    description = "Specifies whether the adjustment is an absolute number or a percentage of the current capacity. Valid values are ChangeInCapacity, ExactCapacity, and PercentChangeInCapacity."
    default     = "ChangeInCapacity"
}
variable "asg_recurrence_scale_up" {
    description = " Cronjob time for scale-up"
    default     = "0 9 * * *"
}
variable "asg_recurrence_scale_down" {
    description = " Cronjob time for scale-down"
    default     = "0 17 * * *"
}
variable "enable_autoscaling_schedule" {
    description = "Enabling autoscaling schedule"
    default     = false
}
variable "desired_capacity" {
    description = "Desired numbers of servers in ASG"
    default     = 1
}
variable "vpc_zone_identifier" {
    description = "A list of subnet IDs to launch resources in"
    type        = "list"
}
variable "default_cooldown" {
    description = "The amount of time, in seconds, after a scaling activity completes before another scaling activity can start"
    default     = 300
}
variable "health_check_grace_period" {
    description = "Time (in seconds) after instance comes into service before checking health."
    default     = 300
}
variable "health_check_type" {
    description = "Controls how health checking is done. Need to choose 'EC2' or 'ELB'"
    default     = "EC2"
}
variable "force_delete" {
    description = "Allows deleting the autoscaling group without waiting for all instances in the pool to terminate."
    default     = "true"
}
variable "load_balancers" {
    description = "A list of elastic load balancer names to add to the autoscaling group names"
    default     = []
}
variable "target_group_arns" {
    description = "A list of aws_alb_target_group ARNs, for use with Application Load Balancing"
    default     = []
}
variable "termination_policies" {
    description = "A list of policies to decide how the instances in the auto scale group should be terminated. The allowed values are OldestInstance, NewestInstance, OldestLaunchConfiguration, ClosestToNextInstanceHour, Default"
    type        = "list"
    default     = ["Default"]
}
variable "suspended_processes" {
    description = "A list of processes to suspend for the AutoScaling Group. The allowed values are Launch, Terminate, HealthCheck, ReplaceUnhealthy, AZRebalance, AlarmNotification, ScheduledActions, AddToLoadBalancer. Note that if you suspend either the Launch or Terminate process types, it can prevent your autoscaling group from functioning properly."
    default     = []
}
variable "placement_group" {
  description = "The name of the placement group into which you'll launch your instances, if any"
  default     = ""
}
variable "metrics_granularity" {
    description = "The granularity to associate with the metrics to collect. The only valid value is 1Minute"
    default     = "1Minute"
}
variable "enabled_metrics" {
    description = "A list of metrics to collect. The allowed values are GroupMinSize, GroupMaxSize, GroupDesiredCapacity, GroupInServiceInstances, GroupPendingInstances, GroupStandbyInstances, GroupTerminatingInstances, GroupTotalInstances"
    type        = "list"

    default = [
        "GroupMinSize",
        "GroupMaxSize",
        "GroupDesiredCapacity",
        "GroupInServiceInstances",
        "GroupPendingInstances",
        "GroupStandbyInstances",
        "GroupTerminatingInstances",
        "GroupTotalInstances",
    ]
}
variable "wait_for_capacity_timeout" {
    description = "A maximum duration that Terraform should wait for ASG instances to be healthy before timing out. (See also Waiting for Capacity below.) Setting this to '0' causes Terraform to skip all Capacity Waiting behavior."
    default     = "10m"
}
variable "min_elb_capacity" {
    description = "Setting this causes Terraform to wait for this number of instances to show up healthy in the ELB only on creation. Updates will not wait on ELB instance number changes"
    default     = 0
}
variable "wait_for_elb_capacity" {
    description = "Setting this will cause Terraform to wait for exactly this number of healthy instances in all attached load balancers on both create and update operations. Takes precedence over min_elb_capacity behavior."
    default     = false
}
variable "protect_from_scale_in" {
    description = "Allows setting instance protection. The autoscaling group will not select instances with this setting for terminination during scale in events."
    default     = false
}

Собственно в этом файле храняться все переменные. Спасибо кэп!

Открываем последний файл:

$ vim outputs.tf

и в него вставить нужно следующие строки:

# Launch configuration
output "this_launch_configuration_id" {
  description = "The ID of the launch configuration"
  value       = "${var.launch_configuration == "" && var.create_lc ? element(concat(aws_launch_configuration.lc.*.id, list("")), 0) : var.launch_configuration}"
}

output "this_launch_configuration_name" {
  description = "The name of the launch configuration"
  value       = "${var.launch_configuration == "" && var.create_lc ? element(concat(aws_launch_configuration.lc.*.name, list("")), 0) : ""}"
}

# Autoscaling group
output "this_autoscaling_group_id" {
  description = "The autoscaling group id"
  value       = "${element(concat(aws_autoscaling_group.asg.*.id, list("")), 0)}"
}

output "this_autoscaling_group_name" {
  description = "The autoscaling group name"
  value       = "${element(concat(aws_autoscaling_group.asg.*.name, list("")), 0)}"
}

output "this_autoscaling_group_arn" {
  description = "The ARN for this AutoScaling Group"
  value       = "${element(concat(aws_autoscaling_group.asg.*.arn, list("")), 0)}"
}

output "this_autoscaling_group_min_size" {
  description = "The minimum size of the autoscale group"
  value       = "${element(concat(aws_autoscaling_group.asg.*.min_size, list("")), 0)}"
}

output "this_autoscaling_group_max_size" {
  description = "The maximum size of the autoscale group"
  value       = "${element(concat(aws_autoscaling_group.asg.*.max_size, list("")), 0)}"
}

output "this_autoscaling_group_desired_capacity" {
  description = "The number of Amazon EC2 instances that should be running in the group"
  value       = "${element(concat(aws_autoscaling_group.asg.*.desired_capacity, list("")), 0)}"
}

output "this_autoscaling_group_default_cooldown" {
  description = "Time between a scaling activity and the succeeding scaling activity"
  value       = "${element(concat(aws_autoscaling_group.asg.*.default_cooldown, list("")), 0)}"
}

output "this_autoscaling_group_health_check_grace_period" {
  description = "Time after instance comes into service before checking health"
  value       = "${element(concat(aws_autoscaling_group.asg.*.health_check_grace_period, list("")), 0)}"
}

output "this_autoscaling_group_health_check_type" {
  description = "EC2 or ELB. Controls how health checking is done"
  value       = "${element(concat(aws_autoscaling_group.asg.*.health_check_type, list("")), 0)}"
}

Переходим теперь в папку aws/examples и создадим еще одну папку для проверки написанного чуда:

$ mkdir asg && cd $_

Внутри созданной папки открываем файл:

$ vim main.tf

И вставим в него следующий код:

#
# MAINTAINER Vitaliy Natarov "vitaliy.natarov@yahoo.com"
#
terraform {
  required_version = "> 0.9.0"
}
provider "aws" {
    region  = "us-east-1"
    # Make it faster by skipping something
    #skip_get_ec2_platforms      = true
    #skip_metadata_api_check     = true
    #skip_region_validation      = true
    #skip_credentials_validation = true
    #skip_requesting_account_id  = true
}
module "iam" {
    source                          = "../../modules/iam"
    name                            = "TEST-AIM2"
    region                          = "us-east-1"
    environment                     = "PROD"

    aws_iam_role-principals         = [
        "ec2.amazonaws.com",
    ]
    aws_iam_policy-actions           = [
        "cloudwatch:GetMetricStatistics",
        "logs:DescribeLogStreams",
        "logs:GetLogEvents",
        "elasticache:Describe*",
        "rds:Describe*",
        "rds:ListTagsForResource",
        "ec2:DescribeAccountAttributes",
        "ec2:DescribeAvailabilityZones",
        "ec2:DescribeSecurityGroups",
        "ec2:DescribeVpcs",
        "ec2:Owner",
    ]
}
module "vpc" {
    source                              = "../../modules/vpc"
    name                                = "main"
    environment                         = "PROD"
    # VPC
    instance_tenancy                    = "default"
    enable_dns_support                  = "true"
    enable_dns_hostnames                = "true"
    assign_generated_ipv6_cidr_block    = "false"
    enable_classiclink                  = "false"
    vpc_cidr                            = "172.31.0.0/16"
    private_subnet_cidrs                = ["172.31.64.0/20"]
    public_subnet_cidrs                 = ["172.31.0.0/20"]
    availability_zones                  = ["us-east-1a", "us-east-1b"]
    enable_all_egress_ports             = "true"
    allowed_ports                       = ["9300", "3272", "8888", "8444"]

    map_public_ip_on_launch             = "true"

    #Internet-GateWay
    enable_internet_gateway             = "true"
    #NAT
    enable_nat_gateway                  = "false"
    single_nat_gateway                  = "false"
    #VPN
    enable_vpn_gateway                  = "false"
    #DHCP
    enable_dhcp_options                 = "false"
    # EIP
    enable_eip                          = "false"
}
module "asg" {
    source                              = "../../modules/asg"
    name                                = "TEST-ASG"
    region                              = "us-east-1"
    environment                         = "PROD"

    security_groups = ["${module.vpc.security_group_id}"]

    root_block_device  = [
        {
            volume_size = "8"
            volume_type = "gp2"
        },
    ]

    # Auto scaling group
    #asg_name                  = "example-asg"
    vpc_zone_identifier       = ["${module.vpc.vpc-publicsubnet-ids}"]
    health_check_type         = "EC2"
    asg_min_size              = 0
    asg_max_size              = 1
    desired_capacity          = 1
    wait_for_capacity_timeout = 0

    #
    enable_autoscaling_schedule = true
}

PS: Тут имеются вспомогательные модули. Я описывал работу тут:

Работа с AWS IAM и Terraform в Unix/Linux

Работа с AWS VPC и Terraform в Unix/Linux

Для общего развития, можно ознакомится еще с (Он тут не нужен):

Работа с AWS EC2 и Terraform в Unix/Linux

Все уже написано и готово к использованию. Ну что, начнем тестирование. В папке с вашим плейбуком, выполняем:

$ terraform init

Этим действием я инициализирую проект. Затем, подтягиваю модуль:

$ terraform get

PS: Для обновление изменений в самом модуле, можно выполнять:

$ terraform get -update

Запускем прогон:

$ terraform plan

Мне вывело что все у меня хорошо и можно запускать деплой:

$ terraform apply

Как видно с вывода, — все прошло гладко! Чтобы удалить созданное творение, можно выполнить:

$ terraform destroy

У меня уже имеются наработки на github, вот аккаунт:

$ git clone https://github.com/SebastianUA/terraform.git

Вот и все на этом. Данная статья «Работа с AWS ELB и Terraform в Unix/Linux» завершена.

Viewing all 152 articles
Browse latest View live