April 4, 2022

Let’s Get Started with Terraform for Astra DB

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"
Share

One-stop Data API for Production GenAI

Astra DB gives JavaScript developers a complete data API and out-of-the-box integrations that make it easier to build production RAG apps with high relevancy and low latency.