Некоторые очень явно отдают предпочтение CLI (источник: Imgur)
Пока облачные технологии набирали популярность, платформа Amazon Web Services (AWS), обеспечивающая сегодня работу многих интернет-гигантов и определяющая стандарты того, как должны быть организованы многие облачные сервисы, стала бесспорным лидером рынка облачных вычислений. Чтобы понимать как исползовать постоянно растущее число сервисов и предоставляемые ими возможности, DevOps инженер должен не отставать от темпа развития облачных технологий, который задает Amazon, и это становится настоящим испытанием.
DevOps'ы часто задаются вопросом о том, как лучше управлять быстро растущей инфраструктурой AWS. Они размышляют, лучше ли использовать для этого GUI (AWS console) или CLI (AWS CLI). А может быть использовать и то, и другое?
Представляем вашему вниманию третий вариант, созданый для облегчения работы DevOps'ов: awless.io — новый open source CLI для AWS, написанный на Go. Проект получил одобрение Джеффа Барра (Jeff Barr), рок-звезды AWS, и всего за несколько месяцев собрал более 2.5K звезд на GitHub. В этой статье я объясню, почему компания Wallix, в которой я работаю, создала awless.io, и почему мы считаем, что этот инструмент может помочь DevOps'ам.
О чем, кстати, говорят эти твиты:
Любовь и ненавитсь к GUI
AWS пердоставляет множество сервисов
Сисадмины, как правило, ненавидят GUI. The Linux Foundation считает их уделом новичков. Является ли AWS Console исключением? Console предоставляет возможность управления всеми доступными сервисами и позволяет использовать мастеров настройки для решения разнообразных задач. Мы ценим возможности, предоставляемые Console, особенно при выполнении разовых задач, т.к. визуализация процесса в этом случае бывает очень полезна. А вот решение стандартных, повторяющихся задач с помощью GUI отнимает слишком много времени и может вывести из себя опытных пользователей.
Мы на шестом шаге в AWS Console и мы все еще не создали инстанс
С помощью GUI сложно автоматизировать действия, оставлять пометки для себя или взаимодействовать с коллегой для выполнения той или иной операции. Помните как вы в последний раз объясняли сослуживцу (или, например, маме) по телефону, как сделать что-то, с помощью веб-интерфейса, попутно копаясь в нем? Это действительно раздражает.
Трудности aws CLI
CLI, с другой стороны, великолепен для решения рутинных задач. После пердварительной настройки с помощью CLI можно сделать что угодно, не вводя данные для входа в систему вручную и не прикасаясь к мыши.
Например, этой команды достаточно для запуска t1.micro инстанса:
find
-name "sws"
> aws ec2 run-instances --image-id ami-xxxxxxxx --count 1 --instance-type t1.micro
--key-name keypair-xxxxxxxx --security-groups sg-xxxxxxxx
Заметим, что запомнить идентификатор Amazon Machine Image (AMI) или имя ключевой пары может быть непросто, но эта проблема решается использованием команды оболочки alias. Например, для начала мы находим нужную security group:
> aws ec2 describe-security-groups --group-name "awless-secgroup"
и грепаем ID группы из вывода, который по умолчанию должен выглядеть как-то так:
{
"SecurityGroups": [
{
"IpPermissionsEgress": [
{
"PrefixListIds": [],
"FromPort": 80,
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"ToPort": 80,
"IpProtocol": "tcp",
"UserIdGroupPairs": [],
"Ipv6Ranges": []
},
{
"PrefixListIds": [],
"FromPort": 443,
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"ToPort": 443,
"IpProtocol": "tcp",
"UserIdGroupPairs": [],
"Ipv6Ranges": []
}
],
"Description": "awless-secgroup",
"IpPermissions": [
{
"PrefixListIds": [],
"FromPort": 22,
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"ToPort": 22,
"IpProtocol": "tcp",
"UserIdGroupPairs": [],
"Ipv6Ranges": []
}
],
"GroupName": "awless-secgroup",
"VpcId": "vpc-00b68c65",
"OwnerId": "519101999238",
"GroupId": "sg-687a5d0e"
}
]
}
Хотя такой подход и кажется более «продвинутым» по сравнению с использованием AWS Console, он не всегда удобен и эффективен. При использовании aws CLI приходиться постоянно переключаться с ввода команд на выполнение других действий, таких как копирование вывода предыдущих команд или редактирования JSON сниппетов. Существующие open source альтернативы aws CLI только немного изменяют синтаксис операций, добавляют подсветку, автодополнение и прочие свистелки.
Такие инструменты как AWS CloudFormation удобны для создания стеков, но написание соответствующих шаблонов представляет собой отдельную задачу, а сами шаблоны не всегда могут заменить ручное выполнение нескольких команд. Однажды мы мучались, пытаясь с помощью aws CLI найти ресурсы, созданные с использование шаблонов CloudFormation. Угадать правильное место в килобайтах JSON, где нужно прописать Id — нелегкая задача. В конце концов мы сдались и использовали GUI.
Явление awless.io
awless.io — альтернативный CLI для AWS, в котором простота использования ставится на первый план, перед исчерпывающей полнотой функционала. С помощью этого инструмента мы стремимся упростить 90 процентов возможных задач, путем изменения существующих команд.
awless.io не просто фронтэнд для AWS CLI: это новый консольный интерфейс, написанный на Go с использованием официального AWS Go SDK. Это полностью open-source проект, выпущенный под лицензией Apache. На данный момент awless.io поддерживает следующие AWS сервисы: IAM, EC2 (включая ELBv2), S3, Route53, RDS, SQS, SNS, Cloudfront, Cloudwatch, CloudFormation и Lambda. В ближайшем будущем планируется расширение этого списка.
Изначально awless.io разрабатывался отделом инноваций моей компании Wallix для решения ряда внутренних задач. Де-факто Wallix спонсировал разработку, но, по существу, awless.io — проект, который создается сообществом разработчиков, и ваше участие в нем строго приветствуется.
Преимущества awless.io
При создании awless.io мы пытались следовать принципам, заложенным популярными инструментами, такими как git; большинство команд имеют вид:
awless [verb] [noun] [parameter=value ...]
Например, все это возможные команды:
# Показать существующих пользователей
awless list users
# Создать новый инстанс
awless create instance
# Добавить пользователя в группу
awless attach user name=my-user-name group=my-group
# Запустить шаблон
awless run https://example.com/create_vpc.aws
Основные принципы awless.io включают:
- использование «умных» настроек по умолчанию, которые позволят пользоваться интсрументом даже при минимальном знании облачных технологий
- вывод информации в формате, который одновременно и читаем, и удобен для парсинга
- локальное сохранение копии модели инфраструктуры в виде графа RDF (Resource Description Framework), что позволяет обращаться к ней и производить вычисления не удаленно
awless.io делает упор на использование одних и тех же глаголов (таких как list, create, delete) в синтаксисе разных операций, что в результате приводит к небольшому (и простому для запомнинания) множеству используемых команд. Синтаксис унифицирован для разных сервисов. К примеру, вы можете написать:
awless list [instances|users|buckets|records]
вместо:
aws ec2 describe-instances
aws iam list-users
aws s3api list-buckets
aws route53 list-resource-record-sets
Начинаем работу с awless.io
awless.io доступен на GitHub. Мы также распространяем его в качестве скомпилированных пакетов и через Homebrew для macOS:
brew tap wallix/awless; brew install awless
Сборка из исходников очень проста, при условии что в системе установлен Go:
go get -u github.com/wallix/awless
При первом запуске, awless.io запросит идентификационные данные или, если в системе установлен и настроен aws-cli, подтнет их из его конфигурации автоматически. Помимо этого стоит установить автодополнение для bash или zsh.
Исследуем инфраструктуру AWS
awless.io предоставляет DevOps'ам широкий набор возможностей для навигации по развернутой AWS инфраструктуре. Две основные команды для этого — list и show. Для каждого типа ресурсов awless.io вначале выводит наиболее значимую информацию.
Вывод списка объектов
awless.io позволяет выводить список всевозможных объектов AWS, таких как пользователи, группы безопасности или инстансы:
> awless list users
| ID ▲ | NAME | LASTUSED | CREATED |
|-----------------------|-----------|----------|-----------|
| AIDAI37GETCRRVNLDKFYQ | hbinsztok | 8 days | 10 months |
| AIDAI3FX74KAQQKIOM2XY | awless-ts | 13 weeks | 4 months |
[…]
Если ширина терминала не позволяет вывести данные полностью, то колонки обрезаются автоматически, и на экран выводится предупреждение о том, что такая-то информация была скрыта:
> awless list securitygroups
| ID ▲ | VPC | INBOUND |
|-------------|--------------|-------------------------------------|
| sg-1d578b64 | vpc-00b68c65 | [0.0.0.0/0](tcp:1433) |
| | | [0.0.0.0/0;::/0](tcp:443) |
| | | [::/0;0.0.0.0/0](tcp:80) |
| | | [::/0;0.0.0.0/0](tcp:2242) |
| | | [::/0;0.0.0.0/0](tcp:22) |
| | | [0.0.0.0/0](tcp:3389) |
| sg-30abc756 | vpc-00b68c65 | [0.0.0.0/0](tcp:443) |
| | | [0.0.0.0/0](tcp:80) |
[...]
Columns truncated to fit terminal: 'Outbound', 'Name', 'Description'
Вывод легко и непринужденно сортируется и фильтруется:
> awless list instance --sort uptime --filter zone=eu-west-1b
| ID | ZONE | NAME | STATE |
|---------------------|------------|---------------------|---------|
| i-03a1f22b36ddb0739 | eu-west-1b | blog-test | running |
| i-05adde5a930da5ed3 | eu-west-1b | authoringtest | stopped |
| i-06b8f07c1e4afb49a | eu-west-1b | AwlessWithScheduler | running |
[...]
Columns truncated to fit terminal: 'Type', 'Public IP', 'Private IP', 'Uptime', 'KeyPair'
Формат вывода может быть настроен. По умолчанию данные выводятся в удобочитаемую таблицу (результат выводится в markdown, который можно передать в качестве ввода в сторонний инструмент, например в pandoc). Данные можно также выводить в форматах csv, json или tsv:
> awless list subnets --format csv
ID,Name,CIDR,Zone,Default,Vpc,Public,State
subnet-0c41ad68,,172.31.0.0/20,eu-west-1a,true,vpc-00b68c65,true,available
subnet-2486b17c,demo-env-subnet,10.0.0.0/24,eu-west-1c,false,vpc-67b25c00,true,available
[...]
Одной из отличительных черт awless.io является возможность работы с инфраструктурой, представленной в виде RDF графа, и выполнения сложных запросов локально. Использование стандартизированного формата позволяет применять существующие инструменты, такие как Protégé, для выполнения запросов на графе. Сохраненный локально граф позволяет в определенной мере работать с инфраструктурой даже без выхода в интернет:
> ping amazon.com
ping: cannot resolve amazon.com: Unknown host
> awless list instances --local
| ID ▲ | ZONE | NAME | STATE |
|---------------------|------------|---------------------|---------|
| i-01b17116fed0a09bd | eu-west-1c | windows-demo-env | running |
| i-05c0a275adb5484fa | eu-west-1c | git.inno.wallix.com | running |
| i-06b8f07c1e4afb49a | eu-west-1b | AwlessWithScheduler | running |
[...]<br />
Получение информации о ресурсах
Команда show позволяет получить информацию о любом ресурсе:
> awless show i-03a1f22b36ddb0739
| PROPERTY ▲ | VALUE |
|-------------------|---------------------|
| Architecture | x86_64 |
| Hypervisor | xen |
| ID | i-03a1f22b36ddb0739 |
| Image | ami-70edb016 |
| KeyPair | keypair-blog |
| Name | blog-test |
| NetworkInterfaces | [eni-10e4352d] |
| Private IP | 10.0.20.245 |
| Public IP | 34.252.193.183 |<br />
| RootDevice | /dev/xvda |
| RootDeviceType | ebs |
| SecurityGroups | [sg-a2a282c4] |
| State | running |
| Subnet | subnet-472a1731 |
| Type | t2.micro |
| Uptime | 46 hours |
| Vpc | vpc-96c7eef2 |
| Zone | eu-west-1b |
eu-west-1[region]
↳ @awless-test-vpc[vpc]
↳ @awless-public-subnet[subnet]
↳ @blog-test[instance]
Depending on: keypair-blog[keypair], @default[securitygroup], vol-0f82cd93824f456e5[volume]
Siblings: @AwlessWithScheduler[instance]
Эта команда выводит характеристики и зависимости облачного ресурса. Например, в случае инстанса, команда выведет его Virtual Private Cloud (VPC), подсеть, связаные с ним объекты и информацию о смонтированном томе, ключевой паре и гуппах безопасности инстанса. Список свойств будет различаться в зависимости от типа ресурса:
> awless show AIDAI3FX74KAQQKIOM2XY
| PROPERTY ▲ | VALUE |
|------------------|-----------------------------------------------|
| Arn | arn:aws:iam::519101999238:user/awless-test-usr|
| Created | 4 months |
| ID | AIDAI3FX74KAQQKIOM2XY |
| Name | awless-test-user |
| PasswordLastUsed | 2 weeks |
| Path | / |
Depending on: @PepsWallixS3Assume[policy], @PepsWallixS3[policy]
Однострочники и шаблоны
awless.io замечательный инструмент для просмотра и анализа облачных ресурсов. Но он также предоставляет мощный мехнизм шаблонов, поддерживающий операции с инфраструктурой (создание, редактирование и удаление ресурсов).
Однострочники
Шаблоны awless.io можно применять путем ввода однострочных команд, или с помощью скриптов. Для создания инстанса, ключевой пары или ресурса любого другого типа достаточно двух простых команд:
> awless create instance
> awless create keypair
awless.io не требует ввода всей необходимой информации сразу. Вместо этого он запрашивает данные по ходу выполнения операции, предоставляя возможность автодополнения во время их ввода.
Давайте для начала создадим ключевую пару, которую мы используем для подключения по SSH к инстансам, которые мы создадим сразу после:
> awless create keypair
Please specify (Ctrl+C to quit, Tab for completion):
keypair.name? keypair-blog
create keypair name=keypair-blog
Confirm? (y/n): y
[info] Generating locally a RSA 4096 bits keypair…
[info] 4096 RSA keypair generated locally and stored in ‘/Users/henri/.awless/keys/keypair-blog.pem’
OK keypair = keypair-blog
[info] Revert this template with `awless revert 01BHAE1C0CPMNYQ0KFPRQQ7XYA`
Мы ввели только команду awless create keypair, имя ключевой пары keypair-blog и подтвредили ее создание.
awless.io использует одновременно данные, вводимые с помощью командной строки, и опции по-умолчанию, которые можно настроить (например, AMI и тип инстанса); перед внесением изменений в существующую инфраструктуру awless.io запрашивает подтверждение пользователя.
Теперь мы легко создаем инстанс, используя нашу новенькую пару ключей:
> awless create instance keypair=@keypair-blog
Please specify (Ctrl+C to quit, Tab for completion):
instance.name? instance-blog
instance.subnet? <Tab>
@awless-private-subnet @awless-public-subnet @demo-env-subnet
instance.subnet? @demo-env-subnet
create instance count=1 image=ami-70edb016 keypair=keypair-blog name=instance-blog subnet=subnet-2486b17c type=t2.micro
Confirm? (y/n): y
[info] create tag ‘Name=instance-blog’ on ‘i-094ceffee40892f66’ done
[info] create instance ‘i-094ceffee40892f66’ done
OK instance = i-094ceffee40892f66
[info] Revert this template with `awless revert 01BHAGCXY80FPK5FR73GTWWSD2`
Для подключения к инстансу напрямую можно использовать команду ssh:
> awless ssh instance-blog
awless could not validate the authenticity of ‘34.252.193.183:22’ (unknown host)
ecdsa-sha2-nistp256 public key fingerprint is SHA256:Ay8ODMNQiEt1U6BoTsPyIajoaHZ047v7uNjTV1SSQmk.
Do you want to continue connecting and persist this key to ‘/Users/henri/.ssh/known_hosts’ (yes/no)? yes
[info] Login as ‘ec2-user’ on ‘34.252.193.183’, using keypair ‘/Users/henri/.awless/keys/keypair-blog.pem’ with ssh client ‘/usr/bin/ssh’
__| __|_ )
_| ( / Amazon Linux AMI
___|___|___|
https://aws.amazon.com/amazon-linux-ami/2016.09-release-notes/
18 package(s) needed for security, out of 52 available
Run “sudo yum update” to apply all updates.
Amazon Linux version 2017.03 is available.
[ec2-user@ip-10–0–20–245 ~]$
Нет никакой необходимости в том, чтобы передавать ключи в качестве аргументов команды, т.к. они хранятся локально, нет никакой необходимости в том, чтобы указывать имя пользователя, т.к. awless.io угадывает его самостоятельно. Дьявол кроется в деталях, и awless.io делает все возможное для того, чтобы использование CLI было максимально удобным.
Помимо упрощенных коротких команд, к вашим услугам и другие новые и полезные функции. Если вы внимательно прочитали предыдущий вывод команды, вы могли обратить внимание на то, что с каждым успешно выполненым действием ассоциируется revert Id. Действительно, изменения в результате выполнения большинства шаблонов awless.io (однострочников и полноценных скриптов) можно очень просто отменить.
Как и git, awless.io ведет лог выполненных операций:
> awless log
[...]
ID: 01BHAE1C0CPMNYQ0KFPRQQ7XYA, Date: May 29 17:43:50, Author: user/hbinsztok, Region: eu-west-1
OK create keypair name=keypair-blog[keypair-blog]
ID: 01BHAGCXY80FPK5FR73GTWWSD2, Date: May 29 18:25:06, Author: user/hbinsztok, Region: eu-west-1
OK create instance count=1 image=ami-70edb016 keypair=keypair-blog name=instance-blog subnet=subnet-2486b17c type=t2.micro [i-094ceffee40892f66]
И как и коммиты, операции можно запросто откатить:
> awless revert 01BHAGCXY80FPK5FR73GTWWSD2
delete instance id=i-094ceffee40892f66
Confirm? (y/n): y
OK delete instance
Шаблоны
Ранее мы использовали шаблоны, содержавшие только одну команду (однострочники). Вообще, шаблоны являются обобщением и представляют из себя последовательность команд awless.io.
# Создать новую группу безопасности для данного инстанса
securitygroup = create securitygroup vpc={instance.vpc} description={securitygroup.description} name=ssh-from-internet
# Открыть доступ через порт 22 к инстансам в данной группе безопасности
update securitygroup id=$securitygroup inbound=authorize protocol=tcp cidr=0.0.0.0/0 portrange=22
# Создать новую клучевую пару
keypair = create keypair name={keypair.name}
# Создать инстанс в группе безопасности, к которому можно подключиться, используя созданную ключевую пару
create instance subnet={instance.subnet} image={instance.image} type={instance.type} keypair=$keypair name={instance.name} count=1 securitygroup=$securitygroup
Мы добавили следующие возможности для выстраивания цепочек команд:
- результат выполнения операции может быть сохранен в переменную, соответствующий синтаксис: value = command. В дальнейшем к сохраненному значению можно обратиться так: $value;
- использование параметров шаблонов, т.е. отсутствующих аргументов команд, которые awless.io запросит во время исполнения. Они записываются в фигруных скобках, как {instance.image} в примере выше.
Шаблоны — крайне эффективная и полезная особенность awless.io. С помощью них, например, можно легко:
- развернуть высоконадежную инфраструктуру с балансировкой нагрузки для сайта на WordPress при помощи короткого шаблона;
- создать самомасштабирующуюся группу инстансов и отслеживать нагрузку на CPU каждого в отдельности, для динамического создания новых инстансов при необходимости.
Для выполнения шаблона в качестве аргумента можно передавать имя файла в официальном репозитории awless-templates (с префиксом repo:), URL или имя докального файла-шаблона:
> awless run repo:dynamic_autoscaling_watching_CPU
Попробуйте сами! Тем более после этого вы сможете использовать команду awless revert, которую мы обсудили выше, чтобы удалить все ресурсы созданные в результате выполнения шаблонов (инстансы, группы безопасности, группы целей (target groups), балансировщики нагрузки и т.д.).
Обратите внимание, что пока мы реализовали только черновой вариант мехнаизма шаблонов, и до выпуска awless.io 1.0 в него могут привноситься изменения и добавляться новые функции. После релиза 1.0 все новые версии будут сопровождаться утилитами для упрощения миграций.
Обзор команд
Получить справку по функциям awless.io можно так:
> awless help
> awless [verb] -h
В этих таблицах собраны основные ключевые слова, использующиеся в командах и шаблонах.
И это только начало
Сегодня, после более 20 альфа релизов, выпущенных с момента запуска проекта в январе 2017, мы представляем awless.io 0.1.0. Это проект все еще находится в стадии разработки. Мы планируем улучшить наш продукт во многих отношениях, в частности добавить поддержку еще большего числа AWS сервисов и функций. Пожалуйста, если ваш любимый сервис (все еще) не поддерживается, открывайте новые или плюcуйте существующие issues на GitHub. Вот план развития и функционал, который мы планируем добавить в течение следующего года:
- 0.2.0 — Работа с несколькими регионами. Использование локального графа для предложения выбора ресурсов в соответствие с их регионами; простое переключение между регионами;
- 0.3.0 — Усовершенстование языка скриптов. Мы хотим сделать формальное описание семантики и добавить проверку типов для шаблонов, для того чтобы диагностировать ошибки до выполнения запроса на стороне AWS (это относится в том числе и к dry-run'ам);
- 0.3.0 — Усовершенстование языка скриптов. Мы хотим сделать формальное описание семантики и добавить проверку типов для шаблонов, для того чтобы диагностировать ошибки до выполнения запроса на стороне AWS (это относится в том числе и к dry-run'ам);
- 0.4.0 — Добавление возможности выполнения сложных запросов к глобальной инфраструктуре с использованием локального графа.
Мы будем рады вашей помощи в реализации проекта, в том числе если вы расскажете о нем своим знакомым. А для того чтобы оставаться в курсе всех нововведений, следите за новосятми в официальном твиттере @awlessCLI.
Автор: buddha_pinmask