Skip to content

Commit

Permalink
#542 Add Unity tf (#543)
Browse files Browse the repository at this point in the history
* #542 Add Unity tf

* #542 Add Unity tf 2

* #542 Add all ENVs to tf

* #542 Update unity terraform
  • Loading branch information
tariqksoliman authored Jul 16, 2024
1 parent 2984c1d commit 3c7bae9
Show file tree
Hide file tree
Showing 7 changed files with 700 additions and 0 deletions.
55 changes: 55 additions & 0 deletions sds/unity/terraform/add-mmgis.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/bin/bash
# From https://gist.github.com/jamesmishra/18ee5d7d053db9958d0e4ccbb37f8e1d
set -Eeuxo pipefail
# Filesystem code is adapted from:
# https://github.com/GSA/devsecops-example/blob/03067f68ee2765f8477ae84235f7faa1d2f2cb70/terraform/files/attach-data-volume.sh
DEVICE=${local.block_device_path}
DEST=${var.persistent_volume_mount_path}
devpath=$(readlink -f $DEVICE)

if [[ $(file -s $devpath) != *ext4* && -b $devpath ]]; then
# Filesystem has not been created. Create it!
mkfs -t ext4 $devpath
fi
# add to fstab if not present
if ! egrep "^$devpath" /etc/fstab; then
echo "$devpath $DEST ext4 defaults,nofail,noatime,nodiratime,barrier=0,data=writeback 0 2" | tee -a /etc/fstab > /dev/null
fi
mkdir -p $DEST
mount $DEST
chown ec2-user:ec2-user $DEST
chmod 0755 $DEST

# Filesystem code is over
# Now we install docker and docker-compose.
# Adapted from:
# https://gist.github.com/npearce/6f3c7826c7499587f00957fee62f8ee9
yum update -y
amazon-linux-extras install docker
systemctl start docker.service
usermod -a -G docker ec2-user
chkconfig docker on
yum install -y python3-pip
python3 -m pip install docker-compose

# Put the docker-compose.yml file at the root of our persistent volume
cat > $DEST/docker-compose.yml <<-TEMPLATE
${var.docker_compose_str}
TEMPLATE

# Write the systemd service that manages us bringing up the service
cat > /etc/systemd/system/mmgis.service <<-TEMPLATE
[Unit]
Description=${var.description}
After=${var.systemd_after_stage}
[Service]
Type=simple
User=${var.user}
ExecStart=/usr/local/bin/docker-compose -f $DEST/docker-compose.yml up
Restart=on-failure
[Install]
WantedBy=multi-user.target
TEMPLATE

# Start the service.
systemctl start mmgis
58 changes: 58 additions & 0 deletions sds/unity/terraform/bk.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
resource "aws_iam_instance_profile" "unity_mmgis_instance_profile" {
name = "unity-mmgis-instance-profile-tf"

role = var.role

tags = {
Name = "unity_mmgis_instance_profile"
}
}

resource "aws_instance" "unity_mmgis_instance" {
ami = var.ami
instance_type = "t3.large"

tags = {
Name = "unity-mmgis-instance-tf"
}

#key_name = var.key_name

vpc_security_group_ids = [var.sg_id]

subnet_id = var.subnet_id

iam_instance_profile = aws_iam_instance_profile.unity_mmgis_instance_profile.name

block_device_path = "/dev/sdh"
user_data = file("./add-mmgis.sh")
}

resource "aws_ebs_volume" "persistent" {
availability_zone = aws_instance.this.availability_zone
size = var.persistent_volume_size_gb
}

resource "aws_volume_attachment" "persistent" {
device_name = local.block_device_path
volume_id = aws_ebs_volume.persistent.id
instance_id = aws_instance.this.id
}

