Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aws-ec2.yaml: initial implementation #37

Merged
merged 1 commit into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ for each. Details for each use case can be found in the linked documents.

- [Running builds locally](docs/building-locally.md)
- [Running builds on Hetzner Cloud](docs/building-with-hetzner-cloud.md)
- [Running builds on AWS EC2](docs/building-with-aws-ec2.md)
- [Running builds with tmt](docs/building-with-tmt.md)

Some common scenarios are also documented:
Expand Down
52 changes: 52 additions & 0 deletions aws-ec2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
- name: instantiate-builder
hosts: localhost
roles:
- aws-ec2-instantiate

- name: initiate build
hosts: "asz_server"
remote_user: ec2-user
roles:
- common

- name: prepare sample images
hosts: "asz_server"
remote_user: ec2-user
roles:
- prepare-sample-images

- name: prepare custom images
hosts: "asz_server"
remote_user: ec2-user
roles:
- prepare-custom-images

- name: prepare distro configs
hosts: "asz_server"
remote_user: ec2-user
roles:
- prepare-distro-configs

- name: prepare osbuild
hosts: "asz_server"
remote_user: ec2-user
roles:
- prepare-osbuild

- name: run make
hosts: "asz_server"
remote_user: ec2-user
roles:
- run-make

- name: run make for osbuildvm-images
hosts: "asz_server"
remote_user: ec2-user
roles:
- run-make-osbuildvm

- name: teardown-builder
hosts: localhost
roles:
- aws-ec2-teardown
11 changes: 11 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,14 @@ hcloud_x86_64_image: "centos-stream-9"
hcloud_x86_64_location: "fsn1"
hcloud_x86_64_ssh_keys:
- "michael@fedora"

# AWS EC2 configuration
aws_ec2_aarch64_instance_type: "t4g.medium"
aws_ec2_aarch64_ami: "ami-0249b4054bde4661d" # CentOS Stream 9 aarch64 20240212
aws_ec2_aarch64_region: "eu-central-1"
aws_ec2_aarch64_ssh_key: "michael@fedora"

aws_ec2_x86_64_instance_type: "t3.medium"
aws_ec2_x86_64_ami: "ami-000dc02a9a29648e7" # CentOS Stream 9 x86_64 20240212
aws_ec2_x86_64_region: "eu-central-1"
aws_ec2_x86_64_ssh_key: "michael@fedora"
54 changes: 54 additions & 0 deletions docs/building-with-aws-ec2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
## Running Builds on AWS with EC2

Zeppelin can orchestrate spawning an AWS EC2 server instance (Virtual Machine),
running the build operations on said server, fetching the results back to the
users computer, and deleting the EC2 server as a final clean up operation.

> :warning: Be warned! If the build fails or is cancelled midway through, the
> server instance is not automatically cleaned up! Later I intend to add a
> playbook to help do manual clean ups but until then you should keep an eye on
> the usage billing of your account to avoid any nasty surprises.

To build with AWS, [you need an existing account][1] and you need to [generate
an access key or security token][2] and [configure your shell environment][3]
as needed (such as setting environment variables like below).

```
export AWS_ACCESS_KEY_ID="xxx"
export AWS_SECRET_ACCESS_KEY="yyy"
```

In addition to having [Ansible installed][4], you must also install the [boto3
pypi package][5] and the [amazon.aws Ansible module][6]. This enables the
playbooks to interact with the AWS EC2 API.

```
pip install boto3
ansible-galaxy collection install amazon.aws
```

You need to have an [SSH key pair already provisioned in your AWS account][7]
and configure the config.yaml accordingly based on the name (see:
`aws_ec2_aarch64_ssh_key` and `aws_ec2_x86_64_ssh_key`). The private key should
be configured for default use with your ssh client.

## Usage

You can run a build with AWS EC2 by invoking `ansible-playbook` on the
`aws-ec2.yaml` playbook with the aws\_ec2 inventory.

```
ansible-playbook -i inventories/aws-ec2/aws_ec2.yaml aws-ec2.yaml
```

