Автоматизация облачной инфраструктуры с помощью SparrowCI
Пайплайн SparrowCI — это дерево задач, где одна задача может зависеть от других и так далее. У задач также есть состояния, которые доступны из других задач. Эта архитектура очень хорошо соответствует природе иерархических облачных ресурсов.
—
Рассмотрим этот простой пример идемпотентного создания экземпляра ec2:
tasks: - name: create-ec2 default: true config: name: host_01 image: ami-0e322da50e0e90e21 if: language: Bash code: | name=$(config name) instance_id=$(aws ec2 describe-instances \ --filters "Name=tag:Name,Values=$name" \ | yq ‘.Reservations | .[0] | .Instances \ | .[0]| .InstanceId’) if $instance_id != “null”; then echo "{ \"status\": \"skip\" }" \ > $cache_root_dir/state.json fi language: Raku init: | run_task "ec2", %( sn => config()<tasks><state><create-sn><state><sn-id> ); subtasks: - name: ec2 language: Bash code: | set -e name=$(config name) image=$(config image) id=$(aws ec2 run-instances \ --image-id $image \ --count 1 \ --instance-type t2.micro \ --subnet-id $sn \ | yq ‘.Instances | .[0] | .InstanceId’) aws ec2 create-tags \ --resources $id \ --region $region \ --tags "Name=$name" depends: - # create subnet name: create-sn config: sb_name: subnet_01 - name: create-sn config: cidr_block: 10.0.0.0/24 vpc_id: vpc-000111222 language: Bash code: | set -e sb_name=$(config sb_name) cidr_block=$(config cidr_block) vpc_id=$(config vpc_id) SubnetId=$(aws ec2 describe-subnets \ --filters "Name=tag:Name,Values=$sb_name" \ | yq ‘.subnets | .[0] | .SubnetId’) if $SubnetId != "null"; then echo "{ \"sn-id\": \"$SubnetId\" }" \ > $cache_root_dir/state.json else SubnetId=(aws ec2 create-subnet \ --vpc-id $vpc_id \ --cidr-block $cidr_block \ --tag-specifications \ “ResourceType=subnet,Tags=[{Key=Name,Value=$sb_name}]” \ | yq ‘.Subnet.SubnetId’) echo "{ \"sn-id\": \"$SubnetId\" }" \ > $cache_root_dir/state.json fi
В этом сценарии задача, создающая экземпляр ec2, зависит от задачи, которая сначала создает подсеть. Идентификатор подсети доступен в задаче создания экземпляра ec2 через синтаксис хэша Raku config()<tasks><create-sn><sn-id>
, где create-sn — это имя задачи, создающей подсеть.
Модификатор «Если» первой задачи предотвращает выполнение задачи, если экземпляр ec2 с заданным именем host_01
существует, объявляя статус как "status": "skip"
.
Задачи Bash объявляют о своем состоянии, выгружая данные в файл state.json
, другие языки могут вызывать функцию updates_state(hash)
напрямую.
—
Создание нескольких экземпляров
Приведенный выше пример может быть легко расширен для развертывания множества экземпляров ec2. Все, что нам нужно сделать, это использовать синтаксис hub tasks для многократного выполнения одного и того же шаблона задачи:
tasks: - name: create-ec2 default: true config: image: ami-0e322da50e0e90e21 hub: language: Raku code: | update_state %( list => [ { config => { image => config()<image>, name => “host_01” } }, { config => { image => config()<image>, name => “host_02” } }, { config => { image => config()<image>, name => “host_03” } }, ] ); if: language: Bash code: | name=$(config name) instance_id=$(aws ec2 describe-instances \ --filters "Name=tag:Name,Values=$name" \ | yq ‘.Reservations | .[0] | .Instances \ | .[0].InstanceId’) if $instance_id != “null”; then echo "{ \"status\": \"skip\" }" \ > $cache_root_dir/state.json fi language: Raku init: | # the rest is the same # as in the snippet above
—
Этот простой пример демонстрирует гибкость SparrowCI, позволяющую пользователям создавать различные сценарии для управления сложной облачной инфраструктурой.
—
Спасибо за чтение!
PS. Поразмыслив над этим примером, я придумал лучшее решение — “https://github.com/melezhik/sparrowci-aws-example/blob/main/sparrow.yaml» — но это, наверное, тема к следующему посту))