Terraform Provider

The Control Plane Terraform Provider Plugin enables the scaffolding of any Control Plane object as code using HCL. It enables infrastructure as code with all the added benefit of the global virtual cloud (GVC). You can build your VPCs, subnets, databases, queues, caches, etc. and overlay them with a multi-cloud/multi-region universal compute workloads that span regions and clouds. Nearly everything you can do using the Control Plane CLI, UI or API is available using Terraform.

Each header below (i.e., cpln_agent) corresponds to a resource within the Control Plane Terraform provider.

Authentication

Authenticate using one of the following methods:

  1. CLI
  • Install the CLI and execute the command cpln login. After a successful login, the provider will use the default profile to authenticate. To use a different profile, set the profile variable when initializing the provider or set the CPLN_PROFILE environment variable.
  1. Token
  • The token variable can be set when initializing the provider or by setting the CPLN_TOKEN environment variable.
  • The value of token can be either:
    • The output of running the command cpln profile token PROFILE_NAME, or
    • In the case of a Service Account, the value of one of it's keys

Note: To perform automated tasks using Terraform, the preferred method is to use a Service Account and one of it's keys as the token value.

Provider Declaration

Required

  • org (String) The Control Plane org that this provider will perform actions against. Can be specified with the CPLN_ORG environment variable.

Optional

  • endpoint (String) The Control Plane Data Service API endpoint. Default is: "https://api.cpln.io". Can be specified with the CPLN_ENDPOINT environment variable.
  • profile (String) The user/service account profile that this provider will use to authenticate to the data service. Can be specified with the CPLN_PROFILE environment variable.
  • token (String) The generated token that can be used to authenticate to the data service API. Can be specified with the CPLN_TOKEN environment variable.

Note: If the token value is empty, the Control Plane CLI (cpln) must be installed and the command cpln login must be used to authenticate.

Example Usage

copy
terraform {
required_providers {
cpln = {
version = "1.0.1"
source = "controlplane.com/com/cpln"
}
}
}
provider "cpln" {
# Required
# Can use CPLN_ORG Environment Variable
org = var.org
# Optional
# Default Value: https://api.cpln.io
# Can use CPLN_ENDPOINT Environment Variable
endpoint = var.endpoint
# Optional
# Can use CPLN_PROFILE Environment Variable
profile = var.profile
# Optional
# Can use CPLN_TOKEN Environment Variable
token = var.token
}

cpln_agent

Support the creation of an account Agent. Multiple agents can be created for an account.

These allow secure communication between workloads running on the Control Plane platform and TCP endpoints inside private networks such as VPCs.

Declaration

Required

  • name (String) Name of the Agent.

Optional

  • description (String) Description of the Agent.
  • tags (Map of String) Key-value map of resource tags.

Outputs

The following attributes are exported:

  • self_link (String) Full link to this resource. Can be referenced by other resources.
  • user_data (String, Sensitive) The JSON output used when creating an agent.

Example Usage

copy
resource "cpln_agent" "example" {
name = "agent-example"
description = "Example Agent"
tags = {
terraform_generated = "true"
example = "true"
}
}

cpln_cloud_account

Cloud Accounts enable Control Plane identities (workload identities) to define least-privilege access rules so that workloads can seamlessly consume resources from one or multiple clouds. The cpln_cloud_account resource defines a cloud account of either AWS, Azure or GCP.

The configuration at the associated cloud provider must exist before using Terraform to manage a Cloud Account.

Refer to the Cloud Account Reference Page for additional details.

Declaration

Required

  • name (String)

Optional

  • description (String) Description of the Cloud Account.
  • tags (Map of String) Key-value map of resource tags.
  • aws (Block List, Max: 1) (see below).
  • azure (Block List, Max: 1) (see below).
  • gcp (Block List, Max: 1) (see below).

aws

Required:

  • role_arn (String) Amazon Resource Name (ARN) Role.

azure

Required:

  • secret_link (String) Full link to an Azure secret. (e.g., /org/ORG_NAME/secret/AZURE_SECRET).

gcp

Required:

  • project_id (String) GCP project ID. Obtained from the GCP cloud console.

Outputs

The following attributes are exported:

  • cpln_id (String) ID, in GUID format, of the Cloud Account.
  • self_link (String) Full link to this resource. Can be referenced by other resources.

Example Usage

copy
# AWS Cloud Account
resource "cpln_cloud_account" "aws" {
name = "cloud-account-aws"
description = "AWS cloud account"
tags = {
terraform_generated = "true"
example = "true"
}
aws {
role_arn = "arn:aws:iam::1234:role/test_role"
}
}
# Azure Cloud Account
resource "cpln_cloud_account" "azure" {
name = "cloud-account-azure"
description = "Azure cloud account "
tags = {
terraform_generated = "true"
example = "true"
}
azure {
// Use full link
secret_link = "/org/ORG_NAME/secret/AZURE_SECRET"
}
}
# GCP Cloud Account
resource "cpln_cloud_account" "gcp" {
name = "cloud-account-gcp"
description = "GCP cloud account"
tags = {
terraform_generated = "true"
example = "true"
}
gcp {
project_id = "cpln_gcp_project_1234"
}
}

cpln_domain

Manages an org's custom Domain.

The required DNS entries must exist before using Terraform to manage a Domain.

Refer to the Configure a Domain page for additional details.

During the creation of a domain, Control Plane will verify that the DNS entries exists. If they do not exist, the Terraform script will fail.

Declaration

Required

  • name (String) Domain name. Must be a valid domain name with at least three segments (e.g., test.example.com). Control Plane will validate the existence of the domain with DNS. Create and Update will fail if the required DNS entries cannot be validated.

Optional

  • description (String) Description for the domain name.
  • tags (Map of String) Key-value map of resource tags.

Outputs

The following attributes are exported:

  • self_link (String) Full link to this resource. Can be referenced by other resources.

Example Usage

copy
resource "cpln_domain" "example" {
name = "app.example.com"
description = "Custom domain that can be set on a GVC and used by associated workloads"
tags = {
terraform_generated = "true"
example = "true"
}
}

cpln_group

Manages an org's Groups.

Groups membership can contain users, service accounts, and custom queries.

Declaration

Required

  • name (String) Name of the Group.

