Skip to content

Commit

Permalink
Merge pull request #102 from unity-sds/mplotkin-dev-01
Browse files Browse the repository at this point in the history
MMGIS Terraform code deploys without error
  • Loading branch information
galenatjpl authored Sep 17, 2024
2 parents 64dfea7 + 11e965e commit 2b5ff0d
Show file tree
Hide file tree
Showing 10 changed files with 759 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@ aws_role_create/identity.txt
aws_role_create/output.txt
aws_role_create/policies.list
aws_role_create/role.txt

MMGIS-IAC/terraform/.terraform
MMGIS-IAC/terraform/.terraform*
55 changes: 55 additions & 0 deletions MMGIS-IAC/terraform/modules/ec2-docker/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
64 changes: 64 additions & 0 deletions MMGIS-IAC/terraform/modules/ec2-docker/bk.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
locals {
block_device_path = "/dev/sdh"
}

data "aws_iam_role" "existing_role" {
name = "Unity-CS_Service_Role"
}

data "aws_ssm_parameter" "mmgis_ami_id" {
name = "/mcp/amis/ubuntu2004-cset"
}

data "aws_ssm_parameter" "subnet_id" {
name = "/unity/account/network/publicsubnet1"
}

resource "aws_security_group" "allow_tls" {
name = "allow_tls"
description = "Allow TLS inbound traffic and all outbound traffic"
vpc_id = data.aws_ssm_parameter.vpc_id.value

tags = {
Name = "allow_tls"
}
}

resource "aws_iam_instance_profile" "unity_mmgis_instance_profile" {
name = "unity-mmgis-instance-profile-tf"

role = data.aws_iam_role.existing_role.name

tags = {
Name = "unity_mmgis_instance_profile"
}
}

resource "aws_ebs_volume" "persistent" {
availability_zone = aws_instance.unity_mmgis_instance.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.unity_mmgis_instance.id
}


resource "aws_instance" "unity_mmgis_instance" {
ami = data.aws_ssm_parameter.mmgis_ami_id.value
instance_type = var.instance_type

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

vpc_security_group_ids = [ aws_security_group.allow_tls.id ]

subnet_id = data.aws_ssm_parameter.subnet_id.value

iam_instance_profile = aws_iam_instance_profile.unity_mmgis_instance_profile.name

user_data = file("./modules/ec2-docker/add-mmgis.sh")
}
70 changes: 70 additions & 0 deletions MMGIS-IAC/terraform/modules/ec2-docker/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 = data.aws_ssm_parameter.vpc_id.value

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 = jsondecode(data.aws_ssm_parameter.subnet_list.value).public

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"
}
}
18 changes: 18 additions & 0 deletions MMGIS-IAC/terraform/modules/ec2-docker/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
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"
#}


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"])
}
84 changes: 84 additions & 0 deletions MMGIS-IAC/terraform/modules/ec2-docker/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.unity_mmgis_instance.id
}

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

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

output "placement_group" {
description = "The placement group of the instance"
value = aws_instance.unity_mmgis_instance.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.unity_mmgis_instance.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.unity_mmgis_instance.public_ip
}

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

output "primary_network_interface_id" {
description = "The ID of the instance's primary network interface"
value = aws_instance.unity_mmgis_instance.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.unity_mmgis_instance.private_dns
}

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

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

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

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

output "credit_specification" {
description = " Credit specification of instance."
value = aws_instance.unity_mmgis_instance.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.unity_mmgis_instance.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 2b5ff0d

Please sign in to comment.