resource "aws_instance" "this" {
ami = data.aws_ami.latest_amazon_linux.id
availability_zone = var.availability_zone
instance_type = var.instance_type
key_name = var.key_name
associate_public_ip_address = var.associate_public_ip_address
vpc_security_group_ids = var.vpc_security_group_ids
subnet_id = var.subnet_id
iam_instance_profile = var.iam_instance_profile
user_data = local.user_data
tags = merge (
{
Name = var.name
},
var.tags
)
}
70 changes: 70 additions & 0 deletions sds/unity/terraform/lb.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# target group
resource "aws_lb_target_group" "unity_mmgis_tg_tf" {
name = "unity-mmgis-tg-tf"
port = 8080
protocol = "TCP"
target_type = "instance"
#vpc_id = data.aws_vpc.default.id
vpc_id = var.vpc_id

health_check {
enabled = true
protocol = "HTTP"
port = 8080
path = "/unity/v0/collections/MUR25-JPL-L4-GLOB-v4.2_analysed_sst/processes"
interval = 30
timeout = 10
matcher = 200
healthy_threshold = 5
unhealthy_threshold = 2
}

tags = {
Name = "unity_mmgis_tg_tf"
}
}

# attach instance
resource "aws_lb_target_group_attachment" "unity_mmgis_tg_attachment_tf" {
target_group_arn = aws_lb_target_group.unity_mmgis_tg_tf.arn
target_id = aws_instance.unity_mmgis_instance.id
port = 8080
}

# create alb
resource "aws_lb" "unity-mmgis-lb-tf" {
name = "unity-mmgis-lb-tf"
load_balancer_type = "network"
internal = true
#security_groups = [var.sg_id]
#security_groups = []
#subnets = [for subnet in aws_subnet.public : subnet.id]
subnets = var.subnet_ids

enable_deletion_protection = false

#access_logs {
# bucket = "tbd"
# prefix = "mmgis/tbd/unity-mmgis-lb"
# enabled = true
#}

tags = {
Name = "unity-mmgis-lb-tf"
}
}

resource "aws_lb_listener" "unity_mmgis_lb_listener" {
load_balancer_arn = aws_lb.unity-mmgis-lb-tf.arn
port = 80
protocol = "TCP"

default_action {
type = "forward"
target_group_arn = aws_lb_target_group.unity_mmgis_tg_tf.arn
}

tags = {
Name = "unity_mmgis_lb_listener"
}
}
99 changes: 99 additions & 0 deletions sds/unity/terraform/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
data "aws_ssm_parameter" "vpc_id" {
name = "/unity/account/network/vpc_id"
}

data "aws_ssm_parameter" "subnet_list" {
name = "/unity/account/network/subnet_list"
}

#data "aws_ssm_parameter" "u-cs-ecs" {
# name = "/unity/account/ecs/execution_role_arn"
#}

module "base" {
source = ""
project = var.project
venue = var.venue
subsystem = var.subsystem
capability = var.capability
custom_url = var.custom_url
groups = var.groups
api = var.api
component = var.component
desired_count = var.desired_count
app_protocol = var.app_protocol
app_listening_port = var.app_listening_port
environment = local.environment_vars
ecr_uri = var.ecr_uri
docker_image_name = var.docker_image_name
docker_image_tag = var.docker_image_tag
max_capacity = var.max_capacity
app_one_ecs = var.app_one_ecs
instance_type = var.instance_type
ebs_block_device_size = var.ebs_block_device_size
root_block_device_size = var.root_block_device_size
ebs_mount_directory = var.ebs_mount_directory
application_endpoint_url = var.application_endpoint_url
terraform_app_commit = var.terraform_app_commit
deployment_method = var.deployment_method
secrets = local.secrets
docker_volume_path = var.docker_volume_path
efs_config = {
efs_id = var.efs_id
efs_root_directory = var.efs_root_directory
}
}

locals {
subnet_map = jsondecode(data.aws_ssm_parameter.subnet_list.value)
subnet_ids = nonsensitive(local.subnet_map["private"])
public_subnet_ids = nonsensitive(local.subnet_map["public"])
}


