Skip to content
Open
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
18 changes: 18 additions & 0 deletions assets/docker/perforce/p4-broker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM amazonlinux:2023

# Install p4broker from Perforce YUM repository
RUN rpm --import https://package.perforce.com/perforce.pubkey && \
echo -e "[perforce]\nname=Perforce\nbaseurl=https://package.perforce.com/yum/rhel/9/x86_64\nenabled=1\ngpgcheck=1\ngpgkey=https://package.perforce.com/perforce.pubkey" \
> /etc/yum.repos.d/perforce.repo && \
dnf install -y helix-broker && \
dnf clean all && \
rm -rf /var/cache/dnf

# Create config directory
RUN mkdir -p /config /tmp

# p4broker listens on 1666 by default
EXPOSE 1666

# Run p4broker in foreground mode
ENTRYPOINT ["/usr/sbin/p4broker", "-c", "/config/p4broker.conf"]
56 changes: 56 additions & 0 deletions assets/docker/perforce/p4-broker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# P4 Broker Container Image

This directory contains the Dockerfile for building a Perforce Helix Broker (`p4broker`) container image.

## Building the Image

```bash
docker build -t p4-broker .
```

## Pushing to Amazon ECR

```bash
# Authenticate with ECR
aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <account-id>.dkr.ecr.<region>.amazonaws.com

# Tag the image
docker tag p4-broker:latest <account-id>.dkr.ecr.<region>.amazonaws.com/p4-broker:latest

# Push the image
docker push <account-id>.dkr.ecr.<region>.amazonaws.com/p4-broker:latest
```

## Pushing to Another Container Registry

```bash
# Tag the image for your registry
docker tag p4-broker:latest <registry-url>/p4-broker:latest

# Push the image
docker push <registry-url>/p4-broker:latest
```

## Local Testing

```bash
# Create a local broker config file
cat > p4broker.conf <<EOF
target = ssl:your-p4-server:1666;
listen = 1666;
directory = /tmp;
logfile = /tmp/p4broker.log;

command: *
{
action = pass;
}
EOF

# Run the container
docker run -p 1666:1666 -v $(pwd)/p4broker.conf:/config/p4broker.conf p4-broker
```

## Configuration

The container expects a broker configuration file at `/config/p4broker.conf`. When deployed via the Terraform module, this file is downloaded from S3 by an init container and mounted into the broker container via a shared volume.
File renamed without changes.
4 changes: 2 additions & 2 deletions docs/assets/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ description: Re-usable assets for game development on AWS

| Asset Type | Description |
| :--------------------------------------------------------------- | :- |
| [:simple-packer: **Packer Templates**](./packer/index.md) | Packer templates provide an easy way to build machine images for commonly used game dev infrastructure. Currently the project includes Packer templates for UE5 build agents for Linux and Windows, as well as a Packer template for building a Perforce Helix Core version control AMI. |
| [:simple-packer: **Packer Templates**](./packer/README.md) | Packer templates provide an easy way to build machine images for commonly used game dev infrastructure. Currently the project includes Packer templates for UE5 build agents for Linux and Windows, as well as a Packer template for building a Perforce Helix Core version control AMI. |
| [:simple-jenkins: **Jenkins Pipelines**](../../assets/jenkins-pipelines/README.md) | Jenkins Pipelines for common game dev automation workflows |
| [:simple-ansible: **Ansible Playbooks**](../../assets/ansible-playbooks/perforce/p4-server/README.md) | Automation scripts for reusable system level configurations. Unlike Packer templates, you can use these to add new functionality to existing EC2 instances. |
| [:simple-docker: **Dockerfiles (Coming Soon!)**](./dockerfiles.md) | Dockerfiles for creating Docker images of commonly used game dev infrastructure. These are primarily used in scenarios where there aren't openly available pre-built images that address a use case, or significant customization is needed that warrants building an image |
| [:simple-docker: **Dockerfiles**](./docker/README.md) | Dockerfiles for creating Docker images of commonly used game dev infrastructure. These are primarily used in scenarios where there aren't openly available pre-built images that address a use case, or significant customization is needed that warrants building an image |
File renamed without changes.
2 changes: 1 addition & 1 deletion docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Welcome to the **Cloud Game Development Toolkit
### Assets

