AWS Secrets Manager Setup

📘

Prerequisites

  1. An environment.tf file generated by symflow init
    a. If you have not run symflow init, please follow the instructions in Installing Sym
  2. A runtime_connector module defined in connectors.tf
    a. If you do not have a connectors.tf, please follow the instructions in AWS Runtime Setup

Grant Sym Read-Only Access to AWS Secrets Manager

🚧

You can generate this

If you ran symflow generate, you might already be configured with a secrets.tf file! If so, then you do not need to complete these steps.

In the directory that contains your Sym configuration (i.e. the directory created by symflow init), create a new file named secrets.tf with the following contents:


# This secrets_manager_access module defines an AWS IAM Policy and attachment that grants the Sym Runtime Role
# the permissions to read secrets from AWS Secrets Manager that are under the /sym/ path and tagged with
# `SymEnv = local.environment_name`.
module "secrets_manager_access" {
  source  = "symopsio/secretsmgr-addon/aws"
  version = "~> 1.1"

  environment   = local.environment_name
  iam_role_name = module.runtime_connector.sym_runtime_connector_role.name
}

# This resource tells Sym how to access your AWS account's Secrets Manager instance.
resource "sym_secrets" "this" {
  type = "aws_secrets_manager"
  name = "${local.environment_name}-sym-secrets"

  settings = {
    # This tells Sym to use the runtime_context integration defined in runtime.tf to access
    # your AWS account's Secrets Manager.
    context_id = sym_integration.runtime_context.id
  }
}

Finally, run terraform init && terraform apply to save your configuration.

For more information about the inputs and outputs of the secrets_manager_access module, see the Terraform registry.

Create an AWS Secrets Manager Secret

The aws_secretsmanager_secret resource is a Terraform resource that manages AWS Secrets Manager secret metadata.

Note: This only declares the secret, but does not populate its value.

resource "aws_secretsmanager_secret" "my_secret" {
  name        = "sym/main/my-secret"
  description = "A secret needed for interacting with an external service"

  tags = {
    # This SymEnv tag is required and MUST match the SymEnv tag in the 
    # aws_iam_policy.secrets_manager_access in your `secrets.tf` file
    SymEnv = local.environment_name
  }
}

Populate the secret value

You can populate the secret in two ways:

  • A plain value
  • A JSON blob

A JSON blob is useful if your values are closely related, such as an Aptible bot username and password. In general, you will want to use the plain value.

Using the AWS CLI

You can use the AWS CLI put-secret-value command to populate the value

Plain value

# The secret-id must match the `name` parameter of the `aws_secretsmanager_secret` resource
aws secretsmanager put-secret-value --secret-id "sym/main/my-secret" --secret-string "YOUR-SECRET-VALUE"

JSON blob

# The secret-id must match the `name` parameter of the `aws_secretsmanager_secret` resource
# Make sure the JSON is a valid JSON string
aws secretsmanager put-secret-value --secret-id "sym/main/my-secret"  --secret-string '{"username":"[email protected]", "password": "EXAMPLE-PASSWORD"}'

Using the AWS console

Alternatively, this can be done in a browser by visiting the AWS console. Find the secret in AWS Secrets Manager, and update the value manually. See AWS's documentation: Modify a Secret.

Share the Secret with the Sym Runtime

The sym_secret resource tells Sym how to find a specific secret by providing the source (AWS Secrets Manager) and the name of the secret, so that Sym knows where to look and what to look for.

The configuration will vary depending on if you populated your AWS Secrets Manager Secret with a plain value or with a JSON blob.

Plain value

In this case, the Sym Runtime will use the value in your AWS Secrets Manager Secret directly.

resource "sym_secret" "my_api_key" {
  # The source of your secrets and the permissions needed to access
  # i.e. AWS Secrets Manager, access with IAM Role.
  # This resource was defined in "Manage Secrets with AWS Secrets Manager"
  source_id = sym_secrets.this.id

  # Name of the key in AWS Secrets Manager
  path = aws_secretsmanager_secret.my_secret.name
}

