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

Tarraform Integration #1

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from
Draft
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
45 changes: 45 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,48 @@ cython_debug/

# PyPI configuration file
.pypirc

# Local .terraform directories
terraform/.terraform

# .tfstate files
*.tfstate
*.tfstate.*

# Crash log files
crash.log
crash.*.log

# Exclude all .tfvars files, which are likely to contain sensitive data, such as
# password, private keys, and other secrets. These should not be part of version
# control as they are data points which are potentially sensitive and subject
# to change depending on the environment.
*.tfvars
*.tfvars.json

# Ignore override files as they are usually used to override resources locally and so
# are not checked in
terraform/override.tf
terraform/override.tf.json
terraform/*_override.tf
terraform/*_override.tf.json

# Ignore transient lock info files created by terraform apply
terraform/.terraform.tfstate.lock.info

# Include override files you do wish to add to version control using negated pattern
# !example_override.tf

# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
# example: *tfplan*

# Ignore CLI configuration files
terraform/.terraformrc
terraform/terraform.rc

# Ignore credentials file (any json file that starts with "vmassign-dev-")
terraform/vmassign-dev-*.json
terraform/service-account-*.json

# ignore DS_Store files
.DS_Store
20 changes: 20 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Use a lightweight Python base image
FROM python:3.9-slim

# Set the working directory in the container
WORKDIR /app

# Copy the requirements file
COPY app/requirements.txt requirements.txt

# Install Python dependencies
RUN pip install -r requirements.txt

# Copy the app code into the container
COPY ./app .

# Expose the port Flask will run on
EXPOSE 8080

# Command to run the Flask app
CMD ["python", "app.py"]
17 changes: 17 additions & 0 deletions app/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from flask import Flask

app = Flask(__name__)


@app.route("/")
def home():
return "Hello, World! This is a test Flask app."


@app.route("/health")
def health():
return {"status": "healthy"}, 200


if __name__ == "__main__":
app.run(host="0.0.0.0", port=8080)
1 change: 1 addition & 0 deletions app/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
flask==2.2.5
33 changes: 33 additions & 0 deletions create-service-account.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Project ID as an argument
PROJECT_ID=$1

# Create the service account
gcloud iam service-accounts create service-account-admin \
--description="Service account to create and manage other service accounts" \
--display-name="Service Account Admin" \
--project="${PROJECT_ID}"

# Grant roles to allow service account management
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:service-account-admin@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/iam.serviceAccountAdmin"

# Grant roles to allow assignment of roles to other service accounts
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:service-account-admin@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/iam.roleAdmin"

# Grant database admin roles
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:service-account-admin@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/spanner.admin"

# Grant cloud run deployment roles
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:service-account-admin@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/run.developer"

# Generate a key for the service account
gcloud iam service-accounts keys create terraform/service-account-admin-key.json \
--iam-account="service-account-admin@${PROJECT_ID}.iam.gserviceaccount.com" \
--project="${PROJECT_ID}"
41 changes: 41 additions & 0 deletions terraform/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 54 additions & 0 deletions terraform/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Terraform in Lablink

## Overview
This directory contains the Terraform configuration files for the Lablink project. The Terraform configuration files are used to create the infrastructure for the Lablink project. The infrastructure creates the following resources:

- A virtual machine (VM) instance in Google Cloud Platform (GCP) with SLEAP installed.
- A database instance in Google Spanner for VM assignment.
- A Cloud Run service for the Lablink API.

## Prerequisites

Before you can use the Terraform configuration files, running Terraform commands, you need to install Terraform. You can install Terraform by following the instructions in the [Terraform documentation](https://learn.hashicorp.com/tutorials/terraform/install-cli).

Also, you need to have a Google Cloud Platform (GCP) account and a project in GCP. You can create a GCP account and a project in the [Google Cloud Platform Official Website](https://cloud.google.com/gcp).

After creating a GCP account and a project, you need to create a service account in GCP and download the service account key. You can create a service account by following the instructions in the [GCP Service Accounts documentation](https://cloud.google.com/iam/docs/creating-managing-service-accounts). After creating the service account, you need to download the service account key in JSON format. You can download the service account key by following the instructions in the [GCP Keys documentation](https://cloud.google.com/iam/docs/creating-managing-service-account-keys).

## Configuration

The Terraform configuration files are located in the `terraform` directory. The configuration files are organized as follows:

- `main.tf`: The main Terraform configuration file that defines the resources to create.
- `variables.tf`: The Terraform variables file that defines the input variables for the Terraform configuration files.
- `outputs.tf`: The Terraform outputs file that defines the output variables for the Terraform configuration files.
- `provider.tf`: The Terraform provider file that defines the provider for the Terraform configuration files.

## Installation

To install the Terraform configuration files, clone the repository:

```bash
git clone https://github.com/talmolab/lablink.git
```

## Usage

To use the Terraform configuration files, you need to run this command to initialize the Terraform configuration files:

```bash
cd terraform
terraform init
```

After initializing the Terraform configuration files, you can run the following command to create the infrastructure:

```bash
terraform apply
```

To destroy the infrastructure, you can run the following command:

```bash
terraform destroy
```
71 changes: 71 additions & 0 deletions terraform/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
locals {
project = var.project_id
service_name = "${var.resource_suffix}-cosyne-service"
database_name = "users"
}

# TODO: Add resources for Terraform to manage

# TODO: Parameterize testing/development values

# Create Spanner Database in the specific instance
resource "google_spanner_database" "default" {
name = local.database_name
instance = "vmassign-dev"
ddl = [
"CREATE TABLE Users (Hostname STRING(1024) NOT NULL, Pin STRING(1024), CrdCmd STRING(1024), UserEmail STRING(1024), inUse BOOL,) PRIMARY KEY (Hostname)"
]
deletion_protection = false
}

# Push an image to Google Container Registry
# NOTE: We can automate the process if we have the vmassign repo combined with this repo
# Google Artifact Registry
resource "google_artifact_registry_repository" "repo" {
format = "DOCKER"
location = "us-central1"
repository_id = "flask-app-repo"
}

# resource "null_resource" "docker_build_and_push" {
# provisioner "local-exec" {
# command = <<EOT
# gcloud auth configure-docker
# docker build -t us-central1-docker.pkg.dev/${var.project_id}/${google_artifact_registry_repository.repo.name}/flask-app:latest ../
# docker push us-central1-docker.pkg.dev/${var.project_id}/${google_artifact_registry_repository.repo.name}/flask-app:latest
# EOT
# }
# }

# Deployment using Cloud Run
resource "google_cloud_run_service" "flask_service" {
name = "flask-service"
location = "us-central1"

template {
spec {
containers {
image = "gcr.io/${google_artifact_registry_repository.repo.name}/flask-app:latest"

resources {
limits = {
memory = "256Mi"
cpu = "1"
}
}
}
}
}

traffic {
percent = 100
latest_revision = true
}
}

resource "google_cloud_run_service_iam_member" "invoker" {
service = google_cloud_run_service.flask_service.name
location = google_cloud_run_service.flask_service.location
role = "roles/run.invoker"
member = "allUsers"
}
1 change: 1 addition & 0 deletions terraform/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

14 changes: 14 additions & 0 deletions terraform/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "6.5.0"
}
}
}

provider "google" {
project = "vmassign-dev"
region = "us-west1"
credentials = "./vmassign-dev-2818ad83c3ff.json"
}
17 changes: 17 additions & 0 deletions terraform/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
variable "instance_name" {
description = "Name of the instance"
type = string
default = "web-server"
}

variable "project_id" {
description = "Target Project ID"
type = string
default = "vmassign-dev"
}

variable "resource_suffix" {
description = "Suffix to append to all resources"
type = string
default = "prod"
}