Search code examples
herokucassandradatastaxdatastax-python-driverdatastax-astra

Cassandra Astra securely deploying to heroku


I am developing an app using python and Cassandra(Astra provider) and trying to deploy it on Heroku.

The problem is connecting to the database requires the credential zip file to be present locally- https://docs.datastax.com/en/astra/aws/doc/dscloud/astra/dscloudConnectPythonDriver.html '/path/to/secure-connect-database_name.zip' and Heroku does not have support for uploading credentials files.

I can configure the username and password as environment variable but the credential zip file can't be configured as an environment variable.

heroku config:set CASSANDRA_USERNAME=cassandra
heroku config:set CASSANDRA_PASSWORD=cassandra
heroku config:set CASSANDRA_KEYSPACE=mykeyspace

Is there any way through which I can use the zip file an environment variable, I thought of extracting all files and configuring each file an environment variable in Heroku.

but I am not sure what to specify instead of Cluster(cloud=cloud_config, auth_provider=auth_provider) if I started using the extracted files from an environment variable?

I know I can check in the credential zip inside my private git repo that way it works but checking credentials does not seem secure.

Another idea that came to my mind was to store it in S3 and get the file during deployment and extract it inside the temp directory for usage.

Any pointers or help is really appreciated.


Solution

  • If you can checkin secure bundle into repo, then it should be easy - you just need to point to it from the cloud config map, and take username/password from the configured secrets via environment variables:

    from cassandra.cluster import Cluster
    from cassandra.auth import PlainTextAuthProvider
    import os
    
    cloud_config = {
        'secure_connect_bundle': '/path/to/secure-connect-dbname.zip'
    }
    auth_provider = PlainTextAuthProvider(
        username=os.environ['CASSANDRA_USERNAME'], 
        password=os.environ['CASSANDRA_PASSWORD'])
    cluster = Cluster(cloud=cloud_config, auth_provider=auth_provider)
    session = cluster.connect()
    

    Idea about storing the file on S3, and downloading - isn't very bad as well. You can implement it in the script itself, to get file, and you can use environment variables to pass S3 credentials as well, so file won't be accessible in the repository, plus it would be easier to exchange the secure bundles if necessary.