# Application environment variables
locals {
environment_vars = {
AWS_DEFAULT_REGION = module.base.aws_region
DOMAIN = module.base.cname
SERVER = var.server
AUTH = var.auth
NODE_ENV = var.node_env
DB_HOST = var.db_host
DB_PORT = var.db_port
DB_NAME = var.db_name
DB_USER = var.db_user
PORT = var.app_listening_port
DB_POOL_MAX = var.db_pool_max
DB_POOL_TIMEOUT = var.db_pool_timeout
DB_POOL_IDLE = var.db_pool_idle
CSSO_GROUPS = var.csso_groups
VERBOSE_LOGGING = var.verbose_logging
FRAME_ANCESTORS = var.frame_ancestors
FRAME_SRC = var.frame_src
THIRD_PARTY_COOKIES = var.third_party_cookies
ROOT_PATH = var.root_path
WEBSOCKET_ROOT_PATH = var.websocket_root_path
CLEARANCE_NUMBER = var.clearance_number
DISABLE_LINK_SHORTENER = var.disable_link_shortener
HIDE_CONFIG = var.hide_config
FORCE_CONFIG_PATH = var.force_config_path
LEADS = "[${join(", ", formatlist("\"%s\"", var.leads))}]"
ENABLE_MMGIS_WEBSOCKETS = var.enable_mmgis_websockets
ENABLE_CONFIG_WEBSOCKETS = var.enable_config_websockets
ENABLE_CONFIG_OVERRIDE = var.enable_config_override
MAIN_MISSION = var.main_mission
SKIP_CLIENT_INITIAL_LOGIN = var.skip_client_initial_login
GENERATE_SOURCEMAP = var.generate_sourcemap
SPICE_SCHEDULED_KERNEL_DOWNLOAD = var.spice_scheduled_kernel_download
SPICE_SCHEDULED_KERNEL_DOWNLOAD_ON_START = var.spice_scheduled_kernel_download_on_start
SPICE_SCHEDULED_KERNEL_cron_expr = var.spice_scheduled_kernel_cron_expr
}
}

locals {
secrets = {
SECRET = var.secret
DB_PASS = var.db_pass
}
}
84 changes: 84 additions & 0 deletions sds/unity/terraform/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# We try to match the API contract that `aws_instance` has.
# Descriptions for these outputs are copied from:
# https://www.terraform.io/docs/providers/aws/r/instance.html
output "id" {
description = "The instance ID"
value = aws_instance.this.id
}

output "arn" {
description = "The ARN of the instance"
value = aws_instance.this.arn
}

output "availability_zone" {
description = "The availability zone of the instance"
value = aws_instance.this.availability_zone
}

output "placement_group" {
description = "The placement group of the instance"
value = aws_instance.this.placement_group
}

output "public_dns" {
description = "The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC"
value = aws_instance.this.public_dns
}

output "public_ip" {
description = "The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws_eip with your instance, you should refer to the EIP's address directly and not use public_ip, as this field will change after the EIP is attached."
value = aws_instance.this.public_ip
}

output "ipv6_addresses" {
description = "A list of assigned IPv6 addresses, if any"
value = aws_instance.this.ipv6_addresses
}

output "primary_network_interface_id" {
description = "The ID of the instance's primary network interface"
value = aws_instance.this.primary_network_interface_id
}

output "private_dns" {
description = " The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC"
value = aws_instance.this.private_dns
}

output "private_ip" {
description = "The private IP address assigned to the instance"
value = aws_instance.this.private_ip
}

output "security_groups" {
description = " The associated security groups."
value = aws_instance.this.security_groups
}

output "vpc_security_group_ids" {
description = "The associated security groups in non-default VPC."
value = aws_instance.this.vpc_security_group_ids
}

output "subnet_id" {
description = "The VPC subnet ID."
value = aws_instance.this.subnet_id
}

output "credit_specification" {
description = " Credit specification of instance."
value = aws_instance.this.credit_specification
}

output "instance_state" {
description = "The state of the instance. One of: pending, running, shutting-down, terminated, stopping, stopped. See Instance Lifecycle for more information."
value = aws_instance.this.instance_state
}

# TODO: This is a list with the `aws_instance` resource and we are just
# returning a string. I know there is an obvious solution for this...
output "ebs_block_device_id" {
description = "The persistent block device that we are storing information on."
value = aws_ebs_volume.persistent.id
}
Loading

0 comments on commit 3c7bae9

Please sign in to comment.