Optional

  • description (String) Description of Group.

  • tags (Map of String) Key-value map of resource tags.

  • service_accounts (List of String) List of service accounts that exists within the configured org. Group membership will fail if the service account does not exits within the org.

  • user_ids_and_emails (List of String) List of either the user ID or email address for a user that exists within the configured org. Group membership will fail if the user ID / email does not exist within the org.

  • member_query (Block List, Max: 1) (see below).

member_query

Optional:

  • fetch (String) Type of fetch. Specify either: links or items. Default: items.
  • spec (Block List, Max: 1) (see below).

member_query.spec

Optional:

  • match (String) Type of match. Available values: all, any, none. Default: all.
  • terms (Block List) (see below).

member_query.spec.terms

Terms can only contain one of the following attributes: property, tag.

Optional:

  • op (String) Type of query operation. Available values: =, >, >=, <, <=, !=, exists, !exists. Default: =.

  • property (String) Property to use for query evaluation.

  • tag (String) Tag key to use for query evaluation.

  • value (String) Testing value for query evaluation.

Outputs

The following attributes are exported:

  • origin (String) Origin of the service account. Either builtin or default.
  • self_link (String) Full link to this resource. Can be referenced by other resources.

Example Usage

copy
resource "cpln_service_account" "example" {
name = "service-account-example"
description = "Service Account to be used as a member of a group"
tags = {
terraform_generated = "true"
example = "true"
}
}
resource "cpln_group" "example" {
name = "group-example"
description = "group description ${var.random-name}"
tags = {
terraform_generated = "true"
example = "true"
}
user_ids_and_emails = ["valid_user@example.com"]
service_accounts = [cpln_service_account.example.name]
member_query {
fetch = "items"
spec {
match = "all"
terms {
op = "="
tag = "firebase/sign_in_provider"
value = "microsoft.com"
}
}
}
}

cpln_gvc

Manages an org's Global Virtual Cloud (GVC).

Declaration

Required

  • name (String) Name of the GVC.
  • locations (List of String) A list of locations making up the Global Virtual Cloud.

Optional

  • description (String) Description of the GVC.

  • tags (Map of String) Key-value map of resource tags.

  • domain (String) Custom domain used by associated workloads.

Outputs

The following attributes are exported:

  • self_link (String) Full link to this resource. Can be referenced by other resources.

Example Usage

copy
resource "cpln_gvc" "example" {
name = "gvc-example"
description = "Example GVC"
# Example Locations: `aws-eu-central-1`, `aws-us-west-2`, `azure-east2`, `gcp-us-east1`
locations = ["aws-eu-central-1", "aws-us-west-2"]
# domain = "app.example.com"
tags = {
terraform_generated = "true"
example = "true"
}
}

cpln_identity

Manages a GVC's Identities.

Declaration

Required

  • name (String) Name of the Identity.
  • gvc (String) Name of the GVC.

Optional

  • description (String) Description of the Identity.

  • tags (Map of String) Key-value map of resource tags.

  • aws_access_policy (Block List, Max: 1) (see below).

  • azure_access_policy (Block List, Max: 1) (see below).

  • gcp_access_policy (Block List, Max: 1) (see below).

  • network_resource (Block List) (see below).

aws_access_policy

Required:

  • cloud_account_link (String) Full link to referenced cloud account.

Optional:

Note: AWS Identity can either contain an existing role_name or multiple policy_refs.

  • policy_refs (List of String) List of policies.
  • role_name (String) Role name.

azure_access_policy

Optional:

  • cloud_account_link (String) Full link to referenced cloud account.
  • role_assignment (Block List) (see below).

azure_access_policy.role_assignment

Optional:

  • roles (List of String) List of assigned roles.
  • scope (String) Scope of roles.

gcp_access_policy

Note: The GCP access policy can either contain an existing service_account or multiple bindings.

  • cloud_account_link (String) Full link to referenced Cloud Account.

  • scopes (String) Comma delimited list of GCP scope URLs.

  • service_account (String) Name of existing GCP service account.

  • binding (Block List) (see below).

gcp_access_policy.binding

Optional:

  • resource (String) Name of resource for binding.
  • roles (List of String) List of allowed roles.

network_resource

A network resource can be configured with:

  • A fully qualified domain name (FQDN) and ports.
  • An FQDN, resolver IP, and ports.
  • IP's and ports.

Required:

  • name (String) Name of the Network Resource.
  • agent_link (String) Full link to referenced Agent.

Optional:

  • fqdn (String) Fully qualified domain name.

  • resolver_ip (String) Resolver IP.

  • ips (Set of String) List of IP addresses.

  • ports (Set of Number) Ports to expose.

Outputs

The following attributes are exported:

  • cpln_id (String) ID, in GUID format, of the Identity.
  • self_link (String) Full link to this resource. Can be referenced by other resources.

Example Usage