The results of the build (on success) can be found in the `out` directory
(created in the current working directory). See the [Outputs section](#Output-Directory)
below for more details on the output contents.

[1]: https://docs.aws.amazon.com/accounts/latest/reference/manage-acct-creating.html
[2]: https://repost.aws/knowledge-center/create-access-key
[3]: https://docs.ansible.com/ansible/latest/collections/amazon/aws/docsite/guide_aws.html#authentication
[4]: https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#installing-and-upgrading-ansible
[5]: https://boto3.amazonaws.com/v1/documentation/api/latest/index.html
[6]: https://docs.ansible.com/ansible/latest/collections/amazon/aws/docsite/guide_aws.html
[7]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html
8 changes: 8 additions & 0 deletions inventories/aws-ec2/aws_ec2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
plugin: amazon.aws.aws_ec2
hostnames:
- tag:Name
filters:
tag:asz:
- "1"
compose:
ansible_host: public_ip_address
30 changes: 30 additions & 0 deletions roles/aws-ec2-instantiate/tasks/instantiate_builder.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
- name: Create a security group for ssh access to builder instances
amazon.aws.ec2_security_group:
name: "asz-security-group-ssh"
description: security group for ssh access to asz builders
region: "{{ aws_ec2_aarch64_region if target_arch == 'aarch64' else aws_ec2_x86_64_region }}"
rules:
- proto: tcp
ports:
- 22
cidr_ip: 0.0.0.0/0
rule_desc: allow all on port 22
state: present

- name: Create a basic ec2 instance with ssh key
amazon.aws.ec2_instance:
name: "asz-server-{{ server_id }}"
key_name: "{{ aws_ec2_aarch64_ssh_key if target_arch == 'aarch64' else aws_ec2_x86_64_ssh_key }}"
instance_type: "{{ aws_ec2_aarch64_instance_type if target_arch == 'aarch64' else aws_ec2_x86_64_instance_type }}"
image_id: "{{ aws_ec2_aarch64_ami if target_arch == 'aarch64' else aws_ec2_x86_64_ami }}"
region: "{{ aws_ec2_aarch64_region if target_arch == 'aarch64' else aws_ec2_x86_64_region }}"
network:
assign_public_ip: true
delete_on_termination: true
security_groups:
- "asz-security-group-ssh"
tags:
asz: "1"
state: running
wait: true
35 changes: 35 additions & 0 deletions roles/aws-ec2-instantiate/tasks/main.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
- name: load variables
ansible.builtin.include_vars: ../../../config.yaml

# Prepare server id
- name: prepare random server id
ansible.builtin.set_fact:
server_id: "{{ lookup('community.general.random_string', length=4, special=false) }}"

- name: debug server id
ansible.builtin.debug:
msg: "server id: {{ server_id }}"

# Instantiate ec2 instance
- include_tasks: instantiate_builder.yaml

- meta: refresh_inventory

- name: prepare ansible hosts group for playbook usage
ansible.builtin.add_host:
name: "asz-server-{{ server_id }}"
groups: "asz_server"

- name: debug ansible host ip
ansible.builtin.debug:
msg: "{{ hostvars['asz-server-'+server_id].public_ip_address }}"

- name: wait_for_connection
ansible.builtin.wait_for:
port: 22
host: "{{ hostvars['asz-server-'+server_id].public_ip_address }}"
delay: 30
connect_timeout: 60
timeout: 300
remote_user: ec2-user
6 changes: 6 additions & 0 deletions roles/aws-ec2-teardown/tasks/main.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
- name: load variables
ansible.builtin.include_vars: ../../../config.yaml

# Teardown the hetzner server
- include_tasks: teardown_builder.yaml
7 changes: 7 additions & 0 deletions roles/aws-ec2-teardown/tasks/teardown_builder.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
- name: Ensure the server is absent (remove if needed)
amazon.aws.ec2_instance:
state: absent
region: "{{ aws_ec2_aarch64_region if target_arch == 'aarch64' else aws_ec2_x86_64_region }}"
instance_ids:
- "{{ hostvars['asz-server-'+server_id].instance_id }}"
Loading