This project is used to create an operational assessment environment in the COOL environment.
-
Terraform installed on your system.
-
An accessible AWS S3 bucket to store Terraform state (specified in
backend.tf
). -
An accessible AWS DynamoDB database to store the Terraform state lock (specified in
backend.tf
). -
Access to all of the Terraform remote states specified in
remote_states.tf
. -
Accept the terms for any AWS Marketplace subscriptions to be used by the operations instances in your assessment environment (must be done in the AWS account hosting the assessment environment):
-
Access to AWS AMIs for Guacamole and any other operations instance types used in your assessment.
-
OpenSSL server certificate and private key for the Guacamole instance in your assessment environment, stored in an accessible AWS S3 bucket; this can be easily created via certboto-docker or a similar tool.
-
A Terraform variables file customized for your assessment environment, for example:
assessment_account_name = "env0" private_domain = "env0" vpc_cidr_block = "10.224.0.0/21" operations_subnet_cidr_block = "10.224.0.0/24" private_subnet_cidr_blocks = ["10.224.1.0/24", "10.224.2.0/24"] tags = { Team = "VM Fusion - Development" Application = "COOL - env0 Account" Workspace = "env0" }
-
Create a Terraform workspace (if you haven't already done so) for your assessment by running
terraform workspace new <workspace_name>
. -
Create a
<workspace_name>.tfvars
file with all of the required variables (see Inputs below for details). -
Run the command
terraform init
. -
Add all necessary permissions by running the command:
terraform apply -var-file=<workspace_name>.tfvars --target=aws_iam_policy.provisionassessment_policy --target=aws_iam_role_policy_attachment.provisionassessment_policy_attachment
-
Create all remaining Terraform infrastructure by running the command:
terraform apply -var-file=<workspace_name>.tfvars
Name | Version |
---|---|
terraform | ~> 1.5 |
aws | ~> 4.9 |
cloudinit | ~> 2.0 |
null | ~> 3.0 |
Name | Version |
---|---|
aws | ~> 4.9 |
aws.dns_sharedservices | ~> 4.9 |
aws.organizationsreadonly | ~> 4.9 |
aws.parameterstorereadonly | ~> 4.9 |
aws.provisionassessment | ~> 4.9 |
aws.provisionparameterstorereadrole | ~> 4.9 |
aws.provisionsharedservices | ~> 4.9 |
aws.provisionusers | ~> 4.9 |
cloudinit | ~> 2.0 |
null | ~> 3.0 |
terraform | n/a |
Name | Source | Version |
---|---|---|
cw_alarms_assessor_workbench | github.com/cisagov/instance-cw-alarms-tf-module | n/a |
cw_alarms_debiandesktop | github.com/cisagov/instance-cw-alarms-tf-module | n/a |
cw_alarms_egressassess | github.com/cisagov/instance-cw-alarms-tf-module | n/a |
cw_alarms_gophish | github.com/cisagov/instance-cw-alarms-tf-module | n/a |
cw_alarms_guacamole | github.com/cisagov/instance-cw-alarms-tf-module | n/a |
cw_alarms_kali | github.com/cisagov/instance-cw-alarms-tf-module | n/a |
cw_alarms_nessus | github.com/cisagov/instance-cw-alarms-tf-module | n/a |
cw_alarms_pentestportal | github.com/cisagov/instance-cw-alarms-tf-module | n/a |
cw_alarms_samba | github.com/cisagov/instance-cw-alarms-tf-module | n/a |
cw_alarms_teamserver | github.com/cisagov/instance-cw-alarms-tf-module | n/a |
cw_alarms_terraformer | github.com/cisagov/instance-cw-alarms-tf-module | n/a |
cw_alarms_windows | github.com/cisagov/instance-cw-alarms-tf-module | n/a |
email_sending_domain_certreadrole | github.com/cisagov/cert-read-role-tf-module | n/a |
guacamole_certreadrole | github.com/cisagov/cert-read-role-tf-module | n/a |
read_terraform_state | github.com/cisagov/terraform-state-read-role-tf-module | n/a |
read_write_terraform_state | github.com/cisagov/terraform-state-read-role-tf-module | n/a |
session_manager | github.com/cisagov/session-manager-tf-module | n/a |
vpc_flow_logs | trussworks/vpc-flow-logs/aws | ~>2.0 |
Name | Description | Type | Default | Required |
---|---|---|---|---|
assessment_account_name | The name of the AWS account for this assessment (e.g. "env0"). | string |
n/a | yes |
assessment_artifact_export_enabled | Whether or not to enable the export of assessment artifacts to an S3 bucket. If this is set to true, then the following variables should also be configured appropriately: assessment_artifact_export_map, ssm_key_artifact_export_access_key_id, ssm_key_artifact_export_secret_access_key, ssm_key_artifact_export_bucket_name, and ssm_key_artifact_export_region. | bool |
false |
no |
assessment_artifact_export_map | A map whose keys are assessment types and whose values are the prefixes for what an assessment artifact will be named when it is exported to the S3 bucket contained in the SSM parameter specified by the ssm_key_artifact_export_bucket_name variable (e.g. { "PenTest" : "pentest/PT", "Phishing" : "phishing/PH", "RedTeam" : "redteam/RT" }). Note that prefixes can include a path within the bucket. For example, if the prefix is "pentest/PT" and the assessment ID is "ASMT1234", then the corresponding artifact will be exported to "bucket-name/pentest/PT-ASMT1234.tgz" when the archive-artifact-data-to-bucket.sh script is run. | map(string) |
{} |
no |
assessment_id | The identifier for this assessment (e.g. "ASMT1234"). | string |
"" |
no |
assessment_type | The type of this assessment (e.g. "PenTest"). | string |
"" |
no |
assessmentfindingsbucketwrite_sharedservices_policy_description | The description to associate with the IAM policy that allows assumption of the role in the Shared Services account that is allowed to write to the assessment findings bucket. | string |
"Allows assumption of the role in the Shared Services account that is allowed to write to the assessment findings bucket." |
no |
assessmentfindingsbucketwrite_sharedservices_policy_name | The name to assign the IAM policy that allows assumption of the role in the Shared Services account that is allowed to write to the assessment findings bucket. | string |
"SharedServices-AssumeAssessmentFindingsBucketWrite" |
no |
assessor_account_role_arn | The ARN of an IAM role that can be assumed to create, delete, and modify AWS resources in a separate assessor-owned AWS account. | string |
"arn:aws:iam::123456789012:role/Allow_It" |
no |
aws_availability_zone | The AWS availability zone to deploy into (e.g. a, b, c, etc.). | string |
"a" |
no |
aws_region | The AWS region where the non-global resources for this assessment are to be provisioned (e.g. "us-east-1"). | string |
"us-east-1" |
no |
cert_bucket_name | The name of the AWS S3 bucket where certificates are stored. | string |
"cisa-cool-certificates" |
no |
cool_domain | The domain where the COOL resources reside (e.g. "cool.cyber.dhs.gov"). | string |
"cool.cyber.dhs.gov" |
no |
dns_ttl | The TTL value to use for Route53 DNS records (e.g. 86400). A smaller value may be useful when the DNS records are changing often, for example when testing. | number |
60 |
no |
efs_access_point_gid | The group ID that should be used for file-system access to the EFS share (e.g. 2048). Note that this value should match the GID of any group given ownership of the EFS share mount point. | number |
2048 |
no |
efs_access_point_root_directory | The non-root path to use as the root directory for the AWS EFS access point that controls EFS access for assessment data sharing. | string |
"/assessment_share" |
no |
efs_access_point_uid | The user ID that should be used for file-system access to the EFS share (e.g. 2048). Note that this value should match the UID of any user given ownership of the EFS share mount point. | number |
2048 |
no |
efs_users_group_name | The name of the POSIX group that should have ownership of a mounted EFS share (e.g. "efs_users"). | string |
"efs_users" |
no |
email_sending_domains | The list of domains to send emails from within the assessment environment (e.g. [ "example.com" ]). Teamserver and Gophish instances will be deployed with each sequential domain in the list, so teamserver0 and gophish0 will get the first domain, teamserver1 and gophish1 will get the second domain, and so on. If there are more Teamserver or Gophish instances than email-sending domains, the domains in the list will be reused in a wrap-around fashion. For example, if there are three Teamservers and only two email-sending domains, teamserver0 will get the first domain, teamserver1 will get the second domain, and teamserver2 will wrap-around back to using the first domain. Note that all letters in this variable must be lowercase or else an error will be displayed. | list(string) |
[ "example.com" ] |
no |
findings_data_bucket_name | The name of the AWS S3 bucket where findings data is to be written. The default value is not a valid string for a bucket name, so findings data cannot be written to any bucket unless a value is specified. | string |
"" |
no |
guac_connection_setup_path | The full path to the dbinit directory where initialization files must be stored in order to work properly. (e.g. "/var/guacamole/dbinit") | string |
"/var/guacamole/dbinit" |
no |
iam_users_allowed_to_self_deploy | A list of IAM usernames corresponding to the IAM users in the Users account who are allowed to self-deploy. E.g., ["first.last"]. Note that these users must already be included in cisagov/cool-assessment-provisioner-iam, presumably with backend_access equal to false. | list(string) |
[] |
no |
inbound_ports_allowed | An object specifying the ports allowed inbound (from anywhere) to the various instance types (e.g. {"assessorworkbench" : [], "debiandesktop" : [], "egressassess" : [], "gophish" : [], "kali": [{"protocol": "tcp", "from_port": 443, "to_port": 443}, {"protocol": "tcp", "from_port": 9000, "to_port": 9009}], "nessus" : [], "pentestportal" : [], "samba" : [], "teamserver" : [], "terraformer" : [], "windows" : [], }). | object({ assessorworkbench = list(object({ protocol = string, from_port = number, to_port = number })), debiandesktop = list(object({ protocol = string, from_port = number, to_port = number })), egressassess = list(object({ protocol = string, from_port = number, to_port = number })), gophish = list(object({ protocol = string, from_port = number, to_port = number })), kali = list(object({ protocol = string, from_port = number, to_port = number })), nessus = list(object({ protocol = string, from_port = number, to_port = number })), pentestportal = list(object({ protocol = string, from_port = number, to_port = number })), samba = list(object({ protocol = string, from_port = number, to_port = number })), teamserver = list(object({ protocol = string, from_port = number, to_port = number })), terraformer = list(object({ protocol = string, from_port = number, to_port = number })), windows = list(object({ protocol = string, from_port = number, to_port = number })), }) |
{ "assessorworkbench": [], "debiandesktop": [], "egressassess": [], "gophish": [], "kali": [], "nessus": [], "pentestportal": [], "samba": [], "teamserver": [], "terraformer": [], "windows": [] } |
no |
nessus_activation_codes | The list of Nessus activation codes (e.g. ["AAAA-BBBB-CCCC-DDDD"]). The number of codes in this list should match the number of Nessus instances defined in operations_instance_counts. | list(string) |
[] |
no |
nessus_web_server_port | The port on which the Nessus web server should listen (e.g. 8834). | number |
8834 |
no |
operations_instance_counts | A map specifying how many instances of each type should be created in the operations subnet (e.g. { "assessorworkbench" : 0, "debiandesktop" : 0, "egressassess" : 0,"gophish" : 0, "kali": 1, "nessus" : 0, "pentestportal" : 0, "samba" : 0, "teamserver" : 0, "terraformer" : 0, "windows" : 1, }). | object({ assessorworkbench = number, debiandesktop = number, egressassess = number, gophish = number, kali = number, nessus = number, pentestportal = number, samba = number, teamserver = number, terraformer = number, windows = number }) |
{ "assessorworkbench": 0, "debiandesktop": 0, "egressassess": 0, "gophish": 0, "kali": 1, "nessus": 0, "pentestportal": 0, "samba": 0, "teamserver": 0, "terraformer": 0, "windows": 1 } |
no |
operations_subnet_cidr_block | The operations subnet CIDR block for this assessment (e.g. "10.10.0.0/24"). | string |
n/a | yes |
private_domain | The local domain to use for this assessment (e.g. "env0"). If not provided, local.private_domain will be set to the base of the assessment account name. For example, if the account name is "env0 (Staging)", local.private_domain will default to "env0". Note that local.private_domain should be used in place of var.private_domain throughout this project. |
string |
"" |
no |
private_subnet_cidr_blocks | The list of private subnet CIDR blocks for this assessment (e.g. ["10.10.1.0/24", "10.10.2.0/24"]). | list(string) |
n/a | yes |
provisionaccount_role_name | The name of the IAM role that allows sufficient permissions to provision all AWS resources in the assessment account. | string |
"ProvisionAccount" |
no |
provisionassessment_policy_description | The description to associate with the IAM policy that allows provisioning of the resources required in the assessment account. | string |
"Allows provisioning of the resources required in the assessment account." |
no |
provisionassessment_policy_name | The name to assign the IAM policy that allows provisioning of the resources required in the assessment account. | string |
"ProvisionAssessment" |
no |
provisionssmsessionmanager_policy_description | The description to associate with the IAM policy that allows sufficient permissions to provision the SSM Document resource and set up SSM session logging in this assessment account. | string |
"Allows sufficient permissions to provision the SSM Document resource and set up SSM session logging in this assessment account." |
no |
provisionssmsessionmanager_policy_name | The name to assign the IAM policy that allows sufficient permissions to provision the SSM Document resource and set up SSM session logging in this assessment account. | string |
"ProvisionSSMSessionManager" |
no |
publish_egress_ip_addresses | A boolean value that specifies whether EC2 instances in the operations subnet should be tagged to indicate that their public IP addresses may be published. This is useful for deconfliction purposes. Publishing these addresses can be done via the code in cisagov/publish-egress-ip-lambda and cisagov/publish-egress-ip-terraform. | bool |
false |
no |
read_terraform_state_role_name | The name to assign the IAM role (as well as the corresponding policy) that allows read-only access to the cool-assessment-terraform state in the S3 bucket where Terraform state is stored. The %s in this name will be replaced by the value of the assessment_account_name variable. | string |
"ReadCoolAssessmentTerraformTerraformState-%s" |
no |
read_write_terraform_state_role_name | The name to assign the IAM role (as well as the corresponding policy) that allows read-write access to the cool-assessment-terraform state in the S3 bucket where Terraform state is stored. The %s in this name will be replaced by the value of the assessment_account_name variable. | string |
"ReadWriteCoolAssessmentTerraformTerraformState-%s" |
no |
session_cloudwatch_log_group_name | The name of the log group into which session logs are to be uploaded. | string |
"/ssm/session-logs" |
no |
ssm_key_artifact_export_access_key_id | The AWS SSM Parameter Store parameter that contains the AWS access key of the IAM user that can write to the assessment artifact export bucket (e.g. "/assessment_artifact_export/access_key_id"). | string |
"/assessment_artifact_export/access_key_id" |
no |
ssm_key_artifact_export_bucket_name | The AWS SSM Parameter Store parameter that contains the name of the assessment artifact export bucket (e.g. "/assessment_artifact_export/bucket"). | string |
"/assessment_artifact_export/bucket" |
no |
ssm_key_artifact_export_region | The AWS SSM Parameter Store parameter that contains the region of the IAM user (specified via ssm_key_artifact_export_access_key_id) that can write to the assessment artifact export bucket (e.g. "/assessment_artifact_export/region"). | string |
"/assessment_artifact_export/region" |
no |
ssm_key_artifact_export_secret_access_key | The AWS SSM Parameter Store parameter that contains the AWS secret access key of the IAM user that can write to the assessment artifact export bucket (e.g. "/assessment_artifact_export/secret_access_key"). | string |
"/assessment_artifact_export/secret_access_key" |
no |
ssm_key_nessus_admin_password | The AWS SSM Parameter Store parameter that contains the password of the Nessus admin user (e.g. "/nessus/assessment/admin_password"). | string |
"/nessus/assessment/admin_password" |
no |
ssm_key_nessus_admin_username | The AWS SSM Parameter Store parameter that contains the username of the Nessus admin user (e.g. "/nessus/assessment/admin_username"). | string |
"/nessus/assessment/admin_username" |
no |
ssm_key_samba_username | The AWS SSM Parameter Store parameter that contains the username of the Samba user (e.g. "/samba/username"). | string |
"/samba/username" |
no |
ssm_key_vnc_ssh_public_key | The AWS SSM Parameter Store parameter that contains the SSH public key that corresponds to the private SSH key of the VNC user (e.g. "/vnc/ssh/ed25519_public_key"). | string |
"/vnc/ssh/ed25519_public_key" |
no |
ssm_key_vnc_username | The AWS SSM Parameter Store parameter that contains the username of the VNC user (e.g. "/vnc/username"). | string |
"/vnc/username" |
no |
tags | Tags to apply to all AWS resources created | map(string) |
{} |
no |
terraformer_permissions_boundary_policy_description | The description to associate with the IAM permissions boundary policy attached to the Terraformer instance role in order to protect the foundational resources deployed in this account. | string |
"The IAM permissions boundary policy attached to the Terraformer instance role in order to protect the foundational resources deployed in this account." |
no |
terraformer_permissions_boundary_policy_name | The name to assign the IAM permissions boundary policy attached to the Terraformer instance role in order to protect the foundational resources deployed in this account. | string |
"TerraformerPermissionsBoundary" |
no |
terraformer_role_description | The description to associate with the IAM role (and policy) that allows Terraformer instances to create appropriate AWS resources in this account. | string |
"Allows Terraformer instances to create appropriate AWS resources in this account." |
no |
terraformer_role_name | The name to assign the IAM role (and policy) that allows Terraformer instances to create appropriate AWS resources in this account. | string |
"Terraformer" |
no |
valid_assessment_id_regex | A regular expression that specifies valid assessment identifiers (e.g. "^ASMT[[:digit:]]{4}$"). | string |
"" |
no |
valid_assessment_types | A list of valid assessment types (e.g. ["PenTest", "Phishing", "RedTeam"]). If this list is empty (i.e. []), then any value used for assessment_type will trigger a validation error. | list(string) |
[ "" ] |
no |
vpc_cidr_block | The CIDR block to use this assessment's VPC (e.g. "10.224.0.0/21"). | string |
n/a | yes |
windows_with_docker | A boolean to control the instance type used when creating Windows instances to allow Docker Desktop support. Windows instances require the metal instance type to run Docker Desktop because of nested virtualization, but if Docker Desktop is not needed then other instance types are fine. |
bool |
false |
no |
Name | Description |
---|---|
assessment_private_zone | The private DNS zone for this assessment. |
assessor_workbench_instance_profile | The instance profile for the Assessor Workbench instances. |
assessor_workbench_instances | The Assessor Workbench instances. |
assessor_workbench_security_group | The security group for the Assessor Workbench instances. |
aws_region | The AWS region where this assessment environment lives. |
certificate_bucket_name | The name of the S3 bucket where certificate information is stored for this assessment. |
cloudwatch_agent_endpoint_client_security_group | A security group for any instances that run the AWS CloudWatch agent. This security groups allows such instances to communicate with the VPC endpoints that are required by the AWS CloudWatch agent. |
debian_desktop_instance_profile | The instance profile for the Debian desktop instances. |
debian_desktop_instances | The Debian desktop instances. |
debian_desktop_security_group | The security group for the Debian desktop instances. |
dynamodb_endpoint_client_security_group | A security group for any instances that wish to communicate with the DynamoDB VPC endpoint. |
ec2_endpoint_client_security_group | A security group for any instances that wish to communicate with the EC2 VPC endpoint. |
efs_access_points | The access points to control file-system access to the EFS file share. |
efs_client_security_group | A security group that should be applied to all instances that will mount the EFS file share. |
efs_mount_targets | The mount targets for the EFS file share. |
egressassess_instance_profile | The instance profile for the Egress-Assess instances. |
egressassess_instances | The Egress-Assess instances. |
egressassess_security_group | The security group for the Egress-Assess instances. |
email_sending_domain_certreadroles | The IAM roles that allow for reading the certificate for each email-sending domain. |
gophish_instance_profiles | The instance profiles for the Gophish instances. |
gophish_instances | The Gophish instances. |
gophish_security_group | The security group for the Gophish instances. |
guacamole_accessible_security_group | A security group that should be applied to all instances that are to be accessible from Guacamole. |
guacamole_server | The AWS EC2 instance hosting Guacamole. |
kali_instance_profile | The instance profile for the Kali instances. |
kali_instances | The Kali instances. |
kali_security_group | The security group for the Kali instances. |
nessus_instance_profile | The instance profile for the Nessus instances. |
nessus_instances | The Nessus instances. |
nessus_security_group | The security group for the Nessus instances. |
operations_subnet | The operations subnet. |
operations_subnet_acl | The access control list (ACL) for the operations subnet. |
pentest_portal_instance_profile | The instance profile for the Pentest Portal instances. |
pentest_portal_instances | The Pentest Portal instances. |
pentest_portal_security_group | The security group for the Pentest Portal instances. |
private_subnet_acls | The access control lists (ACLs) for the private subnets. |
private_subnet_cidr_blocks | The private subnet CIDR blocks. These are used to index into the private_subnets and efs_mount_targets outputs. |
private_subnet_nat_gateway | The NAT gateway for the private subnets. |
private_subnets | The private subnets. |
read_terraform_state_module | The IAM policies and role that allow read-only access to the cool-assessment-terraform workspace-specific state in the Terraform state bucket. |
read_write_terraform_state_module | The IAM policies and role that allow read-write access to the cool-assessment-terraform workspace-specific state in the Terraform state bucket. |
remote_desktop_url | The URL of the remote desktop gateway (Guacamole) for this assessment. |
s3_endpoint_client_security_group | A security group for any instances that wish to communicate with the S3 VPC endpoint. |
samba_client_security_group | The security group that should be applied to all instance types that wish to mount the Samba file share being served by the Samba file share server instances. |
samba_instance_profile | The instance profile for the Samba file share server instances. |
samba_instances | The Samba file share server instances. |
samba_server_security_group | The security group for the Samba file share server instances. |
scanner_security_group | A security group that should be applied to all instance types that perform scanning. This security group allows egress to anywhere as well as ingress from anywhere via ICMP. |
ssm_agent_endpoint_client_security_group | A security group for any instances that run the AWS SSM agent. This security group allows such instances to communicate with the VPC endpoints that are required by the AWS SSM agent. |
ssm_endpoint_client_security_group | A security group for any instances that wish to communicate with the SSM VPC endpoint. |
ssm_session_role | An IAM role that allows creation of SSM SessionManager sessions to any EC2 instance in this account. |
sts_endpoint_client_security_group | A security group for any instances that wish to communicate with the STS VPC endpoint. |
teamserver_instance_profiles | The instance profiles for the Teamserver instances. |
teamserver_instances | The Teamserver instances. |
teamserver_security_group | The security group for the Teamserver instances. |
terraformer_instances | The Terraformer instances. |
terraformer_permissions_boundary_policy | The permissions boundary policy for the Terraformer instances. |
terraformer_security_group | The security group for the Terraformer instances. |
vpc | The VPC for this assessment environment. |
vpn_server_cidr_block | The CIDR block for the COOL VPN. |
windows_instance_profile | The instance profile for the Windows instances. |
windows_instances | The Windows instances. |
windows_security_group | The security group for the Windows instances. |
Running pre-commit
requires running terraform init
in every directory that
contains Terraform code. In this repository, this is only the main directory.
We welcome contributions! Please see CONTRIBUTING.md
for
details.
This project is in the worldwide public domain.
This project is in the public domain within the United States, and copyright and related rights in the work worldwide are waived through the CC0 1.0 Universal public domain dedication.
All contributions to this project will be released under the CC0 dedication. By submitting a pull request, you are agreeing to comply with this waiver of copyright interest.