copy
resource "cpln_gvc" "example" {
name = "gvc-example"
description = "Example GVC"
locations = ["aws-us-west-2"]
tags = {
terraform_generated = "true"
example = "true"
}
}
resource "cpln_agent" "example" {
name = "agent-example"
description = "Example Agent"
}
resource "cpln_cloud_account" "example_aws" {
name = "aws-example"
description = "Example AWS Cloud Account"
tags = {
terraform_generated = "true"
example = "true"
}
aws {
role_arn = "arn:aws:iam::1234:role/example_role"
}
}
resource "cpln_cloud_account" "example_azure" {
name = "azure-example"
description = "Example Azure Cloud Account"
tags = {
terraform_generated = "true"
example = "true"
}
azure {
// Use the full link to the Azure secret
secret_link = "/org/ORG_NAME/secret/AZURE_SECRET"
}
}
resource "cpln_cloud_account" "example-gcp" {
name = "gcp-example"
description = "Example GCP Cloud Account"
tags = {
terraform_generated = "true"
example = "true"
}
gcp {
project_id = "cpln_gcp_project_1234"
}
}
resource "cpln_identity" "example" {
gvc = cpln_gvc.example.name
name = "identity-example"
description = "Example Identity"
tags = {
terraform_generated = "true"
example = "true"
}
# Network Resource with FQDN
network_resource {
name = "test-network-resource-fqdn"
agent_link = cpln_agent.example.self_link
fqdn = "domain.example.com"
ports = [1234, 5432]
}
# Network Resource with FQDN and Resolver IP
network_resource {
name = "test-network-resource-fqdn-rip"
agent_link = cpln_agent.example.self_link
fqdn = "domain2.example.com"
resolver_ip = "192.168.1.1"
ports = [12345, 54321]
}
# Network Resource with IP
network_resource {
name = "test-network-resource-ip"
agent_link = cpln_agent.test_agent.self_link
ips = ["192.168.1.1", "192.168.1.250"]
ports = [3099, 7890]
}
aws_access_policy {
cloud_account_link = cpln_cloud_account.example_aws.self_link
# The AWS access policy can either contain an existing role_name or multiple policy_refs
// role_name = "rds-monitoring-role"
policy_refs = ["aws::/job-function/SupportUser", "aws::AWSSupportAccess"]
}
azure_access_policy {
cloud_account_link = cpln_cloud_account.example_azure.self_link
role_assignment {
scope = "/subscriptions/d0d1e522-0825-415a-8b07-f7759b5c8a7e/resourceGroups/CP-Test-Resource-Group"
roles = ["AcrPull", "AcrPush"]
}
role_assignment {
scope = "/subscriptions/d0d1e522-0825-415a-8b07-f7759b5c8a7e/resourceGroups/CP-Test-Resource-Group/providers/Microsoft.Storage/storageAccounts/cplntest"
roles = ["Support Request Contributor"]
}
}
gcp_access_policy {
cloud_account_link = cpln_cloud_account.example_gcp.self_link
scopes = ["https://www.googleapis.com/auth/cloud-platform"]
# The GCP access policy can either contain an existing service_account or multiple bindings
// service_account = "cpln-tf@cpln-test.iam.gserviceaccount.com"
binding {
resource = "//cloudresourcemanager.googleapis.com/projects/cpln-test"
roles = ["roles/appengine.appViewer", "roles/actions.Viewer"]
}
binding {
resource = "//iam.googleapis.com/projects/cpln-test/serviceAccounts/cpln-tf@cpln-test.iam.gserviceaccount.com"
roles = ["roles/editor", "roles/iam.serviceAccountUser"]
}
}
}

cpln_policy

Manages an org's Policy.

Declaration

Required

  • name (String) Name of the Policy.

Optional

  • description (String) Description of the Policy.

  • tags (Map of String) Key-value map of resource tags.

  • target_kind (String) The kind of resource to target (e.g., gvc, serviceaccount, etc.).

  • target (String) Set this value of this attribute to all if this policy should target all objects of the given target_kind. Otherwise, do not include the attribute.

  • target_links (List of String) List of the targets this policy will be applied to. Not used if target is set to all.

  • target_query (Block List, Max: 1) (see below).

  • binding (Block Set, Max: 50) (see below).

binding

Optional:

  • permissions (Set of String) List of permissions to allow.
  • principal_links (Set of String) List of the principals this binding will be applied to. Principal links format: group/GROUP_NAME, user/USER_EMAIL, identity/IDENTITY_NAME, serviceaccount/SERVICE_ACCOUNT_NAME.

target_query

Optional:

  • fetch (String) Type of fetch. Either: links or items. Default: items.
  • spec (Block List, Max: 1) (see below).

target_query.spec

Optional:

  • match (String) Type of match. Available values: all, any, none. Default: all.
  • terms (Block List) (see below).

target_query.spec.terms

Terms can only contain one of the following attributes: property, tag.

Optional:

  • op (String) Type of query operation. Available values: =, >, >=, <, <=, !=, exists, !exists. Default: =.

  • property (String) Property to use for query evaluation.

  • tag (String) Tag key to use for query evaluation.

  • value (String) Testing value for query evaluation.

Outputs

The following attributes are exported:

  • cpln_id (String) ID, in GUID format, of the Policy.
  • origin (String) Origin of the Policy. Either builtin or default.
  • self_link (String) Full link to this resource. Can be referenced by other resources.

Example Usage

copy
resource "cpln_service_account" "example" {
name = "service-account-example"
description = "Example Service Account"
tags = {
terraform_generated = "true"
example = "true"
}
}
resource "cpln_policy" "example" {
name = "policy-example"
description = "Example Policy"
tags = {
terraform_generated = "true"
example = "true"
}
target_kind = "serviceaccount"
# Policy can either target `all` or specific target links
// target = "all"
target_links = [cpln_service_account.example.name]
target_query {
spec {
# match is either "all", "any", or "none"
match = "all"
terms {
op = "="
tag = "firebase/sign_in_provider"
value = "microsoft.com"
}
}
}
binding {
# Available permissions are based on the target kind
permissions = ["manage", "edit"]
# Principal links format: `group/GROUP_NAME`, `user/USER_EMAIL`, `identity/IDENTITY_NAME`, `serviceaccount/SERVICE_ACCOUNT_NAME`
principal_links = ["user/email@example.com", "group/viewers"]
}
}

cpln_secret

Manage an org's Secrets.

Use caution when using sensitive values within an HCL script. Best practices should be followed (i.e., do not hard code sensitive values).

Terraform state can contain sensitive data. Please review Terraform's recommendations on how to handle sensitive data.

Declaration

Required

  • name (String) Name of the secret.

Optional

  • description (String) Description of the Secret.
  • tags (Map of String) Key-value map of resource tags.

Note: Only one of the secrets listed below can be included in a resource. Create resources for each additional secret.

aws

Optional:

  • access_key (String, Sensitive) Access Key provided by AWS.
  • role_arn (String) Role ARN provided by AWS.
  • secret_key (String, Sensitive) Secret Key provided by AWS.

azure_connector

Optional:

  • code (String, Sensitive) Code/Key to authenticate to deployment URL.
  • url (String, Sensitive) Deployment URL.

ecr

Reference Page

Optional:

  • access_key (String) Access Key provided by AWS.
  • repos (Set of String) List of ECR repositories.
  • role_arn (String) Role ARN provided by AWS.
  • secret_key (String, Sensitive) Secret Key provided by AWS.

keypair

Optional:

  • passphrase (String, Sensitive) Passphrase for private key.
  • public_key (String) Public Key.
  • secret_key (String, Sensitive) Secret/Private Key.

opaque

Optional:

  • encoding (String) Available encodings: plain, base64. Default: plain.
  • payload (String, Sensitive) Plain text or base64 encoded string. Use encoding attribute to specify encoding.