An _asset_ is a singular template, script, or automation document that may prove useful in isolation. Currently, the **Toolkit** contains three types of
_assets_: [Ansible playbooks](../assets/ansible-playbooks/perforce/p4-server/README.md), [Jenkins pipelines](../assets/jenkins-pipelines/README.md), and [Packer templates](../docs/assets/packer/index.md). Each of these
_assets_: [Ansible playbooks](../assets/ansible-playbooks/perforce/p4-server/README.md), [Jenkins pipelines](../assets/jenkins-pipelines/README.md), and [Packer templates](../docs/assets/packer/README.md). Each of these
_assets_ can be used in isolation.

For more information about _assets_, consult the [detailed documentation](../docs/assets/index.md).
Expand Down
8 changes: 6 additions & 2 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ nav:
- Assets:
- Overview: docs/assets/index.md
- Packer Templates:
- Overview: docs/assets/packer/index.md
- Overview: docs/assets/packer/README.md
- Build Agents:
- Linux Build Agents:
- assets/packer/build-agents/linux/README.md
Expand All @@ -105,7 +105,9 @@ nav:
- Virtual Workstations: assets/packer/virtual-workstations/README.md
- Jenkins Pipelines: assets/jenkins-pipelines/README.md
- Ansible Playbooks: assets/ansible-playbooks/perforce/p4-server/README.md
- Dockerfiles: docs/assets/dockerfiles.md
- Dockerfiles:
- Overview: docs/assets/docker/README.md
- P4 Broker: assets/docker/perforce/p4-broker/README.md
- Modules:
- Overview: modules/README.md
- Design Standards: modules/DESIGN_STANDARDS.md
Expand All @@ -120,6 +122,8 @@ nav:
- modules/perforce/modules/p4-auth/README.md
- P4 Code Review:
- modules/perforce/modules/p4-code-review/README.md
- P4 Broker:
- modules/perforce/modules/p4-broker/README.md
- TeamCity: # Section
- TeamCity: # Dropdown
- Installation and Usage:
Expand Down
22 changes: 18 additions & 4 deletions modules/perforce/README.md

Large diffs are not rendered by default.

29 changes: 26 additions & 3 deletions modules/perforce/lb.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
##########################################
# Send traffic from NLB to ALB
resource "aws_lb_target_group" "perforce" {
count = var.create_shared_network_load_balancer != false ? 1 : 0
count = var.create_shared_network_load_balancer && var.create_shared_application_load_balancer ? 1 : 0
name = "${var.project_prefix}-nlb-to-perforce-web-services"
target_type = "alb"
port = 443
Expand Down Expand Up @@ -40,7 +40,7 @@
}

