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

#542 Add Unity tf #543

Merged
merged 4 commits into from
Jul 16, 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
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
Loading