tls

Optional:

  • cert (String) Public Certificate.
  • chain (String) Chain Certificate.
  • key (String, Sensitive) Private Certificate.

userpass

Optional:

  • encoding (String) Available encodings: plain, base64. Default: plain.
  • password (String, Sensitive) Password.
  • username (String) Username.

Outputs

The following attributes are exported:

  • cpln_id (String) ID, in GUID format, of the Secret.
  • self_link (String) Full link to this resource. Can be referenced by other resources.
  • tags (Map of String) Key-value map of resource tags. Includes any server generated tags.

Example Usage

copy
variable "random" {
type = string
default = "secret-example"
}
# Sample Public Certificate
variable "testcert" {
type = string
default = <<EOT
-----BEGIN CERTIFICATE-----
MIID+zCCAuOgAwIBAgIUEwBv3WQkP7dIiEIxyj+Wi1STz7QwDQYJKoZIhvcNAQEL
BQAwgYwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRQwEgYDVQQH
DAtMb3MgQW5nZWxlczENMAsGA1UECgwEQ1BMTjERMA8GA1UECwwIQ1BMTi1PUkcx
EDAOBgNVBAMMB2NwbG4uaW8xHjAcBgkqhkiG9w0BCQEWD3N1cHBvcnRAY3Bsbi5p
bzAeFw0yMDEwMTQxNzI4MDhaFw0zMDEwMTIxNzI4MDhaMIGMMQswCQYDVQQGEwJV
UzETMBEGA1UECAwKQ2FsaWZvcm5pYTEUMBIGA1UEBwwLTG9zIEFuZ2VsZXMxDTAL
BgNVBAoMBENQTE4xETAPBgNVBAsMCENQTE4tT1JHMRAwDgYDVQQDDAdjcGxuLmlv
MR4wHAYJKoZIhvcNAQkBFg9zdXBwb3J0QGNwbG4uaW8wggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQDBzN2jRf9ouoF4XG0eUxcc4f1sP8vhW1fQXjun3cl0
RsN4jRdOyTKWcls1yAxlOkwFod8d6HND9OvNrsl7U4iJIEcJL6vTqHY7jTGXQkd9
yPONMpMXYE8Dsiqtk0deoOab7fafYcvq1iWnpvg157mJ/u9qdyU+1h8DncES30Fk
PsG8TsIsjx94JkTJeMmEJxtws4dfuoCk88INbBHLjxBQgwTu0vgMxN34b5z+esHr
aetDN2fqxSoTOeIlyFzeS+kwG3GK4I1hUQBiL2TeDrnEY6qP/ZoGuyyVnsT/6pHY
/BTAcH3Rgeqose7mqBT+7zlxDfHYHceuNB/ljq0e1j69AgMBAAGjUzBRMB0GA1Ud
DgQWBBRxncC/8RRio/S9Ly8tKFS7WnTcNTAfBgNVHSMEGDAWgBRxncC/8RRio/S9
Ly8tKFS7WnTcNTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAr
sDZQj4K47fW6JkJbxlzZ1hd7IX6cQhI/DRIdTGR1u0kM1RtZoS0UtV5qsYV/g/S4
ChuB/aIARyTWvHKDhcT3bRGHLnoZJ8pLlQh4nEfO07SRhyeNiO4qmWM9az0nP5qD
wAXpLpmYIairzAgY7QXbk5wXbTrXli3mz14VaNoqN4s7iyLtHn5TGAXc12aMwo7M
5yn/RGxoWQoJqSQKc9nf909cR81AVCdG1dFcp7u8Ud1pTtlmiU9ZJ/YOXDCT/1hZ
YxoeotDBBOIao3Ym/3351somMoQ7Lz6hRWvG0WhDIsCXvth4XSxRkZFXgjWNuhdD
u2ZCis/EwXsqRJPkIPnL
-----END CERTIFICATE-----
EOT
}
# Sample Private Certificate
variable "testcertprivate" {
type = string
default = <<EOT
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDBzN2jRf9ouoF4
XG0eUxcc4f1sP8vhW1fQXjun3cl0RsN4jRdOyTKWcls1yAxlOkwFod8d6HND9OvN
rsl7U4iJIEcJL6vTqHY7jTGXQkd9yPONMpMXYE8Dsiqtk0deoOab7fafYcvq1iWn
pvg157mJ/u9qdyU+1h8DncES30FkPsG8TsIsjx94JkTJeMmEJxtws4dfuoCk88IN
bBHLjxBQgwTu0vgMxN34b5z+esHraetDN2fqxSoTOeIlyFzeS+kwG3GK4I1hUQBi
L2TeDrnEY6qP/ZoGuyyVnsT/6pHY/BTAcH3Rgeqose7mqBT+7zlxDfHYHceuNB/l
jq0e1j69AgMBAAECggEAPGhrPZV4A2D/MlE9AhLMRYh7wd4w4tHiEWUOG0kank/g
Zhc0iK5WQmbq31y34GXHhInsThpCs5AIYFh3HSXwjS2udsKRQKxmDjH4nzldp2uX
3w9Aoiy29GP4wZoCyRBGUZxfH1cQhOazXgrBm6vbPZRldD4nMer0R+BIamWEsIYD
YjDj1pT0noLUSeqoLmGxSQ4DNIBQVZB/T8ziMcEzl6bhprT0QrapJSyD2CtA8tH1
Z8cyhmyE0CUvSkV4K2ecvVukWBJvrAYc6euPAnkS5LJrQotI5+3jJO2QawOlL6Uw
rFWBpgBrCgbzquMRpDCQ/J9/GDYaZjim4YdonboBgQKBgQD7jx3CVnG4LDz198am
spmPwKCW1ke6PhlG7zf3YR00xg9vPBYiy4obb1Jg6em1wr+iZ0dEt8fimeZXewBf
LzlrR8T1Or0eLzfbn+GlLIKGKhn2pKB/i1iolkfIonchqXRk9WNx+PzjgUqiYWRC
/1tH2BsODlVrzKL2lnbWKNIFdQKBgQDFOLedpMeYemLhrsU1TXGt1xTxAbWvOCyt
vig/huyz4SQENXyu3ImPzxIxpTHxKhUaXo/qFXn0jhqnf0LfWI4nbQUbkivb5BPr
KY9aj7XwwsY4MXW5C12Qi0lIwHOWCmfzvyS7TCMqnQb7sT4Mjmm4ydEbiI1TjlFJ
D/RFxzcDKQKBgQCehPcJyZNrrWTU0sh5rz4ZWhdYNbuJXyxqiMBJwQa4hL6hJ8oD
LyPeWe4daAmAIjLEUjSU1wK8hqKiKb54PLgAJH+20MbvyG14lm2Iul2d0dX+mIsT
FGpQAjNF+Sr9KV1RaVi7L12ct5KidKDLn0KUKVgTKXEmtxNSNEq6dYqzKQKBgDI8
zljzvnwSwNloIYgAYDK+FPGHU/Z8QrVHOQ1lmyn+8aO41DfeqZPeVW4b/GrII3QC
HnqsWdJ32EZOXoRyFFPqq2BojY+Hu6MthPy2msvncYKi5q/qOz00nchQbaEMqYon
aH3lWRfjxAGdFocwR7HwhrmSwR1FpWMNE1Yq9tJxAoGBANc0nZSy5ZlTiMWdRrTt
gFc9N/jz8OL6qLrJtX2Axyv7Vv8H/gbDg4olLR+Io38M0S1WwEHsaIJLIvJ6msjl
/LlseAW6oiO6jzhWEr0VQSLkuJn45hG/uy7t19SDuNR7W5NuEr0YbWd6fZEpR7RR
S1hFKnRRcrVqA+HjWnZ//BGi
-----END PRIVATE KEY-----
EOT
}
# Sample Private Key
variable "test-secret-key" {
type = string
default = <<EOT
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,9A26BB15304B18E7
ZdBgMExsvIJEsIFDMQ02xh4nDnhXEGUNu7LiWIZjn9WS6QB2jApyOFOBWmp0lK6L
dIJ+Mb8wMeHtkiKS6ZbYeea8M29kwEejZRnKl1Wq0EFycdwbONtbcbjzF+tQGEBT
gQQgkY7wjDWl8HwjFEA+NUuitzi6uI2xWlQpFdUrmqJAZCbxNFa0aM8nW6jnitvP
616ps3HjLnWCjoyqS4hWxiWmt+VE3KruPnUVVV7bWlzc6jnoZcSaeqeaoQrNKguH
te2iBIMdY/uldb7Ik2Kxr2+kBRmV4YNkp1EelNi/m39VcoUHJLk1jLldzuINhbi2
IRqYZe4EEMSYdb3TkSosXa64Sz7jMBz5AxlA0n78FKlB9G5FAxaXcVYNQIlvzCbw
uXPbQd/UYKUuEI1Yn8OmGBN5xcOdgWz8hfyxA2Hq1tmo1XN6snavGe7TKbZd70N+
1yFbclB2T1z8fPcLwUZUxOl4g2DoMMHIzCSPaIe/otT8389k4H6hEulLis4lW0p3
qopL5kdpxmSGgXsX6q6CUFb/0cw9HskNT3zbzKLx2MzjFCo93IB07UxPwkCD2kb1
sLKMcpTC8a0vLaTVNYgDX7wW/YjBrCokaqk0z1whuN6iSReOtvmu5ybrq1Ksg8UQ
yvCSScM/+muKi+gbEOskQs4Ph3ZLHqAX3/XYoyBcFnPNxVHTIa5Dcju6h5gl1/uY
6tkRsHDr0Lzy8pd6jjf/ApPf9ypCuxKUO1q8PzPg2E4bmEFxc8zOB2NLvfPgFrUR
0Sbkapv/6x6nNRw75cu69c5we/atip6wst8J1MSU0fTqb6bZ3TF2pDyNEOkdkvoZ
YZ0r3hUytdT0pImoDLKoyy17mtHLLApzHyIgmR3cqtSt07ncmC5lyEBcZBrQXMa8
aZeOr8iUWQE/q+4BvoxeKsOD6ttKuFnrgl0rmMnYQsSyLJOPizrU4L1d1HMIKswm
iW+Rg7xlWmQg95m8XEWTjAb3tuNz/tGXC7Qa88HvC7YfyG69yM61oPsT83YnxcBT
C/X67lSFTYguFa3HgDZpjGq7Hc/Q7nhaoqNMEs01O6jbcmrue8IIa2FH1tTwPN0W
D7JefjCQjEghue2mjc0fovOGe9A9jvWf+gJHF3vRtFa67uQiQxge9zUzpHyVNpOj
Ve0y0HvibNTd6TSCArctJpIcwpjO3MTT5LBJ1p/8v4b4+knEKD2c69jumNbKGbWr
Wjq39M/MGNUO5SbZMO3gFCt6fgtXkOktH9pJ9iOQpYKgl7QTe2qQygfWkIm0EZRN
6EaQdNNKgENWicpKyKQ4BxoY1LYAHFHJ95VisLf3KmmOF5MwajADZQT/yth3gvht
xx21b9iudcgq/CRccSvfIPIWZKi6oaqNIXK+E3DQd40TUopLsBWzacTZn9maSZtW
RyAY1TkRn1qDR2soyhBcihrX5PZ83jnOlM3XTdfF1784g8zB9ooDnK7mUKueH1W3
hWFADMUF7uaBbo5EZ9sE+dFPzWPJLhu2j67a1iHmByqEvFY64lzq7VwwU/GE8JdA
85oEkhg1ZEPJp3OYTQfPI/CC/2fc93Exf6wmaXuss8AHehuGcKQniOZmFOKOBprv
-----END RSA PRIVATE KEY-----
EOT
}
# Sample Public Key
variable "test-public-key" {
type = string
default = <<EOT
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwrVyExI0uvRmwCAKFHiv
baAcPMcKJDa6f6TtaVo2p8jyfEhVwDTmR3FUrDDZAjh0Q8G/Up8Ob3+IJafNymCO
BhUKou+8ie7guqsbU9JrT0Zos1k/pd0aVfnAR0EpW3es/7fdkWUszU0uweeEj22m
XMlLplnqqoYOGAhuNMqGsZwBr36Bxq9EeB2O79QsAFDNkPVg7xIaYKn32j69o0Zr
ryYI8xqOYYy5Dw6CX+++YYLYiR/PkLYJTVAsxXeqyltCfb3Iv7vN5HrfoYBhndr3
NxBPkcIJZeh3Z+QzfJ5U+bB5fP/aOsEk5bPbtLzylj2KnOOM/ZxXJtOcu0xtJLd3
XwIDAQAB
-----END PUBLIC KEY-----
EOT
}
# AWS Secret
resource "cpln_secret" "aws" {
name = "aws-${var.random}"
description = "aws description ${var.random}"
tags = {
terraform_generated = "true"
example = "true"
secret_type = "aws"
}
aws {
# Required
secret_key = "AKIAIOSFODNN7EXAMPLE"
# Required
access_key = "AKIAwJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
# Optional
role_arn = "arn:awskey"
}
}
# Azure SDK Secret
resource "cpln_secret" "azure_sdk" {
name = "azuresdk-${var.random}"
description = "azuresdk description ${var.random}"
tags = {
terraform_generated = "true"
example = "true"
secret_type = "azure-sdk"
}
# Required
azure_sdk = "{\"subscriptionId\":\"2cd8674e-4f89-4a1f-b420-7a1361b46ef7\",\"tenantId\":\"292f5674-c8b0-488b-9ff8-6d30d77f38d9\",\"clientId\":\"649846ce-d862-49d5-a5eb-7d5aad90f54e\",\"clientSecret\":\"cpln\"}"
}
# Azure Connector Secret
resource "cpln_secret" "azure_connector" {
name = "azureconnector-${var.random}"
description = "azureconnector description ${var.random}"
tags = {
terraform_generated = "true"
acceptance_test = "true"
secret_type = "azure-connector"
}
azure_connector {
# Required
url = "https://example.azurewebsites.net/api/iam-broker"
# Required
code = "iH0wQjWdAai3oE1C7XrC3t1BBaD7N7foapAylbMaR7HXOmGNYzM3QA=="
}
}
# Docker Secret
resource "cpln_secret" "docker" {
name = "docker-${var.random}"
description = "docker description ${var.random}"
tags = {
terraform_generated = "true"
example = "true"
secret_type = "docker"
}
# Required
docker = "{\"auths\":{\"your-registry-server\":{\"username\":\"your-name\",\"password\":\"your-pword\",\"email\":\"your-email\",\"auth\":\"<Secret>\"}}}"
}
# Amazon ECR Secret
resource "cpln_secret" "ecr" {
name = "ecr-${var.random}"
description = "ecr description ${var.random}"
tags = {
terraform_generated = "true"
example = "true"
secret_type = "ecr"
}
ecr {
# Required
secret_key = "AKIAIOSFODNN7EXAMPLE"
# Required
access_key = "AKIAwJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
# Optional
role_arn = "arn:awskey"
# Required
repos = ["915716931765.dkr.ecr.us-west-2.amazonaws.com/env-test", "015716931765.dkr.ecr.us-west-2.amazonaws.com/cpln-test"]
}
}
# Dictionary Secret
resource "cpln_secret" "dictionary" {
name = "dictionary-${var.random}"
description = "dictionary description ${var.random}"
tags = {
terraform_generated = "true"
example = "true"
secret_type = "dictionary"
}
dictionary = {
key01 = "value-01"
key02 = "value-02"
}
}
# GCP Secret
resource "cpln_secret" "gcp" {
name = "gcp-${var.random}"
description = "gcp description ${var.random}"
tags = {
terraform_generated = "true"
example = "true"
secret_type = "gcp"
}
# Required
gcp = "{\"type\":\"gcp\",\"project_id\":\"cpln12345\",\"private_key_id\":\"pvt_key\",\"private_key\":\"key\",\"client_email\":\"support@cpln.io\",\"client_id\":\"12744\",\"auth_uri\":\"cloud.google.com\",\"token_uri\":\"token.cloud.google.com\",\"auth_provider_x509_cert_url\":\"cert.google.com\",\"client_x509_cert_url\":\"cert.google.com\"}"
}
# Keypair Secret
resource "cpln_secret" "keypair" {
name = "keypair-${var.random}"
description = "keypair description ${var.random}"
tags = {
terraform_generated = "true"
example = "true"
secret_type = "keypair"
}
keypair {
# Required
secret_key = var.test-secret-key
# Optional
public_key = var.test-public-key
# Optional
passphrase = "cpln"
}
}
# Opaque Secret
resource "cpln_secret" "opaque" {
name = "opaque-${var.random}"
description = "opaque description ${var.random}"
tags = {
terraform_generated = "true"
example = "true"
secret_type = "opaque"
}
opaque {
# Required
payload = "opaque_secret_payload"
# Optional
# Options: `plain` or `base64`
encoding = "plain"
}
}
# TLS Secret
resource "cpln_secret" "tls" {
name = "tls-${var.random}"
description = "tls description ${var.random}"
tags = {
terraform_generated = "true"
example = "true"
secret_type = "tls"
}
tls {
# Required
key = var.testcertprivate
# Required
cert = var.testcert
# Optional
chain = var.testcert
}
}
# Username/Password Secret
resource "cpln_secret" "userpass" {
name = "userpass-${var.random}"
description = "userpass description ${var.random}"
tags = {
terraform_generated = "true"
example = "true"
secret_type = "userpass"
}
userpass {
# Required
username = "cpln_username"
# Required
password = "cpln_password"
# Optional
encoding = "plain"
}
}

