From 9c2bf832a55d17435a0411df14dbeb756a84d1a3 Mon Sep 17 00:00:00 2001 From: Henry Kiem Date: Fri, 13 Feb 2026 16:17:49 -0800 Subject: [PATCH 1/2] fix(perforce): restructure tests and fix pre-existing module bugs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test restructuring: - Flatten test directory (remove unit/ and integration/ subdirectories) - Delete integration tests (require AWS credentials and SSM parameters) - Replace jsonencode() in mock_data with raw JSON strings - Add explicit disabled flags for NLB/ALB/R53 in test variables - Fix FQDN/zone name mismatch in full_stack test data - Fix assertion resource names (lb_access_logs → shared_lb_access_logs_bucket) - Simplify tests/README.md Module bug fixes: - versions.tf: add netapp-ontap provider (required by p4-server submodule) - variables.tf: add null guards to all p4_server_config validation rules - variables.tf: fix inverted shared_lb_access_logs_bucket validation - variables.tf: fix route53_private_hosted_zone_name error message - lb.tf: require both NLB and ALB for NLB→ALB resources - sg.tf: require ALB for NLB→ALB egress rule - main.tf: add try() fallback for p4_code_review secret ARN references - outputs.tf: add null guard for p4_server_lambda_link_name --- modules/perforce/README.md | 9 +- modules/perforce/lb.tf | 6 +- modules/perforce/main.tf | 8 +- modules/perforce/outputs.tf | 2 +- modules/perforce/sg.tf | 2 +- .../01_conditional_creation.tftest.hcl | 69 +++-- .../{unit => }/02_shared_resources.tftest.hcl | 56 ++-- modules/perforce/tests/README.md | 293 ++---------------- .../01_create_resources_complete.tftest.hcl | 27 -- .../integration/02_p4_server_fsxn.tftest.hcl | 28 -- modules/perforce/tests/integration/README.md | 171 ---------- .../perforce/tests/integration/setup/ssm.tf | 24 -- .../tests/integration/setup/versions.tf | 10 - modules/perforce/tests/unit/README.md | 119 ------- modules/perforce/variables.tf | 22 +- modules/perforce/versions.tf | 4 + 16 files changed, 115 insertions(+), 735 deletions(-) rename modules/perforce/tests/{unit => }/01_conditional_creation.tftest.hcl (81%) rename modules/perforce/tests/{unit => }/02_shared_resources.tftest.hcl (73%) delete mode 100644 modules/perforce/tests/integration/01_create_resources_complete.tftest.hcl delete mode 100644 modules/perforce/tests/integration/02_p4_server_fsxn.tftest.hcl delete mode 100644 modules/perforce/tests/integration/README.md delete mode 100644 modules/perforce/tests/integration/setup/ssm.tf delete mode 100644 modules/perforce/tests/integration/setup/versions.tf delete mode 100644 modules/perforce/tests/unit/README.md diff --git a/modules/perforce/README.md b/modules/perforce/README.md index d4104678..a3a62947 100644 --- a/modules/perforce/README.md +++ b/modules/perforce/README.md @@ -146,6 +146,7 @@ packer build perforce_x86.pkr.hcl | [aws](#requirement\_aws) | ~> 6.6 | | [awscc](#requirement\_awscc) | ~> 1.51 | | [local](#requirement\_local) | ~> 2.5 | +| [netapp-ontap](#requirement\_netapp-ontap) | ~> 2.3 | | [null](#requirement\_null) | ~> 3.2 | | [random](#requirement\_random) | ~> 3.7 | @@ -218,9 +219,9 @@ packer build perforce_x86.pkr.hcl | [enable\_shared\_lb\_access\_logs](#input\_enable\_shared\_lb\_access\_logs) | Enables access logging for both the shared NLB and shared ALB. Defaults to false. | `bool` | `false` | no | | [existing\_ecs\_cluster\_name](#input\_existing\_ecs\_cluster\_name) | The name of an existing ECS cluster to use for the Perforce server. If omitted a new cluster will be created. | `string` | `null` | no | | [existing\_security\_groups](#input\_existing\_security\_groups) | A list of existing security group IDs to attach to the shared network load balancer. | `list(string)` | `[]` | no | -| [p4\_auth\_config](#input\_p4\_auth\_config) | # General
name: "The string including in the naming of resources related to P4Auth. Default is 'p4-auth'."

project\_prefix : "The project prefix for the P4Auth service. Default is 'cgd'."

environment : "The environment where the P4Auth service will be deployed. Default is 'dev'."

enable\_web\_based\_administration: "Whether to de enable web based administration. Default is 'true'."

debug : "Whether to enable debug mode for the P4Auth service. Default is 'false'."

fully\_qualified\_domain\_name : "The FQDN for the P4Auth Service. This is used for the P4Auth's Perforce configuration."


# Compute
cluster\_name : "The name of the ECS cluster where the P4Auth service will be deployed. Cluster is not created if this variable is null."

container\_name : "The name of the P4Auth service container. Default is 'p4-auth-container'."

container\_port : "The port on which the P4Auth service will be listening. Default is '3000'."

container\_cpu : "The number of CPU units to reserve for the P4Auth service container. Default is '1024'."

container\_memory : "The number of CPU units to reserve for the P4Auth service container. Default is '4096'."

pd4\_port : "The full URL you will use to access the P4 Depot in clients such P4V and P4Admin. Note, this typically starts with 'ssl:' and ends with the default port of ':1666'."


# Storage & Logging
cloudwatch\_log\_retention\_in\_days : "The number of days to retain the P4Auth service logs in CloudWatch. Default is 365 days."


# Networking
create\_defaults\_sgs : "Whether to create default security groups for the P4Auth service."

internal : "Set this flag to true if you do not want the P4Auth service to have a public IP."

create\_default\_role : "Whether to create the P4Auth default IAM Role. Default is set to true."

custom\_role : "ARN of a custom IAM Role you wish to use with P4Auth."

admin\_username\_secret\_arn : "Optionally provide the ARN of an AWS Secret for the P4Auth Administrator username."

admin\_password\_secret\_arn : "Optionally provide the ARN of an AWS Secret for the P4Auth Administrator password."


# - SCIM -
p4d\_super\_user\_arn : "If you would like to use SCIM to provision users and groups, you need to set this variable to the ARN of an AWS Secrets Manager secret containing the super user username for p4d."

p4d\_super\_user\_password\_arn : "If you would like to use SCIM to provision users and groups, you need to set this variable to the ARN of an AWS Secrets Manager secret containing the super user password for p4d."

scim\_bearer\_token\_arn : "If you would like to use SCIM to provision users and groups, you need to set this variable to the ARN of an AWS Secrets Manager secret containing the bearer token."

extra\_env : "Extra configuration environment variables to set on the p4 auth svc container." |
object({
# - General -
name = optional(string, "p4-auth")
project_prefix = optional(string, "cgd")
environment = optional(string, "dev")
enable_web_based_administration = optional(bool, true)
debug = optional(bool, false)
fully_qualified_domain_name = string

# - Compute -
container_name = optional(string, "p4-auth-container")
container_port = optional(number, 3000)
container_cpu = optional(number, 1024)
container_memory = optional(number, 4096)
p4d_port = optional(string, null)

# - Storage & Logging -
cloudwatch_log_retention_in_days = optional(number, 365)

# - Networking & Security -
service_subnets = optional(list(string), null)
create_default_sgs = optional(bool, true)
existing_security_groups = optional(list(string), [])
internal = optional(bool, false)

certificate_arn = optional(string, null)
create_default_role = optional(bool, true)
custom_role = optional(string, null)
admin_username_secret_arn = optional(string, null)
admin_password_secret_arn = optional(string, null)

# SCIM
p4d_super_user_arn = optional(string, null)
p4d_super_user_password_arn = optional(string, null)
scim_bearer_token_arn = optional(string, null)
extra_env = optional(map(string), null)
})
| `null` | no | -| [p4\_code\_review\_config](#input\_p4\_code\_review\_config) | # General
name: "The string including in the naming of resources related to P4 Code Review. Default is 'p4-code-review'."

project\_prefix : "The project prefix for the P4 Code Review service. Default is 'cgd'."

environment : "The environment where the P4 Code Review service will be deployed. Default is 'dev'."

debug : "Whether to enable debug mode for the P4 Code Review service. Default is 'false'."

fully\_qualified\_domain\_name : "The FQDN for the P4 Code Review Service. This is used for the P4 Code Review's Perforce configuration."


# Compute
container\_name : "The name of the P4 Code Review service container. Default is 'p4-code-review-container'."

container\_port : "The port on which the P4 Code Review service will be listening. Default is '3000'."

container\_cpu : "The number of CPU units to reserve for the P4 Code Review service container. Default is '1024'."

container\_memory : "The number of CPU units to reserve for the P4 Code Review service container. Default is '4096'."

pd4\_port : "The full URL you will use to access the P4 Depot in clients such P4V and P4Admin. Note, this typically starts with 'ssl:' and ends with the default port of ':1666'."

p4charset : "The P4CHARSET environment variable to set in the P4 Code Review container."

existing\_redis\_connection : "The existing Redis connection for the P4 Code Review service."


# Storage & Logging
cloudwatch\_log\_retention\_in\_days : "The number of days to retain the P4 Code Review service logs in CloudWatch. Default is 365 days."


# Networking & Security
create\_default\_sgs : "Whether to create default security groups for the P4 Code Review service."

internal : "Set this flag to true if you do not want the P4 Code Review service to have a public IP."

create\_default\_role : "Whether to create the P4 Code Review default IAM Role. Default is set to true."

custom\_role : "ARN of a custom IAM Role you wish to use with P4 Code Review."

super\_user\_password\_secret\_arn : "Optionally provide the ARN of an AWS Secret for the P4 Code Review Administrator username."

super\_user\_username\_secret\_arn : "Optionally provide the ARN of an AWS Secret for the P4 Code Review Administrator password."

p4d\_p4\_code\_review\_user\_secret\_arn : "Optionally provide the ARN of an AWS Secret for the P4 Code Review user's username."

p4d\_p4\_code\_review\_password\_secret\_arn : "Optionally provide the ARN of an AWS Secret for the P4 Code Review user's password."

p4d\_p4\_code\_review\_user\_password\_arn : "Optionally provide the ARN of an AWS Secret for the P4 Code Review user's password."

enable\_sso : "Whether to enable SSO for the P4 Code Review service. Default is set to false."

config\_php\_source : "Used as the ValueFrom for P4CR's config.php. Contents should be base64 encoded, and will be combined with the generated config.php via array\_replace\_recursive."


# Caching
elasticache\_node\_count : "The number of Elasticache nodes to create for the P4 Code Review service. Default is '1'."

elasticache\_node\_type : "The type of Elasticache node to create for the P4 Code Review service. Default is 'cache.t4g.micro'." |
object({
# General
name = optional(string, "p4-code-review")
project_prefix = optional(string, "cgd")
environment = optional(string, "dev")
debug = optional(bool, false)
fully_qualified_domain_name = string

# Compute
container_name = optional(string, "p4-code-review-container")
container_port = optional(number, 80)
container_cpu = optional(number, 1024)
container_memory = optional(number, 4096)
p4d_port = optional(string, null)
p4charset = optional(string, null)
existing_redis_connection = optional(object({
host = string
port = number
}), null)

# Storage & Logging
cloudwatch_log_retention_in_days = optional(number, 365)

# Networking & Security
create_default_sgs = optional(bool, true)
existing_security_groups = optional(list(string), [])
internal = optional(bool, false)
service_subnets = optional(list(string), null)

create_default_role = optional(bool, true)
custom_role = optional(string, null)

super_user_password_secret_arn = optional(string, null)
super_user_username_secret_arn = optional(string, null)
p4_code_review_user_password_secret_arn = optional(string, null)
p4_code_review_user_username_secret_arn = optional(string, null)
enable_sso = optional(string, false)
config_php_source = optional(string, null)

# Caching
elasticache_node_count = optional(number, 1)
elasticache_node_type = optional(string, "cache.t4g.micro")
})
| `null` | no | -| [p4\_server\_config](#input\_p4\_server\_config) | # - General -
name: "The string including in the naming of resources related to P4 Server. Default is 'p4-server'"

project\_prefix: "The project prefix for this workload. This is appended to the beginning of most resource names."

environment: "The current environment (e.g. dev, prod, etc.)"

auth\_service\_url: "The URL for the P4Auth Service."

fully\_qualified\_domain\_name = "The FQDN for the P4 Server. This is used for the P4 Server's Perforce configuration."


# - Compute -
lookup\_existing\_ami : "Whether to lookup the existing Perforce P4 Server AMI."

ami\_prefix: "The AMI prefix to use for the AMI that will be created for P4 Server."

instance\_type: "The instance type for Perforce P4 Server. Defaults to c6g.large."

instance\_architecture: "The architecture of the P4 Server instance. Allowed values are 'arm64' or 'x86\_64'."

IMPORTANT: "Ensure the instance family of the instance type you select supports the instance\_architecture you select. For example, 'c6in' instance family only works for 'x86\_64' architecture, not 'arm64'. For a full list of this mapping, see the AWS Docs for EC2 Naming Conventions: https://docs.aws.amazon.com/ec2/latest/instancetypes/instance-type-names.html"

p4\_server\_type: "The Perforce P4 Server server type. Valid values are 'p4d\_commit' or 'p4d\_replica'."

unicode: "Whether to enable Unicode configuration for P4 Server the -xi flag for p4d. Set to true to enable Unicode support."

selinux: "Whether to apply SELinux label updates for P4 Server. Don't enable this if SELinux is disabled on your target operating system."

case\_sensitive: "Whether or not the server should be case insensitive (Server will run '-C1' mode), or if the server will run with case sensitivity default of the underlying platform. False enables '-C1' mode. Default is set to true."

plaintext: "Whether to enable plaintext authentication for P4 Server. This is not recommended for production environments unless you are using a load balancer for TLS termination. Default is set to false."


# - Storage -
storage\_type: "The type of backing store. Valid values are either 'EBS' or 'FSxN'"

depot\_volume\_size: "The size of the depot volume in GiB. Defaults to 128 GiB."

metadata\_volume\_size: "The size of the metadata volume in GiB. Defaults to 32 GiB."

logs\_volume\_size: "The size of the logs volume in GiB. Defaults to 32 GiB."


# - Networking & Security -
instance\_subnet\_id: "The subnet where the P4 Server instance will be deployed."

instance\_private\_ip: "The private IP address to assign to the P4 Server."

create\_default\_sg : "Whether to create a default security group for the P4 Server instance."

existing\_security\_groups: "A list of existing security group IDs to attach to the P4 Server load balancer."

internal: "Set this flag to true if you do not want the P4 Server instance to have a public IP."

super\_user\_password\_secret\_arn: "If you would like to manage your own super user credentials through AWS Secrets Manager provide the ARN for the super user's username here. Otherwise, the default of 'perforce' will be used."

super\_user\_username\_secret\_arn: "If you would like to manage your own super user credentials through AWS Secrets Manager provide the ARN for the super user's password here."

create\_default\_role: "Optional creation of P4 Server default IAM Role with SSM managed instance core policy attached. Default is set to true."

custom\_role: "ARN of a custom IAM Role you wish to use with P4 Server." |
object({
# General
name = optional(string, "p4-server")
project_prefix = optional(string, "cgd")
environment = optional(string, "dev")
auth_service_url = optional(string, null)
fully_qualified_domain_name = string

# Compute
lookup_existing_ami = optional(bool, true)
ami_prefix = optional(string, "p4_al2023")

instance_type = optional(string, "c6i.large")
instance_architecture = optional(string, "x86_64")
p4_server_type = optional(string, null)

unicode = optional(bool, false)
selinux = optional(bool, false)
case_sensitive = optional(bool, true)
plaintext = optional(bool, false)

# Storage
storage_type = optional(string, "EBS")
depot_volume_size = optional(number, 128)
metadata_volume_size = optional(number, 32)
logs_volume_size = optional(number, 32)

# Networking & Security
instance_subnet_id = optional(string, null)
instance_private_ip = optional(string, null)
create_default_sg = optional(bool, true)
existing_security_groups = optional(list(string), [])
internal = optional(bool, false)

super_user_password_secret_arn = optional(string, null)
super_user_username_secret_arn = optional(string, null)

create_default_role = optional(bool, true)
custom_role = optional(string, null)

# FSxN
fsxn_password = optional(string, null)
fsxn_filesystem_security_group_id = optional(string, null)
protocol = optional(string, null)
fsxn_region = optional(string, null)
fsxn_management_ip = optional(string, null)
fsxn_svm_name = optional(string, null)
amazon_fsxn_svm_id = optional(string, null)
fsxn_aws_profile = optional(string, null)
})
| `null` | no | +| [p4\_auth\_config](#input\_p4\_auth\_config) | # General
name: "The string including in the naming of resources related to P4Auth. Default is 'p4-auth'."

project\_prefix : "The project prefix for the P4Auth service. Default is 'cgd'."

environment : "The environment where the P4Auth service will be deployed. Default is 'dev'."

enable\_web\_based\_administration: "Whether to de enable web based administration. Default is 'true'."

debug : "Whether to enable debug mode for the P4Auth service. Default is 'false'."

fully\_qualified\_domain\_name : "The FQDN for the P4Auth Service. This is used for the P4Auth's Perforce configuration."


# Compute
cluster\_name : "The name of the ECS cluster where the P4Auth service will be deployed. Cluster is not created if this variable is null."

container\_name : "The name of the P4Auth service container. Default is 'p4-auth-container'."

container\_port : "The port on which the P4Auth service will be listening. Default is '3000'."

container\_cpu : "The number of CPU units to reserve for the P4Auth service container. Default is '1024'."

container\_memory : "The number of CPU units to reserve for the P4Auth service container. Default is '4096'."

pd4\_port : "The full URL you will use to access the P4 Depot in clients such P4V and P4Admin. Note, this typically starts with 'ssl:' and ends with the default port of ':1666'."


# Storage & Logging
cloudwatch\_log\_retention\_in\_days : "The number of days to retain the P4Auth service logs in CloudWatch. Default is 365 days."


# Networking
create\_defaults\_sgs : "Whether to create default security groups for the P4Auth service."

internal : "Set this flag to true if you do not want the P4Auth service to have a public IP."

create\_default\_role : "Whether to create the P4Auth default IAM Role. Default is set to true."

custom\_role : "ARN of a custom IAM Role you wish to use with P4Auth."

admin\_username\_secret\_arn : "Optionally provide the ARN of an AWS Secret for the P4Auth Administrator username."

admin\_password\_secret\_arn : "Optionally provide the ARN of an AWS Secret for the P4Auth Administrator password."


# - SCIM -
p4d\_super\_user\_arn : "If you would like to use SCIM to provision users and groups, you need to set this variable to the ARN of an AWS Secrets Manager secret containing the super user username for p4d."

p4d\_super\_user\_password\_arn : "If you would like to use SCIM to provision users and groups, you need to set this variable to the ARN of an AWS Secrets Manager secret containing the super user password for p4d."

scim\_bearer\_token\_arn : "If you would like to use SCIM to provision users and groups, you need to set this variable to the ARN of an AWS Secrets Manager secret containing the bearer token."

extra\_env : "Extra configuration environment variables to set on the p4 auth svc container." |
object({
# - General -
name = optional(string, "p4-auth")
project_prefix = optional(string, "cgd")
environment = optional(string, "dev")
enable_web_based_administration = optional(bool, true)
debug = optional(bool, false)
fully_qualified_domain_name = string

# - Compute -
container_name = optional(string, "p4-auth-container")
container_port = optional(number, 3000)
container_cpu = optional(number, 1024)
container_memory = optional(number, 4096)
p4d_port = optional(string, null)

# - Storage & Logging -
cloudwatch_log_retention_in_days = optional(number, 365)

# - Networking & Security -
service_subnets = optional(list(string), null)
create_default_sgs = optional(bool, true)
existing_security_groups = optional(list(string), [])
internal = optional(bool, false)

certificate_arn = optional(string, null)
create_default_role = optional(bool, true)
custom_role = optional(string, null)
admin_username_secret_arn = optional(string, null)
admin_password_secret_arn = optional(string, null)

# SCIM
p4d_super_user_arn = optional(string, null)
p4d_super_user_password_arn = optional(string, null)
scim_bearer_token_arn = optional(string, null)
extra_env = optional(map(string), null)
})
| `null` | no | +| [p4\_code\_review\_config](#input\_p4\_code\_review\_config) | # General
name: "The string including in the naming of resources related to P4 Code Review. Default is 'p4-code-review'."

project\_prefix : "The project prefix for the P4 Code Review service. Default is 'cgd'."

environment : "The environment where the P4 Code Review service will be deployed. Default is 'dev'."

debug : "Whether to enable debug mode for the P4 Code Review service. Default is 'false'."

fully\_qualified\_domain\_name : "The FQDN for the P4 Code Review Service. This is used for the P4 Code Review's Perforce configuration."


# Compute
container\_name : "The name of the P4 Code Review service container. Default is 'p4-code-review-container'."

container\_port : "The port on which the P4 Code Review service will be listening. Default is '3000'."

container\_cpu : "The number of CPU units to reserve for the P4 Code Review service container. Default is '1024'."

container\_memory : "The number of CPU units to reserve for the P4 Code Review service container. Default is '4096'."

pd4\_port : "The full URL you will use to access the P4 Depot in clients such P4V and P4Admin. Note, this typically starts with 'ssl:' and ends with the default port of ':1666'."

p4charset : "The P4CHARSET environment variable to set in the P4 Code Review container."

existing\_redis\_connection : "The existing Redis connection for the P4 Code Review service."


# Storage & Logging
cloudwatch\_log\_retention\_in\_days : "The number of days to retain the P4 Code Review service logs in CloudWatch. Default is 365 days."


# Networking & Security
create\_default\_sgs : "Whether to create default security groups for the P4 Code Review service."

internal : "Set this flag to true if you do not want the P4 Code Review service to have a public IP."

create\_default\_role : "Whether to create the P4 Code Review default IAM Role. Default is set to true."

custom\_role : "ARN of a custom IAM Role you wish to use with P4 Code Review."

super\_user\_password\_secret\_arn : "Optionally provide the ARN of an AWS Secret for the P4 Code Review Administrator username."

super\_user\_username\_secret\_arn : "Optionally provide the ARN of an AWS Secret for the P4 Code Review Administrator password."

p4d\_p4\_code\_review\_user\_secret\_arn : "Optionally provide the ARN of an AWS Secret for the P4 Code Review user's username."

p4d\_p4\_code\_review\_password\_secret\_arn : "Optionally provide the ARN of an AWS Secret for the P4 Code Review user's password."

p4d\_p4\_code\_review\_user\_password\_arn : "Optionally provide the ARN of an AWS Secret for the P4 Code Review user's password."

enable\_sso : "Whether to enable SSO for the P4 Code Review service. Default is set to false."

config\_php\_source : "Used as the ValueFrom for P4CR's config.php. Contents should be base64 encoded, and will be combined with the generated config.php via array\_replace\_recursive."


# Caching
elasticache\_node\_count : "The number of Elasticache nodes to create for the P4 Code Review service. Default is '1'."

elasticache\_node\_type : "The type of Elasticache node to create for the P4 Code Review service. Default is 'cache.t4g.micro'." |
object({
# General
name = optional(string, "p4-code-review")
project_prefix = optional(string, "cgd")
environment = optional(string, "dev")
debug = optional(bool, false)
fully_qualified_domain_name = string

# Compute
container_name = optional(string, "p4-code-review-container")
container_port = optional(number, 80)
container_cpu = optional(number, 1024)
container_memory = optional(number, 4096)
p4d_port = optional(string, null)
p4charset = optional(string, null)
existing_redis_connection = optional(object({
host = string
port = number
}), null)

# Storage & Logging
cloudwatch_log_retention_in_days = optional(number, 365)

# Networking & Security
create_default_sgs = optional(bool, true)
existing_security_groups = optional(list(string), [])
internal = optional(bool, false)
service_subnets = optional(list(string), null)

create_default_role = optional(bool, true)
custom_role = optional(string, null)

super_user_password_secret_arn = optional(string, null)
super_user_username_secret_arn = optional(string, null)
p4_code_review_user_password_secret_arn = optional(string, null)
p4_code_review_user_username_secret_arn = optional(string, null)
enable_sso = optional(string, true)
config_php_source = optional(string, null)

# Caching
elasticache_node_count = optional(number, 1)
elasticache_node_type = optional(string, "cache.t4g.micro")
})
| `null` | no | +| [p4\_server\_config](#input\_p4\_server\_config) | # - General -
name: "The string including in the naming of resources related to P4 Server. Default is 'p4-server'"

project\_prefix: "The project prefix for this workload. This is appended to the beginning of most resource names."

environment: "The current environment (e.g. dev, prod, etc.)"

auth\_service\_url: "The URL for the P4Auth Service."

fully\_qualified\_domain\_name = "The FQDN for the P4 Server. This is used for the P4 Server's Perforce configuration."


# - Compute -
lookup\_existing\_ami : "Whether to lookup the existing Perforce P4 Server AMI."

ami\_prefix: "The AMI prefix to use for the AMI that will be created for P4 Server."

instance\_type: "The instance type for Perforce P4 Server. Defaults to c6g.large."

instance\_architecture: "The architecture of the P4 Server instance. Allowed values are 'arm64' or 'x86\_64'."

IMPORTANT: "Ensure the instance family of the instance type you select supports the instance\_architecture you select. For example, 'c6in' instance family only works for 'x86\_64' architecture, not 'arm64'. For a full list of this mapping, see the AWS Docs for EC2 Naming Conventions: https://docs.aws.amazon.com/ec2/latest/instancetypes/instance-type-names.html"

p4\_server\_type: "The Perforce P4 Server server type. Valid values are 'p4d\_commit' or 'p4d\_replica'."

unicode: "Whether to enable Unicode configuration for P4 Server the -xi flag for p4d. Set to true to enable Unicode support."

selinux: "Whether to apply SELinux label updates for P4 Server. Don't enable this if SELinux is disabled on your target operating system."

case\_sensitive: "Whether or not the server should be case insensitive (Server will run '-C1' mode), or if the server will run with case sensitivity default of the underlying platform. False enables '-C1' mode. Default is set to true."

plaintext: "Whether to enable plaintext authentication for P4 Server. This is not recommended for production environments unless you are using a load balancer for TLS termination. Default is set to false."


# - Storage -
storage\_type: "The type of backing store. Valid values are either 'EBS' or 'FSxN'"

depot\_volume\_size: "The size of the depot volume in GiB. Defaults to 128 GiB."

metadata\_volume\_size: "The size of the metadata volume in GiB. Defaults to 32 GiB."

logs\_volume\_size: "The size of the logs volume in GiB. Defaults to 32 GiB."


# - Networking & Security -
instance\_subnet\_id: "The subnet where the P4 Server instance will be deployed."

instance\_private\_ip: "The private IP address to assign to the P4 Server."

create\_default\_sg : "Whether to create a default security group for the P4 Server instance."

existing\_security\_groups: "A list of existing security group IDs to attach to the P4 Server load balancer."

internal: "Set this flag to true if you do not want the P4 Server instance to have a public IP."

super\_user\_password\_secret\_arn: "If you would like to manage your own super user credentials through AWS Secrets Manager provide the ARN for the super user's username here. Otherwise, the default of 'perforce' will be used."

super\_user\_username\_secret\_arn: "If you would like to manage your own super user credentials through AWS Secrets Manager provide the ARN for the super user's password here."

create\_default\_role: "Optional creation of P4 Server default IAM Role with SSM managed instance core policy attached. Default is set to true."

custom\_role: "ARN of a custom IAM Role you wish to use with P4 Server." |
object({
# General
name = optional(string, "p4-server")
project_prefix = optional(string, "cgd")
environment = optional(string, "dev")
auth_service_url = optional(string, null)
fully_qualified_domain_name = string

# Compute
lookup_existing_ami = optional(bool, true)
ami_prefix = optional(string, "p4_al2023")

instance_type = optional(string, "c6i.large")
instance_architecture = optional(string, "x86_64")
p4_server_type = optional(string, null)

unicode = optional(bool, false)
selinux = optional(bool, false)
case_sensitive = optional(bool, true)
plaintext = optional(bool, false)

# Storage
storage_type = optional(string, "EBS")
depot_volume_size = optional(number, 128)
metadata_volume_size = optional(number, 32)
logs_volume_size = optional(number, 32)

# Networking & Security
instance_subnet_id = optional(string, null)
instance_private_ip = optional(string, null)
create_default_sg = optional(bool, true)
existing_security_groups = optional(list(string), [])
internal = optional(bool, false)

super_user_password_secret_arn = optional(string, null)
super_user_username_secret_arn = optional(string, null)

create_default_role = optional(bool, true)
custom_role = optional(string, null)

# FSxN
fsxn_password = optional(string, null)
fsxn_filesystem_security_group_id = optional(string, null)
protocol = optional(string, null)
fsxn_region = optional(string, null)
fsxn_management_ip = optional(string, null)
fsxn_svm_name = optional(string, null)
amazon_fsxn_svm_id = optional(string, null)
fsxn_aws_profile = optional(string, null)
})
| `null` | no | | [project\_prefix](#input\_project\_prefix) | The project prefix for this workload. This is appended to the beginning of most resource names. | `string` | `"cgd"` | no | | [route53\_private\_hosted\_zone\_name](#input\_route53\_private\_hosted\_zone\_name) | The name of the private Route53 Hosted Zone for the Perforce resources. | `string` | `null` | no | | [s3\_enable\_force\_destroy](#input\_s3\_enable\_force\_destroy) | Enables force destroy for the S3 bucket for both the shared NLB and shared ALB access log storage. Defaults to true. | `bool` | `true` | no | @@ -232,7 +233,7 @@ packer build perforce_x86.pkr.hcl | [shared\_network\_load\_balancer\_name](#input\_shared\_network\_load\_balancer\_name) | The name of the shared Network Load Balancer for the Perforce resources. | `string` | `"p4nlb"` | no | | [shared\_nlb\_access\_logs\_prefix](#input\_shared\_nlb\_access\_logs\_prefix) | Log prefix for shared NLB access logs. | `string` | `"perforce-nlb-"` | no | | [shared\_nlb\_subnets](#input\_shared\_nlb\_subnets) | A list of subnets to attach to the shared network load balancer. | `list(string)` | `null` | no | -| [tags](#input\_tags) | Tags to apply to resources. | `map(any)` |
{
"IaC": "Terraform",
"ModuleBy": "CGD-Toolkit",
"ModuleName": "terraform-aws-perforce",
"ModuleSource": "https://github.com/aws-games/cloud-game-development-toolkit/tree/main/modules/perforce",
"RootModuleName": "-"
}
| no | +| [tags](#input\_tags) | Tags to apply to resources. | `map(any)` |
{
"IaC": "Terraform",
"ModuleBy": "CGD-Toolkit",
"ModuleName": "terraform-aws-perforce",
"ModuleSource": "https://github.com/aws-games/cloud-game-development-toolkit/tree/main/modules/perforce",
"RootModuleName": "-"
}
| no | ## Outputs diff --git a/modules/perforce/lb.tf b/modules/perforce/lb.tf index 0fc5a42f..75a71c5f 100644 --- a/modules/perforce/lb.tf +++ b/modules/perforce/lb.tf @@ -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 @@ -40,7 +40,7 @@ resource "aws_lb_target_group" "perforce" { } 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 @@ -97,7 +97,7 @@ resource "aws_lb" "perforce" { ########################################## # 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" diff --git a/modules/perforce/main.tf b/modules/perforce/main.tf index f499c696..26c661dd 100644 --- a/modules/perforce/main.tf +++ b/modules/perforce/main.tf @@ -159,10 +159,10 @@ 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 diff --git a/modules/perforce/outputs.tf b/modules/perforce/outputs.tf index 40df0279..38f0bcd9 100644 --- a/modules/perforce/outputs.tf +++ b/modules/perforce/outputs.tf @@ -118,7 +118,7 @@ output "p4_code_review_execution_role_id" { } output "p4_server_lambda_link_name" { - value = (var.p4_server_config.storage_type == "FSxN" && var.p4_server_config.protocol == "ISCSI" ? + value = (var.p4_server_config != null && var.p4_server_config.storage_type == "FSxN" && var.p4_server_config.protocol == "ISCSI" ? module.p4_server[0].lambda_link_name : null) description = "The name of the Lambda link for the P4 Server instance to use with FSxN." } diff --git a/modules/perforce/sg.tf b/modules/perforce/sg.tf index edf76b9f..91987e1d 100644 --- a/modules/perforce/sg.tf +++ b/modules/perforce/sg.tf @@ -26,7 +26,7 @@ resource "aws_security_group" "perforce_network_load_balancer" { # Perforce NLB --> Perforce Web Services ALB # Allows Perforce NLB to send outbound traffic to Perforce Web Services ALB resource "aws_vpc_security_group_egress_rule" "perforce_nlb_outbound_to_perforce_web_services_alb" { - count = var.create_default_sgs && var.create_shared_network_load_balancer ? 1 : 0 + count = var.create_default_sgs && var.create_shared_network_load_balancer && var.create_shared_application_load_balancer ? 1 : 0 security_group_id = aws_security_group.perforce_network_load_balancer[0].id description = "Allows Perforce NLB to send outbound traffic to Perforce Web Services ALB." from_port = 443 diff --git a/modules/perforce/tests/unit/01_conditional_creation.tftest.hcl b/modules/perforce/tests/01_conditional_creation.tftest.hcl similarity index 81% rename from modules/perforce/tests/unit/01_conditional_creation.tftest.hcl rename to modules/perforce/tests/01_conditional_creation.tftest.hcl index 2150b89f..18e1b122 100644 --- a/modules/perforce/tests/unit/01_conditional_creation.tftest.hcl +++ b/modules/perforce/tests/01_conditional_creation.tftest.hcl @@ -40,14 +40,7 @@ mock_provider "aws" { mock_data "aws_iam_policy_document" { defaults = { - json = jsonencode({ - Version = "2012-10-17" - Statement = [{ - Effect = "Allow" - Action = "*" - Resource = "*" - }] - }) + json = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"*\",\"Resource\":\"*\"}]}" } } @@ -71,7 +64,10 @@ run "no_submodules" { command = plan variables { - vpc_id = "vpc-12345678" + vpc_id = "vpc-12345678" + create_shared_network_load_balancer = false + create_shared_application_load_balancer = false + create_route53_private_hosted_zone = false # All submodule configs are null (default) } @@ -101,9 +97,11 @@ run "p4_server_only" { command = plan variables { - vpc_id = "vpc-12345678" - shared_nlb_subnets = ["subnet-111", "subnet-222", "subnet-333"] - certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test-cert" + vpc_id = "vpc-12345678" + shared_nlb_subnets = ["subnet-111", "subnet-222", "subnet-333"] + certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test-cert" + create_shared_application_load_balancer = false + create_route53_private_hosted_zone = false p4_server_config = { fully_qualified_domain_name = "p4.test.internal" @@ -141,9 +139,11 @@ run "p4_auth_only" { command = plan variables { - vpc_id = "vpc-12345678" - shared_alb_subnets = ["subnet-111", "subnet-222", "subnet-333"] - certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test-cert" + vpc_id = "vpc-12345678" + shared_alb_subnets = ["subnet-111", "subnet-222", "subnet-333"] + certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test-cert" + create_shared_network_load_balancer = false + create_route53_private_hosted_zone = false p4_auth_config = { fully_qualified_domain_name = "auth.test.internal" @@ -178,9 +178,11 @@ run "p4_code_review_only" { command = plan variables { - vpc_id = "vpc-12345678" - shared_alb_subnets = ["subnet-111", "subnet-222", "subnet-333"] - certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test-cert" + vpc_id = "vpc-12345678" + shared_alb_subnets = ["subnet-111", "subnet-222", "subnet-333"] + certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test-cert" + create_shared_network_load_balancer = false + create_route53_private_hosted_zone = false p4_code_review_config = { fully_qualified_domain_name = "swarm.test.internal" @@ -216,10 +218,11 @@ run "server_and_auth" { command = plan variables { - vpc_id = "vpc-12345678" - shared_nlb_subnets = ["subnet-111", "subnet-222", "subnet-333"] - shared_alb_subnets = ["subnet-111", "subnet-222", "subnet-333"] - certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test-cert" + vpc_id = "vpc-12345678" + shared_nlb_subnets = ["subnet-111", "subnet-222", "subnet-333"] + shared_alb_subnets = ["subnet-111", "subnet-222", "subnet-333"] + certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test-cert" + create_route53_private_hosted_zone = false p4_server_config = { fully_qualified_domain_name = "p4.test.internal" @@ -262,10 +265,11 @@ run "server_and_code_review" { command = plan variables { - vpc_id = "vpc-12345678" - shared_nlb_subnets = ["subnet-111", "subnet-222", "subnet-333"] - shared_alb_subnets = ["subnet-111", "subnet-222", "subnet-333"] - certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test-cert" + vpc_id = "vpc-12345678" + shared_nlb_subnets = ["subnet-111", "subnet-222", "subnet-333"] + shared_alb_subnets = ["subnet-111", "subnet-222", "subnet-333"] + certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test-cert" + create_route53_private_hosted_zone = false p4_server_config = { fully_qualified_domain_name = "p4.test.internal" @@ -317,7 +321,7 @@ run "full_stack" { route53_private_hosted_zone_name = "perforce.internal" p4_server_config = { - fully_qualified_domain_name = "p4.perforce.internal" + fully_qualified_domain_name = "perforce.internal" instance_subnet_id = "subnet-111" p4_server_type = "p4d_commit" depot_volume_size = 128 @@ -368,11 +372,12 @@ run "full_stack_existing_ecs_cluster" { command = plan variables { - vpc_id = "vpc-12345678" - shared_nlb_subnets = ["subnet-111", "subnet-222", "subnet-333"] - shared_alb_subnets = ["subnet-111", "subnet-222", "subnet-333"] - certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test-cert" - existing_ecs_cluster_name = "my-existing-cluster" + vpc_id = "vpc-12345678" + shared_nlb_subnets = ["subnet-111", "subnet-222", "subnet-333"] + shared_alb_subnets = ["subnet-111", "subnet-222", "subnet-333"] + certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test-cert" + existing_ecs_cluster_name = "my-existing-cluster" + create_route53_private_hosted_zone = false p4_server_config = { fully_qualified_domain_name = "p4.test.internal" diff --git a/modules/perforce/tests/unit/02_shared_resources.tftest.hcl b/modules/perforce/tests/02_shared_resources.tftest.hcl similarity index 73% rename from modules/perforce/tests/unit/02_shared_resources.tftest.hcl rename to modules/perforce/tests/02_shared_resources.tftest.hcl index 3f8ebaeb..5b0c141a 100644 --- a/modules/perforce/tests/unit/02_shared_resources.tftest.hcl +++ b/modules/perforce/tests/02_shared_resources.tftest.hcl @@ -29,10 +29,7 @@ mock_provider "aws" { } mock_data "aws_iam_policy_document" { defaults = { - json = jsonencode({ - Version = "2012-10-17" - Statement = [{ Effect = "Allow", Action = "*", Resource = "*" }] - }) + json = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"*\",\"Resource\":\"*\"}]}" } } mock_data "aws_ami" { @@ -51,9 +48,11 @@ run "ecs_cluster_auth_only" { command = plan variables { - vpc_id = "vpc-12345678" - shared_alb_subnets = ["subnet-111", "subnet-222"] - certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test" + vpc_id = "vpc-12345678" + shared_alb_subnets = ["subnet-111", "subnet-222"] + certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test" + create_shared_network_load_balancer = false + create_route53_private_hosted_zone = false p4_auth_config = { fully_qualified_domain_name = "auth.test.internal" @@ -77,9 +76,11 @@ run "ecs_cluster_code_review_only" { command = plan variables { - vpc_id = "vpc-12345678" - shared_alb_subnets = ["subnet-111", "subnet-222"] - certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test" + vpc_id = "vpc-12345678" + shared_alb_subnets = ["subnet-111", "subnet-222"] + certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test" + create_shared_network_load_balancer = false + create_route53_private_hosted_zone = false p4_code_review_config = { fully_qualified_domain_name = "swarm.test.internal" @@ -103,10 +104,12 @@ run "ecs_cluster_shared" { command = plan variables { - vpc_id = "vpc-12345678" - shared_alb_subnets = ["subnet-111", "subnet-222"] - certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test" - shared_ecs_cluster_name = "my-shared-cluster" + vpc_id = "vpc-12345678" + shared_alb_subnets = ["subnet-111", "subnet-222"] + certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test" + shared_ecs_cluster_name = "my-shared-cluster" + create_shared_network_load_balancer = false + create_route53_private_hosted_zone = false p4_auth_config = { fully_qualified_domain_name = "auth.test.internal" @@ -143,7 +146,7 @@ run "route53_private_zone" { route53_private_hosted_zone_name = "perforce.internal" p4_server_config = { - fully_qualified_domain_name = "p4.perforce.internal" + fully_qualified_domain_name = "perforce.internal" instance_subnet_id = "subnet-111" p4_server_type = "p4d_commit" } @@ -170,11 +173,12 @@ run "load_balancer_access_logs" { command = plan variables { - vpc_id = "vpc-12345678" - shared_nlb_subnets = ["subnet-111", "subnet-222"] - shared_alb_subnets = ["subnet-111", "subnet-222"] - certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test" - enable_shared_lb_access_logs = true + vpc_id = "vpc-12345678" + shared_nlb_subnets = ["subnet-111", "subnet-222"] + shared_alb_subnets = ["subnet-111", "subnet-222"] + certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test" + enable_shared_lb_access_logs = true + create_route53_private_hosted_zone = false p4_server_config = { fully_qualified_domain_name = "p4.test.internal" @@ -189,12 +193,12 @@ run "load_balancer_access_logs" { } assert { - condition = length(aws_s3_bucket.lb_access_logs) == 1 + condition = length(aws_s3_bucket.shared_lb_access_logs_bucket) == 1 error_message = "S3 bucket should be created when load balancer access logging is enabled" } assert { - condition = length(aws_lb.perforce_shared_nlb) > 0 ? aws_lb.perforce_shared_nlb[0].enable_cross_zone_load_balancing == true : true + condition = aws_lb.perforce[0].enable_cross_zone_load_balancing == true error_message = "NLB should have cross-zone load balancing enabled" } } @@ -204,9 +208,11 @@ run "no_ecs_cluster_server_only" { command = plan variables { - vpc_id = "vpc-12345678" - shared_nlb_subnets = ["subnet-111", "subnet-222"] - certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test" + vpc_id = "vpc-12345678" + shared_nlb_subnets = ["subnet-111", "subnet-222"] + certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test" + create_shared_application_load_balancer = false + create_route53_private_hosted_zone = false p4_server_config = { fully_qualified_domain_name = "p4.test.internal" diff --git a/modules/perforce/tests/README.md b/modules/perforce/tests/README.md index becd9dec..ae2f05e0 100644 --- a/modules/perforce/tests/README.md +++ b/modules/perforce/tests/README.md @@ -1,292 +1,35 @@ # Perforce Module Tests -This directory contains comprehensive tests for the Perforce wrapper module, organized into unit tests and integration tests. +Mock-based unit tests for the Perforce wrapper module. All tests use mock providers and require no AWS credentials. ## Test Structure ```text tests/ -├── unit/ # Mock-based unit tests -│ ├── 01_conditional_creation.tftest.hcl # Tests submodule conditional creation -│ ├── 02_shared_resources.tftest.hcl # Tests shared resource logic -│ └── README.md # Unit test documentation -│ -├── integration/ # Integration tests with real AWS -│ ├── setup/ # Setup module for SSM parameters -│ │ ├── ssm.tf # SSM parameter data sources -│ │ └── versions.tf # Provider requirements -│ ├── 01_create_resources_complete.tftest.hcl -│ ├── 02_p4_server_fsxn.tftest.hcl -│ └── README.md # Integration test documentation -│ -└── README.md # This file +├── 01_conditional_creation.tftest.hcl # Submodule conditional creation +├── 02_shared_resources.tftest.hcl # Shared resource logic (ECS cluster, Route53, LBs) +└── README.md ``` -## Quick Start - -### Run All Tests - -```bash -cd /path/to/modules/perforce -terraform test -``` - -### Run Only Unit Tests (No AWS Required) - -```bash -terraform test -filter=tests/unit/ -``` - -### Run Only Integration Tests (AWS Required) - -```bash -export AWS_PROFILE=your-profile -terraform test -filter=tests/integration/ -``` - -## Test Types - -### Unit Tests (`unit/`) - -**Purpose:** Validate conditional logic and resource creation without deploying infrastructure - -**Characteristics:** - -- ✅ Uses mock providers (no AWS credentials needed) -- ✅ Fast execution (seconds) -- ✅ Safe to run anywhere -- ✅ Tests all conditional logic paths -- ✅ No AWS costs - -**When to Run:** On every code change, in CI/CD pipelines, during development - -**Test Coverage:** - -- Conditional creation of P4 Server, P4 Auth, and P4 Code Review submodules -- Shared ECS cluster creation logic -- Load balancer and Route53 resource creation -- Security group configurations - -[📖 Unit Tests Documentation](unit/README.md) - -### Integration Tests (`integration/`) - -**Purpose:** Validate that example deployments work with real AWS resources - -**Characteristics:** - -- ⚠️ Requires AWS credentials -- ⚠️ Slower execution (minutes) -- ⚠️ Plans against real AWS (no apply by default) -- ✅ Tests real-world scenarios -- ✅ Validates examples work correctly - -**When to Run:** Before releases, when testing infrastructure changes, in CI/CD with AWS access - -**Test Coverage:** - -- Complete Perforce deployment example -- P4 Server with FSxN storage example -- Example configurations with real parameters - -[📖 Integration Tests Documentation](integration/README.md) - -## CI/CD Integration - -### Validation Workflow - -The `terraform-validation.yml` workflow validates Terraform configurations: - -**What it validates:** - -- All directories containing `.tf` files (modules, submodules, examples, test setup) -- Runs `terraform init` and `terraform validate` -- Skips directories with only `.tftest.hcl` files - -**What triggers it:** - -- Changes to `modules/**/*.tf` or `samples/**/*.tf` -- Push to `main` branch -- Manual workflow dispatch - -### Test Workflow - -The `terraform-tests.yml` workflow runs Terraform tests: - -**What it runs:** - -- All `.tftest.hcl` files in modules with a `tests/` directory -- Automatically runs when module files change -- Requires AWS credentials for integration tests - -**Workflow behavior:** - -- Detects changed modules -- Runs `terraform test` from module root -- Reports failures to pull requests - -## Development Workflow - -### Adding New Features - -1. **Write unit tests first** - Add test scenarios to `unit/` for new conditional logic -2. **Implement the feature** - Modify module code -3. **Run unit tests** - Verify conditional logic works: `terraform test -filter=tests/unit/` -4. **Add integration tests** - If needed, add scenarios to `integration/` -5. **Run all tests** - Verify everything works: `terraform test` - -### Debugging Test Failures - -**Unit test failures:** +## Running Tests ```bash -# Run with verbose output -terraform test -filter=tests/unit/01_conditional_creation.tftest.hcl -verbose - -# Check specific assertion -# Look for "error_message" in the output to see which assertion failed -``` +# From the module root +cd modules/perforce -**Integration test failures:** - -```bash -# Verify AWS credentials -aws sts get-caller-identity +# Run all tests +terraform test -# Check SSM parameters exist -aws ssm get-parameter --name "/cloud-game-development-toolkit/modules/perforce/route53-public-hosted-zone-name" +# Run a specific test file +terraform test -filter=tests/02_shared_resources.tftest.hcl -# Run with verbose output -terraform test -filter=tests/integration/ -verbose +# Verbose output +terraform test -verbose ``` -## Test Maintenance - -### When to Update Tests - -**Update unit tests when:** - -- Adding new conditional logic -- Adding new submodules or shared resources -- Changing variable validation rules -- Modifying resource creation conditions - -**Update integration tests when:** - -- Adding new examples -- Changing example configurations -- Modifying required variables -- Adding new deployment patterns - -### Adding New Test Files - -**Unit tests:** - -1. Create new `.tftest.hcl` file in `unit/` -2. Copy mock provider blocks from existing test -3. Add test scenarios with clear names and assertions -4. Update `unit/README.md` with test documentation - -**Integration tests:** - -1. Create new `.tftest.hcl` file in `integration/` -2. Add required SSM parameters to `integration/setup/ssm.tf` -3. Reference appropriate example deployment -4. Update `integration/README.md` with test documentation - -## Best Practices - -### Writing Good Tests - -✅ **DO:** - -- Use descriptive test names (`p4_server_only` not `test1`) -- Write clear assertion error messages -- Test both success and failure scenarios -- Document complex test logic with comments -- Keep tests focused on one aspect - -❌ **DON'T:** - -- Hardcode sensitive values (use SSM for integration tests) -- Create tests that depend on execution order -- Test implementation details (test behavior, not code) -- Ignore test failures (fix or document expected failures) - -### Mock Provider Patterns - -When creating unit tests: - -1. Always include all mock providers (even if unused) -2. Use realistic mock data (valid ARNs, IDs, etc.) -3. Copy mock blocks from existing tests for consistency -4. Document any custom mock configurations - -## Performance Considerations - -### Test Execution Time - -| Test Type | Typical Duration | Parallelization | -|-----------|-----------------|-----------------| -| Unit (single file) | 2-5 seconds | Yes | -| Unit (all) | 10-15 seconds | Yes | -| Integration (single) | 30-60 seconds | Yes | -| Integration (all) | 2-5 minutes | Yes | - -### Optimizing Test Speed - -- Run unit tests during development (fast feedback) -- Run integration tests before commits (thorough validation) -- Use `-filter` to run specific tests during debugging -- Leverage Terraform's parallel test execution - -## Troubleshooting - -### Common Issues - -#### "No tests found" - -- Ensure you're running from the module root directory -- Verify `.tftest.hcl` files exist in `tests/` subdirectories - -#### "Module not found" - -- Check that module paths are relative to the test file location -- Integration tests should use `../../examples/` for example paths -- Unit tests should reference the module root - -#### "Provider configuration not found" - -- Verify all required mock providers are declared -- Check that provider versions match `versions.tf` - -#### "Variable not set" - -- Ensure all required variables are provided in test scenarios -- Check that variable types match module expectations - -## Additional Resources - -- [Terraform Testing Documentation](https://developer.hashicorp.com/terraform/language/tests) -- [Module README](../README.md) -- [Example Deployments](../examples/) -- [Horde Module Tests](../../unreal/horde/tests/) - Reference implementation - -## Contributing - -When contributing tests: - -1. Follow existing test patterns and naming conventions -2. Update documentation when adding new tests -3. Ensure tests pass locally before submitting PR -4. Add test coverage for new features -5. Keep tests maintainable and well-documented - -## Questions? - -For questions about testing: +## Adding New Tests -- Review the [unit test README](unit/README.md) for mock-based testing -- Review the [integration test README](integration/README.md) for AWS-based testing -- Check the [main module documentation](../README.md) for module usage -- Open an issue in the repository for specific problems +1. Create a new `.tftest.hcl` file in this directory +2. Copy mock provider blocks from an existing test file +3. Add test scenarios with descriptive names and clear assertion messages +4. Use `command = plan` for mock-based testing diff --git a/modules/perforce/tests/integration/01_create_resources_complete.tftest.hcl b/modules/perforce/tests/integration/01_create_resources_complete.tftest.hcl deleted file mode 100644 index ea5ae0df..00000000 --- a/modules/perforce/tests/integration/01_create_resources_complete.tftest.hcl +++ /dev/null @@ -1,27 +0,0 @@ -# Fetch relevant values from SSM Parameter Store -run "setup" { - command = plan - module { - source = "./setup" - } -} - -run "unit_test" { - command = plan - - variables { - route53_public_hosted_zone_name = run.setup.route53_public_hosted_zone_name - } - module { - source = "../../examples/create-resources-complete" - } -} - -# Unused until error handling/retry logic is improved in Terraform test -# https://github.com/hashicorp/terraform/issues/36846#issuecomment-2820247524 -# run "e2e_test" { -# command = apply -# module { -# source = "../../examples/create-resources-complete" -# } -# } diff --git a/modules/perforce/tests/integration/02_p4_server_fsxn.tftest.hcl b/modules/perforce/tests/integration/02_p4_server_fsxn.tftest.hcl deleted file mode 100644 index 0fb0c864..00000000 --- a/modules/perforce/tests/integration/02_p4_server_fsxn.tftest.hcl +++ /dev/null @@ -1,28 +0,0 @@ -# Fetch relevant values from SSM Parameter Store -run "setup" { - command = plan - module { - source = "./setup" - } -} -run "unit_test" { - command = plan - - variables { - route53_public_hosted_zone_name = run.setup.route53_public_hosted_zone_name - fsxn_password = run.setup.fsxn_password - fsxn_aws_profile = run.setup.fsxn_aws_profile - } - module { - source = "../../examples/p4-server-fsxn" - } -} - -# Unused until error handling/retry logic is improved in Terraform test -# https://github.com/hashicorp/terraform/issues/36846#issuecomment-2820247524 -# # run "e2e_test" { -# # command = apply -# # module { -# # source = "../../examples/p4-server-fsxn" -# # } -# # } diff --git a/modules/perforce/tests/integration/README.md b/modules/perforce/tests/integration/README.md deleted file mode 100644 index bc5e9580..00000000 --- a/modules/perforce/tests/integration/README.md +++ /dev/null @@ -1,171 +0,0 @@ -# Perforce Module Integration Tests - -This directory contains integration tests that validate the Perforce module against real AWS infrastructure by invoking the example deployments. - -## Overview - -Integration tests differ from unit tests in that they: - -- **Use real AWS resources** - Actual infrastructure is deployed (in plan mode for safety) -- **Test example deployments** - Validates that examples work correctly -- **Require AWS credentials** - Must have valid AWS authentication configured -- **Use SSM parameters** - Fetch configuration values from AWS Systems Manager Parameter Store - -## Test Files - -### `01_create_resources_complete.tftest.hcl` - -**Purpose:** Validates the complete Perforce deployment example - -**Example Invoked:** `examples/create-resources-complete` - -**Required SSM Parameters:** - -- `/cloud-game-development-toolkit/modules/perforce/route53-public-hosted-zone-name` - -**Test Flow:** - -1. `setup` run - Fetches Route53 zone name from SSM Parameter Store -2. `unit_test` run - Plans the complete example deployment using fetched parameters - -### `02_p4_server_fsxn.tftest.hcl` - -**Purpose:** Validates P4 Server deployment with FSxN (NetApp ONTAP) storage - -**Example Invoked:** `examples/p4-server-fsxn` - -**Required SSM Parameters:** - -- `/cloud-game-development-toolkit/modules/perforce/route53-public-hosted-zone-name` -- `/cloud-game-development-toolkit/modules/perforce/fsxn-password` -- `/cloud-game-development-toolkit/modules/perforce/fsxn-aws-profile` - -**Test Flow:** - -1. `setup` run - Fetches FSxN configuration from SSM Parameter Store -2. `unit_test` run - Plans the FSxN example deployment using fetched parameters - -## Setup Module - -The `setup/` directory contains a Terraform module that fetches test configuration from AWS Systems Manager Parameter Store. - -**Files:** - -- `setup/ssm.tf` - Data sources for SSM parameters and outputs -- `setup/versions.tf` - Terraform and provider version constraints - -**Purpose:** Centralizes test configuration management and avoids hardcoding sensitive values in test files. - -## Running Integration Tests - -### Prerequisites - -1. **AWS Credentials** - Configure AWS authentication: - - ```bash - export AWS_PROFILE=your-profile - # OR - export AWS_ACCESS_KEY_ID=xxx - export AWS_SECRET_ACCESS_KEY=xxx - ``` - -2. **SSM Parameters** - Create required parameters in your AWS account: - - ```bash - aws ssm put-parameter \ - --name "/cloud-game-development-toolkit/modules/perforce/route53-public-hosted-zone-name" \ - --value "your-domain.com" \ - --type String - ``` - -### Run All Integration Tests - -From the module root directory: - -```bash -cd /path/to/modules/perforce -terraform test -filter=tests/integration/ -``` - -### Run Specific Integration Test - -```bash -terraform test -filter=tests/integration/01_create_resources_complete.tftest.hcl -``` - -## E2E Tests (Disabled) - -The integration test files contain commented-out `e2e_test` run blocks that would deploy actual infrastructure using `command = apply`. These are currently disabled due to Terraform test error handling limitations: - -- **Issue:** [hashicorp/terraform#36846](https://github.com/hashicorp/terraform/issues/36846) -- **When to enable:** Once Terraform improves error handling and retry logic for test commands - -## Test Workflow - -Integration tests are automatically run by the `terraform-tests.yml` GitHub Actions workflow: - -**Trigger Conditions:** - -- Pull requests that modify files in `modules/**` -- Manual workflow dispatch - -**Test Discovery:** - -- Finds all modules with a `tests/` directory -- Runs `terraform test` from the module root - -**Note:** Integration tests require AWS credentials configured in the CI environment via GitHub Secrets or OIDC authentication. - -## Comparison with Unit Tests - -| Aspect | Unit Tests | Integration Tests | -|--------|-----------|-------------------| -| **Speed** | Fast (seconds) | Slow (minutes) | -| **AWS Access** | Not required | Required | -| **Infrastructure** | Mock providers | Real AWS resources | -| **Purpose** | Test conditional logic | Test example deployments | -| **When to Run** | Every commit | Before releases | -| **Cost** | Free | AWS costs (minimal with plan-only) | - -## Maintenance - -### Adding New Integration Tests - -1. Create a new `.tftest.hcl` file in this directory -2. Add required SSM parameters to `setup/ssm.tf` -3. Reference the appropriate example deployment -4. Update this README with test details - -### Updating SSM Parameters - -When test configuration changes: - -1. Update SSM parameter values in your AWS account -2. Update `setup/ssm.tf` if new parameters are needed -3. Update integration test files to use new parameters - -## Troubleshooting - -### "Parameter not found" errors - -- Verify SSM parameters exist in your AWS account -- Check parameter names match exactly (case-sensitive) -- Ensure AWS credentials have permission to read SSM parameters - -### "Access denied" errors - -- Verify your IAM role/user has required permissions -- Check that the AWS region is correct -- Ensure AWS credentials are properly configured - -### Example not found errors - -- Verify the example path is correct relative to module root -- Check that the example directory contains valid Terraform files -- Ensure you're running tests from the module root directory - -## Related Documentation - -- [Unit Tests](../unit/README.md) - Mock-based tests for conditional logic -- [Module Examples](../../examples/) - Example deployments referenced by tests -- [Main Module README](../../README.md) - Module usage and configuration diff --git a/modules/perforce/tests/integration/setup/ssm.tf b/modules/perforce/tests/integration/setup/ssm.tf deleted file mode 100644 index 69045cc9..00000000 --- a/modules/perforce/tests/integration/setup/ssm.tf +++ /dev/null @@ -1,24 +0,0 @@ -# Fetch relevant values from SSM Parameter Store -data "aws_ssm_parameter" "route53_public_hosted_zone_name" { - name = "/cloud-game-development-toolkit/modules/perforce/route53-public-hosted-zone-name" -} -data "aws_ssm_parameter" "fsxn_password" { - name = "/cloud-game-development-toolkit/modules/perforce/fsxn-password" -} -data "aws_ssm_parameter" "fsxn_aws_profile" { - name = "/cloud-game-development-toolkit/modules/perforce/fsxn-aws-profile" -} - - -output "route53_public_hosted_zone_name" { - value = nonsensitive(data.aws_ssm_parameter.route53_public_hosted_zone_name.value) - sensitive = false -} -output "fsxn_password" { - value = nonsensitive(data.aws_ssm_parameter.fsxn_password.value) - sensitive = false -} -output "fsxn_aws_profile" { - value = nonsensitive(data.aws_ssm_parameter.fsxn_aws_profile.value) - sensitive = false -} diff --git a/modules/perforce/tests/integration/setup/versions.tf b/modules/perforce/tests/integration/setup/versions.tf deleted file mode 100644 index 0d42e7a6..00000000 --- a/modules/perforce/tests/integration/setup/versions.tf +++ /dev/null @@ -1,10 +0,0 @@ -terraform { - required_version = ">= 1.0" - - required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 6.6" - } - } -} diff --git a/modules/perforce/tests/unit/README.md b/modules/perforce/tests/unit/README.md deleted file mode 100644 index da15ad9a..00000000 --- a/modules/perforce/tests/unit/README.md +++ /dev/null @@ -1,119 +0,0 @@ -# Perforce Module Unit Tests - -This directory contains mock-based unit tests for the Perforce wrapper module. These tests validate the conditional logic and resource creation without requiring AWS credentials or deploying actual infrastructure. - -## Overview - -The Perforce module is a **wrapper module** that orchestrates the deployment of three submodules: - -- **P4 Server** (`modules/p4-server/`) - Perforce Helix Core version control server -- **P4 Auth** (`modules/p4-auth/`) - Perforce authentication service -- **P4 Code Review** (`modules/p4-code-review/`) - Perforce Swarm code review platform - -Unit tests ensure that: - -- Submodules are created only when their configuration is provided -- Shared resources (ECS cluster, load balancers, Route53) are created correctly -- Various combinations of submodules work without conflicts - -## Test Files - -### `01_conditional_creation.tftest.hcl` - -**Purpose:** Validates that submodules are conditionally created based on configuration - -**Test Scenarios (8 total):** - -1. `no_submodules` - No configuration provided, no resources created -2. `p4_server_only` - Only P4 Server deployed -3. `p4_auth_only` - Only P4 Auth deployed -4. `p4_code_review_only` - Only P4 Code Review deployed (note: depends on P4 Server for credentials) -5. `server_and_auth` - P4 Server + P4 Auth combination -6. `server_and_code_review` - P4 Server + P4 Code Review combination -7. `full_stack` - All three submodules deployed together -8. `full_stack_existing_ecs_cluster` - Full stack using an existing ECS cluster - -**Key Validations:** - -- `length(module.p4_server)` equals 0 or 1 based on configuration -- `length(module.p4_auth)` equals 0 or 1 based on configuration -- `length(module.p4_code_review)` equals 0 or 1 based on configuration -- ECS cluster creation logic based on web service deployment - -### `02_shared_resources.tftest.hcl` - -**Purpose:** Validates shared resource creation logic - -**Test Scenarios (6 total):** - -1. `ecs_cluster_auth_only` - ECS cluster created for Auth service -2. `ecs_cluster_code_review_only` - ECS cluster created for Code Review service -3. `ecs_cluster_shared` - Single ECS cluster shared by both services -4. `route53_private_zone` - Private hosted zone and DNS records -5. `load_balancer_access_logs` - S3 bucket for LB access logs -6. `no_ecs_cluster_server_only` - No ECS cluster when only P4 Server is deployed - -**Key Validations:** - -- `local.create_shared_ecs_cluster` logic correctness -- Route53 zone and record configurations -- S3 bucket creation for access logs -- Load balancer configurations - -## Running Tests - -### Run All Unit Tests - -From the module root directory: - -```bash -cd /path/to/modules/perforce -terraform test -``` - -### Run Specific Test File - -```bash -terraform test -filter=tests/unit/01_conditional_creation.tftest.hcl -``` - -### Run Specific Test Scenario - -```bash -terraform test -filter=tests/unit/01_conditional_creation.tftest.hcl -verbose -``` - -## Mock Providers - -All test files use mock providers to simulate AWS resources without making actual API calls: - -- **aws** - Mocks AWS provider with data sources for region, caller identity, ELB service account, ECS cluster, IAM policy documents, and AMI -- **awscc** - Mocks AWS Cloud Control provider -- **random** - Mocks random provider -- **null** - Mocks null provider -- **local** - Mocks local provider -- **netapp-ontap** - Mocks NetApp ONTAP provider (for FSxN storage) - -## Benefits of Unit Tests - -✅ **Fast execution** - No actual resources created, tests complete in seconds -✅ **No AWS credentials required** - Mock providers eliminate need for authentication -✅ **Safe to run anywhere** - No risk of creating unexpected AWS resources -✅ **Comprehensive coverage** - Tests all conditional logic paths -✅ **Easy to debug** - Clear assertions with descriptive error messages -✅ **CI/CD friendly** - Can run in GitHub Actions without AWS access - -## Test Maintenance - -When modifying the Perforce module: - -1. **Adding new submodules** - Add test scenarios to `01_conditional_creation.tftest.hcl` -2. **Adding shared resources** - Add test scenarios to `02_shared_resources.tftest.hcl` -3. **Changing conditional logic** - Update assertions to match new behavior -4. **Adding required variables** - Update all test scenarios with new variables - -## Related Documentation - -- [Integration Tests](../integration/README.md) - Tests that deploy actual infrastructure -- [Module README](../../README.md) - Main module documentation -- [Terraform Testing Documentation](https://developer.hashicorp.com/terraform/language/tests) diff --git a/modules/perforce/variables.tf b/modules/perforce/variables.tf index d2e2809f..2449d65f 100644 --- a/modules/perforce/variables.tf +++ b/modules/perforce/variables.tf @@ -44,8 +44,8 @@ variable "shared_lb_access_logs_bucket" { default = null # This should not be provided if access logging is disabled validation { - condition = var.enable_shared_lb_access_logs ? var.shared_lb_access_logs_bucket != null : true - error_message = "If access logging is disabled, the variable 'shared_lb_access_logs_bucket' must not be provided." + condition = var.enable_shared_lb_access_logs || var.shared_lb_access_logs_bucket == null + error_message = "If access logging is disabled, the variable 'shared_lb_access_logs_bucket' should not be provided." } } @@ -169,10 +169,10 @@ variable "route53_private_hosted_zone_name" { type = string description = "The name of the private Route53 Hosted Zone for the Perforce resources." default = null - # Should only be provided if create_route53_private_hosted_zone is set to true + # Must be provided if create_route53_private_hosted_zone is set to true validation { condition = var.create_route53_private_hosted_zone ? var.route53_private_hosted_zone_name != null : true - error_message = "If create_route53_private_hosted_zone is false, the variable 'route53_private_hosted_zone_name' must not be provided." + error_message = "If create_route53_private_hosted_zone is true, the variable 'route53_private_hosted_zone_name' must be provided." } } @@ -300,27 +300,27 @@ variable "p4_server_config" { default = null validation { - condition = length(var.p4_server_config.name) > 1 && length(var.p4_server_config.name) <= 50 - error_message = "The defined 'name' has too many characters (${length(var.p4_server_config.name)}). This can cause deployment failures for AWS resources with smaller character limits. Please reduce the character count and try again." + condition = var.p4_server_config == null || (length(var.p4_server_config.name) > 1 && length(var.p4_server_config.name) <= 50) + error_message = "The defined 'name' has too many characters. This can cause deployment failures for AWS resources with smaller character limits. Please reduce the character count and try again." } validation { - condition = var.p4_server_config.instance_architecture == "arm64" || var.p4_server_config.instance_architecture == "x86_64" + condition = var.p4_server_config == null || var.p4_server_config.instance_architecture == "arm64" || var.p4_server_config.instance_architecture == "x86_64" error_message = "The p4_server_config.instance_architecture variable must be either 'arm64' or 'x86_64'." } validation { - condition = contains(["p4d_commit", "p4d_replica"], var.p4_server_config.p4_server_type) - error_message = "${var.p4_server_config.p4_server_type} is not one of p4d_commit or p4d_replica." + condition = var.p4_server_config == null || contains(["p4d_commit", "p4d_replica"], var.p4_server_config.p4_server_type) + error_message = "The p4_server_config.p4_server_type must be one of p4d_commit or p4d_replica." } validation { - condition = contains(["EBS", "FSxN"], var.p4_server_config.storage_type) + condition = var.p4_server_config == null || contains(["EBS", "FSxN"], var.p4_server_config.storage_type) error_message = "Not a valid storage type. Valid values are either 'EBS' or 'FSxN'." } validation { - condition = !var.create_route53_private_hosted_zone || var.route53_private_hosted_zone_name == var.p4_server_config.fully_qualified_domain_name + condition = var.p4_server_config == null || !var.create_route53_private_hosted_zone || var.route53_private_hosted_zone_name == var.p4_server_config.fully_qualified_domain_name error_message = "Route53 zone name and Perforce Server FQDN must match." } diff --git a/modules/perforce/versions.tf b/modules/perforce/versions.tf index 80bb5190..4f5e8204 100644 --- a/modules/perforce/versions.tf +++ b/modules/perforce/versions.tf @@ -22,5 +22,9 @@ terraform { source = "hashicorp/local" version = "~> 2.5" } + netapp-ontap = { + source = "NetApp/netapp-ontap" + version = "~> 2.3" + } } } From af771a45b1229e5830c95453f9c3ec799133c994 Mon Sep 17 00:00:00 2001 From: Henry Kiem Date: Fri, 13 Feb 2026 16:58:45 -0800 Subject: [PATCH 2/2] style(perforce): fix terraform fmt on test files --- .../tests/01_conditional_creation.tftest.hcl | 28 +++++++------- .../tests/02_shared_resources.tftest.hcl | 38 +++++++++---------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/modules/perforce/tests/01_conditional_creation.tftest.hcl b/modules/perforce/tests/01_conditional_creation.tftest.hcl index 18e1b122..fd1c3464 100644 --- a/modules/perforce/tests/01_conditional_creation.tftest.hcl +++ b/modules/perforce/tests/01_conditional_creation.tftest.hcl @@ -64,7 +64,7 @@ run "no_submodules" { command = plan variables { - vpc_id = "vpc-12345678" + vpc_id = "vpc-12345678" create_shared_network_load_balancer = false create_shared_application_load_balancer = false create_route53_private_hosted_zone = false @@ -97,9 +97,9 @@ run "p4_server_only" { command = plan variables { - vpc_id = "vpc-12345678" - shared_nlb_subnets = ["subnet-111", "subnet-222", "subnet-333"] - certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test-cert" + vpc_id = "vpc-12345678" + shared_nlb_subnets = ["subnet-111", "subnet-222", "subnet-333"] + certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test-cert" create_shared_application_load_balancer = false create_route53_private_hosted_zone = false @@ -139,11 +139,11 @@ run "p4_auth_only" { command = plan variables { - vpc_id = "vpc-12345678" - shared_alb_subnets = ["subnet-111", "subnet-222", "subnet-333"] - certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test-cert" - create_shared_network_load_balancer = false - create_route53_private_hosted_zone = false + vpc_id = "vpc-12345678" + shared_alb_subnets = ["subnet-111", "subnet-222", "subnet-333"] + certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test-cert" + create_shared_network_load_balancer = false + create_route53_private_hosted_zone = false p4_auth_config = { fully_qualified_domain_name = "auth.test.internal" @@ -178,11 +178,11 @@ run "p4_code_review_only" { command = plan variables { - vpc_id = "vpc-12345678" - shared_alb_subnets = ["subnet-111", "subnet-222", "subnet-333"] - certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test-cert" - create_shared_network_load_balancer = false - create_route53_private_hosted_zone = false + vpc_id = "vpc-12345678" + shared_alb_subnets = ["subnet-111", "subnet-222", "subnet-333"] + certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test-cert" + create_shared_network_load_balancer = false + create_route53_private_hosted_zone = false p4_code_review_config = { fully_qualified_domain_name = "swarm.test.internal" diff --git a/modules/perforce/tests/02_shared_resources.tftest.hcl b/modules/perforce/tests/02_shared_resources.tftest.hcl index 5b0c141a..5973573c 100644 --- a/modules/perforce/tests/02_shared_resources.tftest.hcl +++ b/modules/perforce/tests/02_shared_resources.tftest.hcl @@ -48,11 +48,11 @@ run "ecs_cluster_auth_only" { command = plan variables { - vpc_id = "vpc-12345678" - shared_alb_subnets = ["subnet-111", "subnet-222"] - certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test" - create_shared_network_load_balancer = false - create_route53_private_hosted_zone = false + vpc_id = "vpc-12345678" + shared_alb_subnets = ["subnet-111", "subnet-222"] + certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test" + create_shared_network_load_balancer = false + create_route53_private_hosted_zone = false p4_auth_config = { fully_qualified_domain_name = "auth.test.internal" @@ -76,11 +76,11 @@ run "ecs_cluster_code_review_only" { command = plan variables { - vpc_id = "vpc-12345678" - shared_alb_subnets = ["subnet-111", "subnet-222"] - certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test" - create_shared_network_load_balancer = false - create_route53_private_hosted_zone = false + vpc_id = "vpc-12345678" + shared_alb_subnets = ["subnet-111", "subnet-222"] + certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test" + create_shared_network_load_balancer = false + create_route53_private_hosted_zone = false p4_code_review_config = { fully_qualified_domain_name = "swarm.test.internal" @@ -104,12 +104,12 @@ run "ecs_cluster_shared" { command = plan variables { - vpc_id = "vpc-12345678" - shared_alb_subnets = ["subnet-111", "subnet-222"] - certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test" - shared_ecs_cluster_name = "my-shared-cluster" - create_shared_network_load_balancer = false - create_route53_private_hosted_zone = false + vpc_id = "vpc-12345678" + shared_alb_subnets = ["subnet-111", "subnet-222"] + certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test" + shared_ecs_cluster_name = "my-shared-cluster" + create_shared_network_load_balancer = false + create_route53_private_hosted_zone = false p4_auth_config = { fully_qualified_domain_name = "auth.test.internal" @@ -208,9 +208,9 @@ run "no_ecs_cluster_server_only" { command = plan variables { - vpc_id = "vpc-12345678" - shared_nlb_subnets = ["subnet-111", "subnet-222"] - certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test" + vpc_id = "vpc-12345678" + shared_nlb_subnets = ["subnet-111", "subnet-222"] + certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/test" create_shared_application_load_balancer = false create_route53_private_hosted_zone = false