JSON blob

In this case, the Sym Runtime will parse the value in your AWS Secrets Manager Secret as JSON and attempt to extract the value defined by the json_key setting.

For example, if your secret was populated with the following:

{
  "username": "[email protected]",
  "password": "EXAMPLE-PASSWORD"
}

You can extract the values as follows:

resource "sym_secret" "bot_username" {
  # The source of your secrets and the permissions needed to access
  # i.e. AWS Secrets Manager, access with IAM Role.
  # This resource was defined in "Manage Secrets with AWS Secrets Manager"
  source_id = sym_secrets.this.id

  # Name of the key in AWS Secrets Manager
  path = aws_secretsmanager_secret.my_secret.name

  settings = {
    json_key = "username"
  }
}

resource "sym_secret" "bot_password" {
  # The source of your secrets and the permissions needed to access
  # i.e. AWS Secrets Manager, access with IAM Role.
  # This resource was defined in "Manage Secrets with AWS Secrets Manager"
  source_id = sym_secrets.this.id

  # Name of the key in AWS Secrets Manager
  path = aws_secretsmanager_secret.my_secret.name

  settings = {
    json_key = "password"
  }
}

Full Configuration Example

############ Plain Value Secret Setup ##############

# An AWS Secrets Manager Secret to hold your API Key. Set the value with:
# aws secretsmanager put-secret-value --secret-id "sym/main/my-api-key" --secret-string "YOUR-API-KEY"
resource "aws_secretsmanager_secret" "my_api_key" {
  name        = "sym/main/my-api-key"
  description = "API Key for Sym to interact with external services"

  tags = {
    # This SymEnv tag is required and MUST match the `environment` in your `runtime.tf` file.
    # because the aws/secretsmgr only grants access to secrets tagged with a matching SymEnv value
    SymEnv = "main"
  }
}

# This resource tells Sym how to access your Secret
resource "sym_secret" "my_api_key" {
  # The source of your secrets and the permissions needed to access
  # i.e. AWS Secrets Manager, access with IAM Role.
  source_id = sym_secrets.this.id

  # Name of the key in AWS Secrets Manager
  path = aws_secretsmanager_secret.my_api_key.name
}

############ JSON Value Secret Setup ##############

# An AWS Secrets Manager Secret to hold your credentials. Set the value with:
# aws secretsmanager put-secret-value --secret-id "sym/main/my-credentials" --secret-string '{"username": "foo", "password": "bar"}'
resource "aws_secretsmanager_secret" "my_credentials" {
  name        = "sym/main/my-credentials"
  description = "JSON Credentials for Sym to interact with external services"

  tags = {
    # This SymEnv tag is required and MUST match the SymEnv tag in the 
    # aws_iam_policy.secrets_manager_access in your `secrets.tf` file
    SymEnv = "main"
  }
}

resource "sym_secret" "bot_username" {
  # The source of your secrets and the permissions needed to access
  # i.e. AWS Secrets Manager, access with IAM Role.
  # This resource was defined in "Manage Secrets with AWS Secrets Manager"
  source_id = sym_secrets.this.id

  # Name of the key in AWS Secrets Manager
  path = aws_secretsmanager_secret.my_secret.name

  settings = {
    json_key = "username"
  }
}

resource "sym_secret" "bot_password" {
  # The source of your secrets and the permissions needed to access
  # i.e. AWS Secrets Manager, access with IAM Role.
  # This resource was defined in "Manage Secrets with AWS Secrets Manager"
  source_id = sym_secrets.this.id

  # Name of the key in AWS Secrets Manager
  path = aws_secretsmanager_secret.my_secret.name

  settings = {
    json_key = "password"
  }
}

These secrets can now be used in Sym Integrations to enable Sym Strategies and SDK methods.

Configuring sym_integration Resources

With your sym_secret resources, you can now configure the specific Integration that you require for your Flow and impl.py.