cpln_service_account

Manages an org's Service Accounts.

Declaration

Required

  • name (String) Name of the Service Account.

Optional

  • description (String) Description of the Service Account.
  • tags (Map of String) Key-value map of resource tags.

Outputs

The following attributes are exported:

  • cpln_id (String) ID, in GUID format, of the Secret.
  • origin (String) Origin of the Policy. Either builtin or default.
  • self_link (String) Full link to this resource. Can be referenced by other resources.

Example Usage

copy
resource "cpln_service_account" "example" {
name = "service-account-example"
description = "Example Service Account"
tags = {
terraform_generated = "true"
example = "true"
}
}
resource "cpln_service_account_key" "example" {
service_account_name = cpln_service_account.example.name
description = "Service Account Key"
}
resource "cpln_service_account_key" "example_02" {
// When adding another key, use `depends_on` to add the keys synchronously
depends_on = [cpln_service_account_key.example]
service_account_name = cpln_service_account.example.name
description = "Service Account Key #2"
}
output "key_01" {
value = cpln_service_account_key.example.key
}
output "key_02" {
value = cpln_service_account_key.example_02.key
}

cpln_service_account_key

Manages an org's Service Account Keys.

Used in conjunction with a Service Account.

A key can only be created and deleted. Updates will fail.

