April 4, 2022
Let’s Get Started with Terraform for Astra DB

mkdir hello_astra_tf
cd hello_astra_tf
terraform {
required_version = ">= 1.0.0"
required_providers {
astra = {
source = "datastax/astra"
version = ">=1.0.0"
}
}
}
terraform init
jeffdavies@jdavies-rmbp16 hello_astra % terraform init
Initializing the backend...
Initializing provider plugins...
- Finding datastax/astra versions matching "1.0.10"...
- Installing datastax/astra v1.0.10...
- Installed datastax/astra v1.0.10 (signed by a HashiCorp partner, key ID …)
export ASTRA_API_TOKEN=AstraCS:plusawholebuncofothercharacters
export ASTRA_ORGANIZATION_ID=<YOUR ORG ID>
variable "token" {}
variable "organization_id" {}
locals {
keyspace = "helloastra"
}
# Create the database
resource "astra_database" "hello_astra_db" {
name = "hello_astra"
keyspace = local.keyspace
cloud_provider = "gcp"
region = "us-west1"
}
terraform plan -var="token=$ASTRA_API_TOKEN" \
-var="organization_id=$ASTRA_ORGANIZATION_ID" -out helloastra
terraform apply helloastra
jeffdavies@jdavies-rmbp16 hello_astra_tf % terraform apply helloastra
astra_database.hello_astra_db: Creating...
astra_database.hello_astra_db: Still creating... [10s elapsed]
astra_database.hello_astra_db: Still creating... [20s elapsed]
astra_database.hello_astra_db: Still creating... [30s elapsed]
astra_database.hello_astra_db: Still creating... [40s elapsed]
astra_database.hello_astra_db: Still creating... [50s elapsed]
astra_database.hello_astra_db: Still creating... [1m0s elapsed]
astra_database.hello_astra_db: Still creating... [1m10s elapsed]
astra_database.hello_astra_db: Still creating... [1m20s elapsed]
astra_database.hello_astra_db: Still creating... [1m30s elapsed]
astra_database.hello_astra_db: Creation complete after 1m39s [id=e57617d3-46cb-4243-a3e4-8b6e7e33c082]
resource "astra_role" "hello_admin" {
role_name = "hello_admin"
description = "Database administrator for the hello_astra database"
effect = "allow"
# Select the resources for which we will create policies
resources = [
# Identify our organization
"drn:astra:org:${var.organization_id}",
# Select the database we want to use
"drn:astra:org:${var.organization_id}:db:${astra_database.hello_astra_db.id}",
# Specify the keyspace to which we need access
"drn:astra:org:${var.organization_id}:db:${astra_database.hello_astra_db.id}:keyspace:${local.keyspace}",
# Select all of the tables in the database/keyspace
"drn:astra:org:${var.organization_id}:db:${astra_database.hello_astra_db.id}:keyspace:${local.keyspace}:table:*"
]
policy = [
# Organization level policies
# "org-audits-read", "org-billing-read", "org-billing-write",
# "org-external-auth-read", "org-external-auth-write",
# "org-notification-write", "org-read", "org-role-delete",
# "org-role-read", "org-role-write", "org-token-read",
# "org-token-write", "org-user-read", "org-user-write",
# "org-write", "accesslist-read", "accesslist-write",
# Database level policies
"db-cql", "db-graphql", "db-rest",
# "org-db-addpeering", "db-manage-privateendpoint",
# "org-db-create", "org-db-expand", "org-db-managemigratorproxy",
# "org-db-passwordreset", "org-db-suspend", "org-db-terminate",
# "org-db-view", "db-manage-region",
# Keyspace
"db-keyspace-alter", "db-keyspace-authorize", "db-keyspace-create",
"db-keyspace-describe", "db-keyspace-drop", "db-keyspace-grant",
"db-keyspace-modify", "db-all-keyspace-create",
"db-all-keyspace-describe",
# Table Access
"db-table-alter", "db-table-authorize", "db-table-create",
"db-table-describe", "db-table-drop", "db-table-grant",
"db-table-modify", "db-table-select",
]
resources = [
# Identify our organization
"drn:astra:org:${var.organization_id}",
# Select the database we want to use
"drn:astra:org:${var.organization_id}:db:${astra_database.hello_astra_db.id}",
# Specify the keyspace to which we need access
"drn:astra:org:${var.organization_id}:db:${astra_database.hello_astra_db.id}:keyspace:${local.keyspace}",
# Select all of the tables in the database/keyspace
"drn:astra:org:${var.organization_id}:db:${astra_database.hello_astra_db.id}:keyspace:${local.keyspace}:table:*"
]
# Create a security token for our hello_admin role
resource "astra_token" "api_token" {
roles = [astra_role.hello_admin.role_id]
}
# Allow any IP to access the database. In practice, you should
# lock this down so only the Google Functions IP address can hit
# the database. However, this is not always practical as the
# Google functions IP addresses are ephemeral (as are many types
# of IP addresses by many different sources).
# Even with the IP whitelisting you still need your Astra security
# token. This is just an extra layer of security.
resource "astra_access_list" "website" {
database_id = astra_database.hello_astra_db.id
addresses {
# Allow any IP to connect
request {
address = "0.0.0.0/0"
enabled = true
}
}
}
# Output the security information
output "organization_id" {
value = var.organization_id
description = "The organization ID"
}
output "database_id" {
value = astra_database.hello_astra_db.id
description = "Test Description"
}
output "token" {
value = astra_token.api_token.token
description = "Token information - DO NOT LOSE"
}
output "client_secret" {
value = astra_token.api_token.secret
description = "Token information - DO NOT LOSE"
}
output "client_id" {
value = astra_token.api_token.client_id
description = "Token information - DO NOT LOSE"
}
output "cqlsh_url" {
value = astra_database.hello_astra_db.cqlsh_url
description = "CQL Shell URL"
}
output "graphql_url" {
value = astra_database.hello_astra_db.graphql_url
description = "GraphQL URL"
}
output "data_endpoint_url" {
value = astra_database.hello_astra_db.data_endpoint_url
description = "Data Endpoint URL (REST API)"
}
output "grafana_url" {
value = astra_database.hello_astra_db.grafana_url
description = "Grafana URL"
}
### These commands are not displayed after the "apply"
output "replication_factor" {
value = astra_database.hello_astra_db.replication_factor
description = "Replication Factor"
}
output "node_count" {
value = astra_database.hello_astra_db.node_count
description = "Node Count"
}
output "total_storage" {
value = astra_database.hello_astra_db.total_storage
description = "Total Storage (GB?)"
}
output "hello_admin_api_token" {
value = astra_token.api_token.token
description = "Generated API token for the hello_admin role"
}
output "hello_admin_client_id" {
value = astra_token.api_token.client_id
description = "Client ID (aka username) for the hello_admin role"
}
output "hello_admin_client_secret" {
value = astra_token.api_token.secret
description = "Secret (aka user password) for the hello_admin role"
}
terraform plan -var="token=$ASTRA_API_TOKEN" -var="organization_id=$ASTRA_ORGANIZATION_ID" -out helloastra
terraform apply helloastra
terraform destroy -var="token=$ASTRA_API_TOKEN" \ -var="organization_id=$ASTRA_ORGANIZATION_ID"