resource "aws_lb_target_group_attachment" "perforce" {
count = var.create_shared_network_load_balancer != false ? 1 : 0
count = var.create_shared_network_load_balancer && var.create_shared_application_load_balancer ? 1 : 0
target_group_arn = aws_lb_target_group.perforce[0].arn
target_id = aws_lb.perforce_web_services[0].arn
port = 443
Expand Down Expand Up @@ -97,7 +97,7 @@
##########################################
# forward HTTPS traffic from Public NLB to Internal ALB
resource "aws_lb_listener" "perforce" {
count = var.create_shared_network_load_balancer != false ? 1 : 0
count = var.create_shared_network_load_balancer && var.create_shared_application_load_balancer ? 1 : 0
load_balancer_arn = aws_lb.perforce[0].arn
port = 443
protocol = "TCP"
Expand Down Expand Up @@ -129,6 +129,29 @@
}


##########################################
# Perforce NLB | P4 Broker TCP Listener
##########################################
# Forward TCP traffic on broker port from NLB to P4 Broker target group
resource "aws_lb_listener" "perforce_broker" {
count = var.p4_broker_config != null && var.create_shared_network_load_balancer ? 1 : 0
load_balancer_arn = aws_lb.perforce[0].arn
port = var.p4_broker_config.container_port
protocol = "TCP"

default_action {
type = "forward"
target_group_arn = module.p4_broker[0].target_group_arn
}

#checkov:skip=CKV2_AWS_74: TCP listener does not support TLS ciphers
tags = merge(var.tags, {
TrafficSource = (var.shared_network_load_balancer_name != null ? var.shared_network_load_balancer_name : "${var.project_prefix}-perforce-shared-nlb")
TrafficDestination = "${var.project_prefix}-${var.p4_broker_config.name}-service"
})
}
Comment on lines +136 to +152

Check warning

Code scanning / checkov

Ensure AWS Load Balancers use strong ciphers Warning

Ensure AWS Load Balancers use strong ciphers
Comment on lines +136 to +152

Check warning

Code scanning / checkov

Ensure AWS Load Balancers use strong ciphers Warning

Ensure AWS Load Balancers use strong ciphers
Comment on lines +136 to +152

Check warning

Code scanning / checkov

Ensure AWS Load Balancers use strong ciphers Warning

Ensure AWS Load Balancers use strong ciphers


# 1. Create the Target Group (this is done in p4-auth, and p4-code-review submodules)
# 2. Create the Target Group Attachment (this is not necessary as ECS handles this automatically. This is handled in the p4-auth, and p4-code-review submodules in the load_balancers block)
# 3. Create the ALB only if the target group (in submodules) has been created
Expand Down
2 changes: 1 addition & 1 deletion modules/perforce/locals.tf
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
locals {
# shared ECS cluster configuration
create_shared_ecs_cluster = (var.existing_ecs_cluster_name == null &&
(var.p4_auth_config != null || var.p4_code_review_config != null))
(var.p4_auth_config != null || var.p4_code_review_config != null || var.p4_broker_config != null))

# This serves as a sensible default for p4d_port config options
p4_port = var.p4_server_config != null ? (
Expand Down
52 changes: 48 additions & 4 deletions modules/perforce/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -159,17 +159,61 @@ module "p4_code_review" {
create_default_role = var.p4_code_review_config.create_default_role
custom_role = var.p4_code_review_config.custom_role

super_user_password_secret_arn = module.p4_server[0].super_user_password_secret_arn
super_user_username_secret_arn = module.p4_server[0].super_user_username_secret_arn
p4_code_review_user_password_secret_arn = module.p4_server[0].super_user_password_secret_arn
p4_code_review_user_username_secret_arn = module.p4_server[0].super_user_username_secret_arn
super_user_password_secret_arn = var.p4_code_review_config.super_user_password_secret_arn != null ? var.p4_code_review_config.super_user_password_secret_arn : try(module.p4_server[0].super_user_password_secret_arn, null)
super_user_username_secret_arn = var.p4_code_review_config.super_user_username_secret_arn != null ? var.p4_code_review_config.super_user_username_secret_arn : try(module.p4_server[0].super_user_username_secret_arn, null)
p4_code_review_user_password_secret_arn = var.p4_code_review_config.p4_code_review_user_password_secret_arn != null ? var.p4_code_review_config.p4_code_review_user_password_secret_arn : try(module.p4_server[0].super_user_password_secret_arn, null)
p4_code_review_user_username_secret_arn = var.p4_code_review_config.p4_code_review_user_username_secret_arn != null ? var.p4_code_review_config.p4_code_review_user_username_secret_arn : try(module.p4_server[0].super_user_username_secret_arn, null)

enable_sso = var.p4_code_review_config.enable_sso
config_php_source = var.p4_code_review_config.config_php_source

depends_on = [aws_ecs_cluster.perforce_web_services_cluster[0]]
}

#################################################
# P4 Broker (Perforce Helix Broker)
#################################################
module "p4_broker" {
source = "./modules/p4-broker"
count = var.p4_broker_config != null ? 1 : 0

# General
name = var.p4_broker_config.name
project_prefix = var.p4_broker_config.project_prefix
debug = var.p4_broker_config.debug

# Compute
cluster_name = (
var.existing_ecs_cluster_name != null ?
var.existing_ecs_cluster_name :
aws_ecs_cluster.perforce_web_services_cluster[0].name
)
container_name = var.p4_broker_config.container_name
container_port = var.p4_broker_config.container_port
container_cpu = var.p4_broker_config.container_cpu
container_memory = var.p4_broker_config.container_memory
container_image = var.p4_broker_config.container_image
desired_count = var.p4_broker_config.desired_count

# Broker Configuration
p4_target = var.p4_broker_config.p4_target
broker_command_rules = var.p4_broker_config.broker_command_rules
extra_env = var.p4_broker_config.extra_env

# Storage & Logging
cloudwatch_log_retention_in_days = var.p4_broker_config.cloudwatch_log_retention_in_days

# Networking & Security
vpc_id = var.vpc_id
subnets = var.p4_broker_config.service_subnets

create_default_role = var.p4_broker_config.create_default_role
custom_role = var.p4_broker_config.custom_role

depends_on = [aws_ecs_cluster.perforce_web_services_cluster[0]]
}


#################################################
# Shared ECS Cluster (Perforce Web Services)
#################################################
Expand Down
Loading