Declaration

Required

  • description (String) Description of the Service Account Key.
  • service_account_name (String) The name of an existing Service Account this key will belong to.

Outputs

The following attributes are exported:

  • created (String) The timestamp, in UTC, when the key was created.
  • key (String, Sensitive) The generated key.
  • name (String) The generated name of the key.

Example Usage

copy
resource "cpln_service_account" "example" {
name = "service-account-example"
description = "Example Service Account"
tags = {
terraform_generated = "true"
example = "true"
}
}
resource "cpln_service_account_key" "example" {
service_account_name = cpln_service_account.example.name
description = "Service Account Key"
}
resource "cpln_service_account_key" "example_02" {
// When adding another key, use `depends_on` to add the keys synchronously
depends_on = [cpln_service_account_key.example]
service_account_name = cpln_service_account.example.name
description = "Service Account Key #2"
}
output "key_01" {
value = cpln_service_account_key.example.key
}
output "key_02" {
value = cpln_service_account_key.example_02.key
}

cpln_workload

Manages a GVC's Workload.

Declaration

Required

  • name (String) Name of the Workload.
  • gvc (String) Name of the associated GVC.

Optional

  • description (String) Description of the Workload.

  • container (Block List) (see below).

  • firewall_spec (Block List, Max: 1) (see below).

  • identity_link (String) Full link to an Identity.

  • options (Block List, Max: 1) (see below).

  • local_options (Block List, Max: 1) (see below).

  • tags (Map of String) Key-value map of resource tags.

