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

Henrykie/helix swarm #306

Merged
merged 7 commits into from
Sep 30, 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
112 changes: 59 additions & 53 deletions docs/media/diagrams/perforce-module-architectures.drawio

Large diffs are not rendered by default.

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.
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
}
}
Dismissed Show dismissed Hide dismissed
Dismissed Show dismissed Hide dismissed


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]
}
Dismissed Show dismissed Hide dismissed

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]
}
Dismissed Show dismissed Hide dismissed

##########################################
# 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
Loading