Skip to content

Commit

Permalink
Henrykie/helix swarm (#306)
Browse files Browse the repository at this point in the history
  • Loading branch information
henrykie authored Sep 30, 2024
1 parent 74550da commit 6cc2dd8
Show file tree
Hide file tree
Showing 31 changed files with 798 additions and 504 deletions.
112 changes: 59 additions & 53 deletions docs/media/diagrams/perforce-module-architectures.drawio

Large diffs are not rendered by default.

Binary file added docs/media/images/helix-swarm-architecture.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/media/images/helix-swarm-architecture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/media/images/perforce-complete-example.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions docs/modules/perforce/examples/complete.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Perforce Complete Example

This example provisions [Helix Core](https://www.perforce.com/products/helix-core), [Helix Swarm](https://www.perforce.com/products/helix-swarm), and the [Helix Authentication Service](https://www.perforce.com/downloads/helix-authentication-service). It also configures security groups for each of these modules to allow inter-service communication. This example takes a single input variable:`root_domain_name` is expected to correspond to an existing [AWS Route53 hosted zone](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/route-53-concepts.html#route-53-concepts-hosted-zone). This hosted zone is used for provisioning DNS records used for external and internal routing, and enables this example to create validated SSL certificates on your behalf.

If you do not have a domain yet you can [register one through Route53](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/domain-register.html#domain-register-procedure-section).

If you already have a domain with a different domain registrar you can leverage Route53 for DNS services. [Please review the documentation for migrating to Route53 as your DNS provider.](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/MigratingDNS.html)

If you own the domain: "example.com" this example will deploy Helix Core to "core.helix.example.com" and Helix Swarm to "swarm.helix.example.com" - this can be modified from the `dns.tf` file.

## Deployment Architecture

![Perforce Example Architecture](../../../media/images/perforce-complete-example.jpg)
7 changes: 4 additions & 3 deletions docs/modules/perforce/helix-swarm/helix-swarm.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@

[Perforce Helix Swarm](https://www.perforce.com/products/helix-swarm) is a free code review tool for projects hosted in [Perforce Helix Core](https://www.perforce.com/products/helix-core). This module deploys Helix Swarm as a service on AWS Elastic Container Service using the [publicly available image from Dockerhub](https://hub.docker.com/r/perforce/helix-swarm).

Helix Swarm also relies on a Redis cache. The module runs Redis as a service alongside Helix Swarm as part of the same task definition.
Helix Swarm also relies on a Redis cache. The module provisions a single node AWS Elasticache Redis OSS cluster and configures connectivity for the Helix Swarm service.

This module deploys the following resources:

- An Elastic Container Service (ECS) cluster backed by AWS Fargate. This can also be created externally and passed in via the `cluster_name` variable.
- An ECS service running the latest Helix Swarm container ([perforce/helix-swarm](https://hub.docker.com/r/perforce/helix-swarm)) available and a Redis sidecar.
- An ECS service running the latest Helix Swarm container ([perforce/helix-swarm](https://hub.docker.com/r/perforce/helix-swarm)) available.
- An Application Load Balancer for TLS termination of the Helix Swarm service.
- A single node [AWS Elasticache Redis OSS](https://aws.amazon.com/elasticache/redis/) cluster.
- Supporting resources such as Cloudwatch log groups, IAM roles, and security groups.

## Deployment Architecture
![HelixSwarm Module Architecture](../../../media/images/helix-swarm-architecture.png)
![Helix Swarm Module Architecture](../../../media/images/helix-swarm-architecture.png){: style="max-width:100%;max-height:100vh;margin:auto"}

## Prerequisites

Expand Down
15 changes: 15 additions & 0 deletions docs/modules/perforce/perforce.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Perforce

[Perforce](https://www.perforce.com/) provides a number of products commonly used in Game development. The modules included in the Cloud Game Development Toolkit provision [Helix Core](https://www.perforce.com/products/helix-core), [Helix Swarm](https://www.perforce.com/products/helix-swarm), and the [Helix Authentication Service](https://www.perforce.com/downloads/helix-authentication-service). These modules can be stitched together to provision version control and code review tools for your developers.

## Modules

| Template | Description |
| :--------------------------------------------------------------- | :- |
| [__Helix Core__](./helix-core/helix-core.md) | A Terraform module for provisioning a [Helix Core](https://www.perforce.com/products/helix-core) version control server on AWS EC2. |
| [__Helix Swarm__](./helix-swarm/helix-swarm.md) | A Terraform module for provisioning [Helix Swarm](https://www.perforce.com/products/helix-swarm) on AWS Elastic Container Service. |
| [__Helix Authentication Service__](./helix-authentication-service/helix-authentication-service.md) | A Terraform module for provisioning the [Helix Authentication Service](https://www.perforce.com/downloads/helix-authentication-service) on AWS Elastic Container Service. |

## Examples

We currently provide a single, [complete example](./examples/complete.md) demonstrating deployment of all three modules in a single VPC. This example configures connectivity between each of the three modules and creates DNS records in an existing [AWS Route53](https://aws.amazon.com/route53/) for simple routing. Please use it as a starting point for your Perforce version control and code review deployments.
105 changes: 105 additions & 0 deletions modules/perforce/examples/complete/dns.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@

##########################################
# Route53 Hosted Zone for FQDN
##########################################
data "aws_route53_zone" "root" {
name = var.root_domain_name
private_zone = false
}

##########################################
# Perforce Helix DNS
##########################################
resource "aws_route53_zone" "helix_private_zone" {
name = "helix.perforce.internal"
#checkov:skip=CKV2_AWS_38: Hosted zone is private (vpc association)
#checkov:skip=CKV2_AWS_39: Query logging disabled by design
vpc {
vpc_id = aws_vpc.perforce_vpc.id
}
}


resource "aws_route53_record" "helix_swarm" {
zone_id = data.aws_route53_zone.root.id
name = "swarm.helix.${data.aws_route53_zone.root.name}"
type = "A"
alias {
name = module.perforce_helix_swarm.alb_dns_name
zone_id = module.perforce_helix_swarm.alb_zone_id
evaluate_target_health = true
}
}

resource "aws_route53_record" "helix_authentication_service" {
zone_id = data.aws_route53_zone.root.zone_id
name = "auth.helix.${data.aws_route53_zone.root.name}"
type = "A"
alias {
name = module.perforce_helix_authentication_service.alb_dns_name
zone_id = module.perforce_helix_authentication_service.alb_zone_id
evaluate_target_health = true
}
}

resource "aws_route53_record" "perforce_helix_core" {
zone_id = data.aws_route53_zone.root.zone_id
name = "core.helix.${data.aws_route53_zone.root.name}"
type = "A"
ttl = 300
#checkov:skip=CKV2_AWS_23:The attached resource is managed by CGD Toolkit
records = [module.perforce_helix_core.helix_core_eip_public_ip]
}

resource "aws_route53_record" "perforce_helix_core_pvt" {
zone_id = aws_route53_zone.helix_private_zone.zone_id
name = "core.${aws_route53_zone.helix_private_zone.name}"
type = "A"
ttl = 300
#checkov:skip=CKV2_AWS_23:The attached resource is managed by CGD Toolkit
records = [module.perforce_helix_core.helix_core_eip_private_ip]
}

##########################################
# Helix Certificate Management
##########################################

resource "aws_acm_certificate" "helix" {
domain_name = "helix.${var.root_domain_name}"
subject_alternative_names = ["*.helix.${var.root_domain_name}"]

validation_method = "DNS"

tags = {
Environment = "dev"
}

lifecycle {
create_before_destroy = true
}
}

resource "aws_route53_record" "helix_cert" {
for_each = {
for dvo in aws_acm_certificate.helix.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
}

allow_overwrite = true
name = each.value.name
records = [each.value.record]
ttl = 60
type = each.value.type
zone_id = data.aws_route53_zone.root.id
}

resource "aws_acm_certificate_validation" "helix" {
timeouts {
create = "15m"
}
certificate_arn = aws_acm_certificate.helix.arn
validation_record_fqdns = [for record in aws_route53_record.helix_cert : record.fqdn]
}
13 changes: 13 additions & 0 deletions modules/perforce/examples/complete/local.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
data "aws_availability_zones" "available" {}

locals {
# VPC Configuration
vpc_cidr_block = "10.0.0.0/16"
public_subnet_cidrs = ["10.0.1.0/24", "10.0.2.0/24"]
private_subnet_cidrs = ["10.0.3.0/24", "10.0.4.0/24"]

tags = {
environment = "cgd"
}
azs = slice(data.aws_availability_zones.available.names, 0, 2)
}
88 changes: 88 additions & 0 deletions modules/perforce/examples/complete/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
##########################################
# Shared ECS Cluster for Services
##########################################

resource "aws_ecs_cluster" "perforce_cluster" {
name = "perforce-cluster"

setting {
name = "containerInsights"
value = "enabled"
}
}

resource "aws_ecs_cluster_capacity_providers" "providers" {
cluster_name = aws_ecs_cluster.perforce_cluster.name

capacity_providers = ["FARGATE"]

default_capacity_provider_strategy {
base = 1
weight = 100
capacity_provider = "FARGATE"
}
}

##########################################
# Perforce Helix Core
##########################################

module "perforce_helix_core" {
source = "../../helix-core"
vpc_id = aws_vpc.perforce_vpc.id
server_type = "p4d_commit"
instance_subnet_id = aws_subnet.public_subnets[0].id
instance_type = "c6g.large"
instance_architecture = "arm64"

storage_type = "EBS"
depot_volume_size = 64
metadata_volume_size = 32
logs_volume_size = 32

fully_qualified_domain_name = "core.helix.perforce.${var.root_domain_name}"

helix_authentication_service_url = "https://${aws_route53_record.helix_authentication_service.name}"
}

##########################################
# Perforce Helix Authentication Service
##########################################

module "perforce_helix_authentication_service" {
source = "../../helix-authentication-service"
vpc_id = aws_vpc.perforce_vpc.id
cluster_name = aws_ecs_cluster.perforce_cluster.name
helix_authentication_service_alb_subnets = aws_subnet.public_subnets[*].id
helix_authentication_service_subnets = aws_subnet.private_subnets[*].id
certificate_arn = aws_acm_certificate.helix.arn

enable_web_based_administration = true
fully_qualified_domain_name = "auth.helix.${var.root_domain_name}"

depends_on = [aws_ecs_cluster.perforce_cluster, aws_acm_certificate_validation.helix]
}

##########################################
# Perforce Helix Swarm
##########################################

module "perforce_helix_swarm" {
source = "../../helix-swarm"
vpc_id = aws_vpc.perforce_vpc.id
cluster_name = aws_ecs_cluster.perforce_cluster.name
helix_swarm_alb_subnets = aws_subnet.public_subnets[*].id
helix_swarm_service_subnets = aws_subnet.private_subnets[*].id
certificate_arn = aws_acm_certificate.helix.arn
p4d_port = "ssl:${aws_route53_record.perforce_helix_core_pvt.name}:1666"
p4d_super_user_arn = module.perforce_helix_core.helix_core_super_user_username_secret_arn
p4d_super_user_password_arn = module.perforce_helix_core.helix_core_super_user_password_secret_arn
p4d_swarm_user_arn = module.perforce_helix_core.helix_core_super_user_username_secret_arn
p4d_swarm_password_arn = module.perforce_helix_core.helix_core_super_user_password_secret_arn

enable_sso = true

fully_qualified_domain_name = "swarm.helix.${var.root_domain_name}"

depends_on = [aws_ecs_cluster.perforce_cluster, aws_acm_certificate_validation.helix]
}
33 changes: 33 additions & 0 deletions modules/perforce/examples/complete/security.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
##########################################
# Internal Access - service to service
##########################################

# Helix Swarm -> Helix Core
resource "aws_vpc_security_group_ingress_rule" "helix_core_inbound_swarm" {
security_group_id = module.perforce_helix_core.security_group_id
ip_protocol = "TCP"
from_port = 1666
to_port = 1666
referenced_security_group_id = module.perforce_helix_swarm.service_security_group_id
description = "Enables Helix Swarm to access Helix Core."
}

# Helix Core -> Helix Swarm
resource "aws_vpc_security_group_ingress_rule" "helix_swarm_inbound_core" {
security_group_id = module.perforce_helix_swarm.alb_security_group_id
ip_protocol = "TCP"
from_port = 443
to_port = 443
cidr_ipv4 = "${module.perforce_helix_core.helix_core_eip_public_ip}/32"
description = "Enables Helix Core to access Helix Swarm"
}

# Helix Core -> Helix Authentication Service
resource "aws_vpc_security_group_ingress_rule" "helix_auth_inbound_core" {
security_group_id = module.perforce_helix_authentication_service.alb_security_group_id
ip_protocol = "TCP"
from_port = 443
to_port = 443
cidr_ipv4 = "${module.perforce_helix_core.helix_core_eip_public_ip}/32"
description = "Enables Helix Core to access Helix Authentication Service"
}
4 changes: 4 additions & 0 deletions modules/perforce/examples/complete/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
variable "root_domain_name" {
type = string
description = "The root domain name you would like to use for DNS."
}
10 changes: 10 additions & 0 deletions modules/perforce/examples/complete/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.0"

required_providers {
aws = {
source = "hashicorp/aws"
version = "5.66.0"
}
}
}
Loading

0 comments on commit 6cc2dd8

Please sign in to comment.