container

Note: A Workload must contain at least one container.

Required:

  • name (String) Name of the container.

    • The following rules apply to the name of a container:
      • Cannot be: 'istio-proxy', 'queue-proxy', 'istio-validation'.
      • Cannot start with: cpln_.
  • image (String) The full image and tag path.

Optional:

  • port (Number) The port the container exposes. Only one container is allowed to specify a port. Min: 80. Max: 65535.

Note: The ports listed below are blocked and are not allowed to be used. Containers which attempt to use these ports will not be able to bind: 8012, 8022, 9090, 9091, 15000, 15001, 15006, 15020, 15021, 15090, 41000.

  • args (List of String) Command line arguments passed to the container at runtime.

  • env (Map of String) Name-Value list of environment variables.

  • command (String) Override the entry point.

  • cpu (String) Reserved CPU of the workload when capacityAI is disabled. Maximum CPU when CapacityAI is enabled. Default: "50m".

  • memory (String) Reserved memory of the workload when capacityAI is disabled. Maximum memory when CapacityAI is enabled. Default: "128Mi".

  • liveness_probe (Block List, Max: 1) Liveness Probe (see below).

  • readiness_probe (Block List, Max: 1) Readiness Probe (see below).

  • metrics (Block List, Max: 1) (see below) Reference Page.

  • volume (Block List) (see below) Reference Page.

  • working_directory (String) Override the working directory. Must be an absolute path.

container.liveness_probe

Optional:

  • failure_threshold (Number) Failure Threshold. Default: 3. Min: 1. Max: 20.

  • initial_delay_seconds (Number) Initial Delay in seconds. Default: 0. Min: 0. Max: 120.

  • period_seconds (Number) Period Seconds. Default: 10. Min: 1. Max: 60.

  • success_threshold (Number) Success Threshold. Default: 1. Min: 1. Max: 20.

  • timeout_seconds (Number) Timeout in seconds. Default: 1. Min: 1. Max: 60.

  • exec (Block List, Max: 1) (see below).

  • http_get (Block List, Max: 1) (see below).

  • tcp_socket (Block List, Max: 1) (see below).

container.liveness_probe.exec

Required:

  • command (List of Strings, Min: 1) List of commands to execute.

container.liveness_probe.http_get

Optional:

  • http_headers (Map of String) Name-Value list of HTTP Headers to send to container.
  • path (String) Path. Default: "/".
  • port (Number) Port. Min: 80. Max: 65535.
  • scheme (String) HTTP Scheme. Valid values: "HTTP", "HTTPS". Default: "HTTP".

container.liveness_probe.tcp_socket

Optional:

  • port (Number) TCP Socket Port.

container.readiness_probe

Optional:

  • failure_threshold (Number) Failure Threshold. Default: 3. Min: 1. Max: 20.

  • initial_delay_seconds (Number) Initial Delay in seconds. Default: 0. Min: 0. Max: 120.

  • period_seconds (Number) Period Seconds. Default: 10. Min: 1. Max: 60.

  • success_threshold (Number) Success Threshold. Default: 1. Min: 1. Max: 20.

  • timeout_seconds (Number) Timeout in seconds. Default: 1. Min: 1. Max: 60.

  • exec (Block List, Max: 1) (see below).

  • http_get (Block List, Max: 1) (see below).

  • tcp_socket (Block List, Max: 1) (see below).

container.readiness_probe.exec

Required:

  • command (List of Strings, Min: 1) List of commands to execute.

container.readiness_probe.http_get

Optional:

  • http_headers (Map of String) Name-Value list of HTTP Headers to send to container.
  • path (String) Path. Default: "/".
  • port (Number) Port. Min: 80. Max: 65535.
  • scheme (String) HTTP Scheme. Valid values: "HTTP", "HTTPS". Default: "HTTP".

container.readiness_probe.tcp_socket

Optional:

  • port (Number) TCP Socket Port.

container.volume

Required:

  • uri (String) URI of volume at cloud provider.
  • path (String) File path added to workload pointing to the volume.

Note: The following list of paths are reserved and cannot be used: /dev, /dev/log, /tmp, /var, /var/log.

container.metrics

Required:

  • path (String) Path from container emitting custom metrics
  • port (Number) Port from container emitting custom metrics

firewall_spec

Control of inbound and outbound access to the workload for external (public) and internal (service to service) traffic. Access is restricted by default.

Optional:

firewall_spec.external

