-
Notifications
You must be signed in to change notification settings - Fork 31
Add a Terraform configuration to deploy lnt.llvm.org #128
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
Open
ldionne
wants to merge
1
commit into
llvm:main
Choose a base branch
from
ldionne:review/terraform
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+294
−0
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| name: Deploy lnt.llvm.org | ||
|
|
||
| on: | ||
| push: | ||
| branches: ['main'] | ||
| paths: | ||
| - '.github/workflows/deploy-lnt.llvm.org.yaml' | ||
| - 'deployment/*' | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| deploy: | ||
| runs-on: ubuntu-24.04 | ||
|
|
||
| steps: | ||
| - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 | ||
|
|
||
| - name: Setup Terraform | ||
| uses: hashicorp/setup-terraform@v3 | ||
|
|
||
| - name: Configure AWS Credentials | ||
| uses: aws-actions/configure-aws-credentials@v4 | ||
| with: | ||
| aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | ||
| aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | ||
|
|
||
| - name: Initialize Terraform | ||
| run: terraform -chdir=deployment init | ||
|
|
||
| - name: Apply Terraform changes | ||
| run: terraform -chdir=deployment apply -auto-approve | ||
| env: | ||
| TF_VAR_lnt_db_password: ${{ secrets.LNT_DB_PASSWORD }} | ||
| TF_VAR_lnt_auth_token: ${{ secrets.LNT_AUTH_TOKEN }} | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ | |
| .tox/ | ||
| /llvm_lnt.egg-info | ||
| build | ||
| deployment/.terraform | ||
| dist | ||
| docs/_build | ||
| lnt/server/ui/static/docs | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| This directory contains configuration files to deploy lnt.llvm.org. | ||
|
|
||
| The https://lnt.llvm.org instance gets re-deployed automatically whenever changes | ||
| are made to the configuration files under `deployment/` on the `main` branch via | ||
| a Github Action. Manually deploying the instance is also possible by directly using | ||
| Terraform: | ||
|
|
||
| ```bash | ||
| aws configure # provide appropriate access keys | ||
| terraform -chdir=deployment init | ||
| terraform -chdir=deployment plan # to see what will be done | ||
| terraform -chdir=deployment apply | ||
| ``` | ||
|
|
||
| At a high level, lnt.llvm.org is running in a Docker container on an EC2 instance. | ||
| The database is stored in an independent EBS storage that gets attached and detached | ||
| to/from the EC2 instance when it is created/destroyed, but the EBS storage has its own | ||
| independent life cycle (because we want the data to outlive any specific EC2 instance). | ||
|
|
||
| The state used by Terraform to track the current status of the instance, EBS storage, etc | ||
| is located in a S3 bucket defined in the Terraform file. It is updated automatically when | ||
| changes are performed via the `terraform` command-line. Terraform is able to access that | ||
| data via the AWS credentials that are set up by `aws configure`. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| LNT_DB_PASSWORD=${__db_password__} | ||
| LNT_AUTH_TOKEN=${__auth_token__} | ||
| LNT_IMAGE=${__lnt_image__} | ||
| LNT_HOST_PORT=${__lnt_host_port__} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| #!/bin/bash | ||
|
|
||
| # | ||
| # This is the startup script that gets executed when the EC2 instance running lnt.llvm.org | ||
| # is brought up. This script references some files under /etc/lnt that are put into place | ||
| # by cloud-init, which is specified in the Terraform configuration file. | ||
| # | ||
|
|
||
| set -e | ||
|
|
||
| echo "Installing docker" | ||
| sudo yum update -y | ||
| sudo yum install -y docker | ||
| docker --version | ||
|
|
||
| echo "Installing docker compose" | ||
| sudo mkdir -p /usr/local/lib/docker/cli-plugins | ||
| sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-linux-$(uname -m) \ | ||
| -o /usr/local/lib/docker/cli-plugins/docker-compose | ||
| sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose | ||
| docker compose version | ||
|
|
||
| echo "Starting the Docker service" | ||
| sudo service docker start | ||
| sudo systemctl enable docker # also ensure the Docker service starts on reboot | ||
|
|
||
| if ! lsblk --output FSTYPE -f /dev/sdh | grep --quiet ext4; then | ||
| echo "Formatting /dev/sdh -- this is a new EBS volume" | ||
| sudo mkfs -t ext4 /dev/sdh | ||
| else | ||
| echo "/dev/sdh already contains a filesystem -- reusing previous EBS volume" | ||
| fi | ||
|
|
||
| echo "Mounting EBS volume with persistent information at /persistent-state" | ||
| sudo mkdir /persistent-state | ||
| sudo mount /dev/sdh /persistent-state | ||
|
|
||
| echo "Creating folders to map volumes in the Docker container to locations on the EC2 instance" | ||
| sudo mkdir -p /persistent-state/var/lib/lnt | ||
| (cd /var/lib && ln -s /persistent-state/var/lib/lnt lnt) | ||
| sudo mkdir -p /persistent-state/var/lib/postgresql | ||
| (cd /var/lib && ln -s /persistent-state/var/lib/postgresql postgresql) | ||
| sudo mkdir -p /var/log/lnt # logs are not persisted | ||
|
|
||
| echo "Starting LNT service with Docker compose" | ||
| sudo docker compose --file /etc/lnt/compose.yaml \ | ||
| --file /etc/lnt/ec2-volume-mapping.yaml \ | ||
| --env-file /etc/lnt/compose.env \ | ||
| up --detach |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| # | ||
| # This file maps volumes in the Docker container to actual locations on the EC2 instance. | ||
| # We basically bind the volumes inside the Docker image to the same filesystem location | ||
| # on the EC2 instance (e.g. /var/lib/lnt -> /var/lib/lnt) for ease of access. | ||
| # | ||
|
|
||
| volumes: | ||
| instance: | ||
| driver: local | ||
| driver_opts: | ||
| o: bind | ||
| type: none | ||
| device: /var/lib/lnt | ||
|
|
||
| logs: | ||
| driver: local | ||
| driver_opts: | ||
| o: bind | ||
| type: none | ||
| device: /var/log/lnt | ||
|
|
||
| database: | ||
| driver: local | ||
| driver_opts: | ||
| o: bind | ||
| type: none | ||
| device: /var/lib/postgresql |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,154 @@ | ||
| # | ||
| # Terraform file for deploying lnt.llvm.org. | ||
| # | ||
|
|
||
| variable "lnt_db_password" { | ||
| type = string | ||
| description = "The database password for the lnt.llvm.org database." | ||
| sensitive = true | ||
| } | ||
|
|
||
| variable "lnt_auth_token" { | ||
| type = string | ||
| description = "The authentication token to perform destructive operations on lnt.llvm.org." | ||
| sensitive = true | ||
| } | ||
|
|
||
| locals { | ||
| # The Docker image to use for the webserver part of the LNT service | ||
| lnt_image = "d9ffa5317a9a42a1d2fa337cba97ec51d931f391" | ||
|
|
||
| # The port on the EC2 instance used by the Docker webserver for communication | ||
| lnt_host_port = "80" | ||
| } | ||
|
|
||
| terraform { | ||
| backend "s3" { | ||
| bucket = "lnt.llvm.org-test-bucket" # TODO: Adjust this for the real LLVM Foundation account | ||
| key = "terraform.tfstate" | ||
| region = "us-west-2" | ||
| encrypt = true | ||
| } | ||
| } | ||
|
|
||
| locals { | ||
| availability_zone = "us-west-2a" | ||
| } | ||
|
|
||
| provider "aws" { | ||
| region = "us-west-2" | ||
| } | ||
|
|
||
| # | ||
| # Setup the EC2 instance | ||
| # | ||
| data "aws_ami" "amazon_linux_2023" { | ||
| most_recent = true | ||
| owners = ["amazon"] | ||
|
|
||
| filter { | ||
| name = "name" | ||
| values = ["al2023-ami-ecs-hvm-*-kernel-*-x86_64"] | ||
| } | ||
| } | ||
|
|
||
| data "cloudinit_config" "startup_scripts" { | ||
| base64_encode = true | ||
|
|
||
| part { | ||
| filename = "ec2-startup.sh" | ||
| content_type = "text/x-shellscript" | ||
| content = file("${path.module}/ec2-startup.sh") | ||
| } | ||
|
|
||
| part { | ||
| content_type = "text/cloud-config" | ||
| content = yamlencode({ | ||
| write_files = [ | ||
| { | ||
| path = "/etc/lnt/compose.yaml" | ||
| permissions = "0400" # read-only for owner | ||
| content = file("${path.module}/../docker/compose.yaml") | ||
| }, | ||
| { | ||
| path = "/etc/lnt/ec2-volume-mapping.yaml" | ||
| permissions = "0400" # read-only for owner | ||
| content = file("${path.module}/ec2-volume-mapping.yaml") | ||
| }, | ||
| { | ||
| path = "/etc/lnt/compose.env" | ||
| permissions = "0400" # read-only for owner | ||
| content = templatefile("${path.module}/compose.env.tpl", { | ||
| __db_password__ = var.lnt_db_password, | ||
| __auth_token__ = var.lnt_auth_token, | ||
| __lnt_image__ = local.lnt_image, | ||
| __lnt_host_port__ = local.lnt_host_port, | ||
| }) | ||
| } | ||
| ] | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| resource "aws_security_group" "server" { | ||
| name = "lnt.llvm.org/server-security-group" | ||
| description = "Allow SSH and HTTP traffic" | ||
|
|
||
| ingress { | ||
| description = "Allow incoming SSH traffic from anywhere" | ||
| from_port = 22 | ||
| to_port = 22 | ||
| protocol = "tcp" | ||
| cidr_blocks = ["0.0.0.0/0"] | ||
| } | ||
|
|
||
| ingress { | ||
| description = "Allow incoming HTTP traffic from anywhere" | ||
| from_port = 80 | ||
| to_port = 80 | ||
| protocol = "tcp" | ||
| cidr_blocks = ["0.0.0.0/0"] | ||
| } | ||
|
|
||
| egress { | ||
| description = "Allow outgoing traffic to anywhere" | ||
| from_port = 0 | ||
| to_port = 0 | ||
| protocol = "-1" | ||
| cidr_blocks = ["0.0.0.0/0"] | ||
| } | ||
| } | ||
|
|
||
| resource "aws_instance" "server" { | ||
| ami = data.aws_ami.amazon_linux_2023.id | ||
| availability_zone = local.availability_zone | ||
| instance_type = "t2.micro" # TODO: Adjust the size of the real instance | ||
| associate_public_ip_address = true | ||
| security_groups = [aws_security_group.server.name] | ||
| tags = { | ||
| Name = "lnt.llvm.org/server" | ||
| } | ||
|
|
||
| user_data_base64 = data.cloudinit_config.startup_scripts.rendered | ||
| } | ||
|
|
||
| # | ||
| # Setup the EBS volume attached to the instance that stores the DB | ||
| # and other instance-related configuration (e.g. the schema files, | ||
| # profiles and anything else that should persist). | ||
| # | ||
| resource "aws_ebs_volume" "persistent_state" { | ||
| availability_zone = local.availability_zone | ||
| # TODO: Put a real size once we're ready to go to production | ||
| size = 20 # GiB | ||
| type = "gp2" | ||
| tags = { | ||
| Name = "lnt.llvm.org/persistent-state" | ||
| } | ||
| } | ||
|
|
||
| resource "aws_volume_attachment" "persistent_state_attachment" { | ||
| instance_id = aws_instance.server.id | ||
| volume_id = aws_ebs_volume.persistent_state.id | ||
| device_name = "/dev/sdh" | ||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.