Optional:

  • inbound_allow_cidr (List of String) he list of ipv4/ipv6 addresses or cidr blocks that are allowed to access this workload. No external access is allowed by default. Specify '0.0.0.0/0' to allow access to the public internet.
  • outbound_allow_cidr (List of String) The list of ipv4/ipv6 addresses or cidr blocks that this workload is allowed reach. No outbound access is allowed by default. Specify '0.0.0.0/0' to allow outbound access to the public internet.
  • outbound_allow_hostname (List of String) The list of public hostnames that this workload is allowed to reach. No outbound access is allowed by default. A wildcard * is allowed on the prefix of the hostname only, ex: *.amazonaws.com. Use outboundAllowCIDR to allow access to all external websites.

firewall_spec.internal

The internal firewall is used to control access between workloads.

Optional:

  • inbound_allow_type (String) Used to control the internal firewall configuration and mutual tls. Allowed Values: "none", "same-gvc", "same-org", "workload-list".

    • 'none': no access is allowed between this workload and other workloads on Control Plane.
    • 'same-gvc': workloads running on the same Global Virtual Cloud are allowed to access this workload internally.
    • 'same-org': workloads running on the same Control Plane Organization are allowed to access this workload internally.
    • 'workload-list': specific workloads provided in the 'inboundAllowWorkload' array are allowed to access this workload internally.
  • inbound_allow_workload (List of String) A list of specific workloads which are allowed to access this workload internally. This list is only used if the 'inboundAllowType' is set to 'workload-list'.

options

Optional:

  • autoscaling (Block List, Max: 1) (see below).

  • capacity_ai (Boolean) Capacity AI. Default: true.

  • debug (Boolean) Debug mode. Default: false

  • spot (Boolean) Spot instance. Default; true.

  • timeout_seconds (Number) Timeout in seconds. Default: 5.

  • location (String) Valid only for local_options. Local options override for a specific location.

options.autoscaling

Optional:

  • metric (String) Valid values: concurrency, cpu, rps. Default: concurrency.
  • max_concurrency (Number) A hard maximum for the number of concurrent requests allowed to a replica. If no replicas are available to fulfill the request then it will be queued until a replica with capacity is available and delivered as soon as one is available again. Capacity can be available from requests completing or when a new replica is available from scale out.Min: 0. Max: 1000. Default 0.
  • max_scale (Number) The maximum allowed number of replicas. Min: 0. Default 5.
  • min_scale (Number) The minimum allowed number of replicas. Control Plane can scale the workload down to 0 when there is no traffic and scale up immediately to fulfill new requests. Min: 0. Max: max_scale. Default 1.
  • scale_to_zero_delay (Number) The amount of time (in seconds) with no requests received before a workload is scaled to 0. Min: 30. Max: 3600. Default: 300.
  • target (Number) Control Plane will scale the number of replicas for this deployment up/down in order to be as close as possible to the target metric across all replicas of a deployment. Min: 0. Max: 20000. Default: 100.

status

Status of the workload.

Read-Only:

  • canonical_endpoint (String) Canonical endpoint for the workload.
  • endpoint (String) Endpoint for the workload.
  • health_check (List of Object) (see below).
  • parent_id (String) ID of the parent object.

status.health_check

Current health status.

Read-Only:

  • active (Boolean) Active boolean for the associated workload.
  • code (Number) Current output code for the associated workload.
  • failures (Number) Failure integer for the associated workload.
  • last_checked (String) Timestamp in UTC of the last health check.
  • message (String) Current health status for the associated workload.
  • success (Boolean) Success boolean for the associated workload.
  • successes (Number) Success integer for the associated workload.

Outputs

The following attributes are exported:

  • cpln_id (String) ID, in GUID format, of the Workload.
  • self_link (String) Full link to this resource. Can be referenced by other resources.
  • status (List of Object) (see below).

Example Usage

copy
resource "cpln_gvc" "example" {
name = "gvc-example"
description = "Example GVC"
locations = ["aws-eu-central-1", "aws-us-west-2"]
tags = {
terraform_generated = "true"
example = "true"
}
}
resource "cpln_identity" "example" {
gvc = cpln_gvc.example.name
name = "identity-example"
description = "Example Identity"
tags = {
terraform_generated = "true"
example = "true"
}
}
resource "cpln_workload" "new" {
gvc = cpln_gvc.example.name
name = "workload-example"
description = "Example Workload"
tags = {
terraform_generated = "true"
example = "true"
}
identity_link = cpln_identity.example.self_link
container {
name = "container-01"
image = "gcr.io/knative-samples/helloworld-go"
port = 8080
memory = "128Mi"
cpu = "50m"
command = "override-command"
working_directory = "/usr"
env = {
env-name-01 = "env-value-01",
env-name-02 = "env-value-02",
}
args = ["arg-01", "arg-02"]
readiness_probe {
tcp_socket {
port = 8181
}
period_seconds = 11
timeout_seconds = 2
failure_threshold = 4
success_threshold = 2
initial_delay_seconds = 1
}
liveness_probe {
http_get {
path = "/path"
port = 8282
scheme = "HTTPS"
http_headers = {
header-name-01 = "header-value-01"
header-name-02 = "header-value-02"
}
}
period_seconds = 10
timeout_seconds = 3
failure_threshold = 5
success_threshold = 1
initial_delay_seconds = 2
}
volume {
uri = "s3://bucket"
path = "/s3"
}
}
options {
capacity_ai = false
spot = true
timeout_seconds = 30
autoscaling {
metric = "concurrency"
target = 100
max_scale = 3
min_scale = 2
max_concurrency = 500
}
}
local_options {
location = "aws-us-west-2"
capacity_ai = false
spot = true
timeout_seconds = 30
autoscaling {
metric = "concurrency"
target = 100
max_scale = 3
min_scale = 2
max_concurrency = 500
}
}
firewall_spec {
external {
inbound_allow_cidr = ["0.0.0.0/0"]
outbound_allow_cidr = []
outbound_allow_hostname = ["*.controlplane.com", "*.cpln.io"]
}
internal {
# Allowed Types: "none", "same-gvc", "same-org", "workload-list"
inbound_allow_type = "none"
inbound_allow_workload = []
}
}
}
Copyright © 2021 Control Plane Corporation. All rights reserved. Revision 30221ec6
Contents