0

I'm using a lambda function, coded in python, as a backend to an aws-api-gateway method.
The api is completed, but now I have a new problem, the API should be deployed to multiple environments (production, test, etc), and each one should use a different configuration for the backend. Let's say that I had this handler:

import settings
import boto3

def dummy_handler(event, context):
    logger.info('got event{}'.format(event))
    utils = Utils(event["stage"])
    response = utils.put_ticket_on_dynamodb(event["item"])
    return json.dumps(response)

class Utils:

    def __init__(self, stage):
        self.stage = stage

    def put_ticket_on_dynamodb(self, item):
        # Write record to dynamoDB
        try:
            dynamodb = boto3.resource('dynamodb')
            table = dynamodb.Table(settings.TABLE_NAME)
            table.put_item(Item=item)
        except Exception as e:
            logger.error("Fail to put item on DynamoDB: {0}".format(str(e)))
            raise
        logger.info("Item successfully written to DynamoDB")
        return item

Now, in order to use a different TABLE_NAME on each stage, I replace the setting.py file by a module, with this structure:

settings/
    __init__.py
    _base.py
    _servers.py
    development.py
    production.py
    testing.py

Following this answer here.
But I don't have any idea of how can I use it on my solution, considering that stage (passed as parameter to the Utils class), will match the settings filename in the module settings, What should I change in my class Utils to make it works?

Community
  • 1
  • 1
Yasel
  • 2,920
  • 4
  • 40
  • 48
  • I don't understand your question. The linked answer suggests making `settings/__init__.py` contain some logic that determines what kind of server it's deployed on, and then import the contents of the appropriate submodule. If you do that, there's nothing that needs to be done in the code that looks up the settings. – Blckknght Feb 21 '16 at 05:22
  • @Blckknght, In my case I don't have a logic to determine the kind of stage, I only have the param stage, and I pass it to the __init__ method of the class Utils. – Yasel Feb 21 '16 at 05:28

2 Answers2

0

Another alternative to handling this use case is to use API Gateway's stage variables and pass in the setting which vary by stage as parameters to your Lambda function.

Stage variables are name-value pairs associated with a specific API deployment stage and act like environment variables for use in your API setup and mapping templates. For example, you can configure an API method in each stage to connect to a different backend endpoint by setting different endpoint values in your stage variables.

Here is a blog post on using stage variables.

Here is the full documentation on using stage variables.

MikeD at AWS
  • 3,565
  • 16
  • 15
  • Thanks Mike, but the issues here is more about of python and how can I use the stage information to import different settings files, using the same lambda function. I am passing the stage information already. – Yasel Feb 22 '16 at 10:18
0

I finally used a different approach here. Instead of a python module for the setting, I used a single script for the settings, with a dictionary containing the configuration for each environment. I would like to use a separate settings script for each environment, but so far I can't find how.

So, now my settings file looks like this:

COUNTRY_CODE = 'CL'
TIMEZONE = "America/Santiago"
LOCALE = "es_CL"
DEFAULT_PAGE_SIZE = 20

ENV = {
    'production': {
        'TABLE_NAME': "dynamodbTable",
        'BUCKET_NAME': "sssBucketName"

    },
    'testing': {
        'TABLE_NAME': "dynamodbTableTest",
        'BUCKET_NAME': "sssBucketNameTest"

    },
    'test-invoke-stage': {
        'TABLE_NAME': "dynamodbTableTest",
        'BUCKET_NAME': "sssBucketNameTest"
    }
}

And my code:

def put_ticket_on_dynamodb(self, item):
    # Write record to dynamoDB
    try:
        dynamodb = boto3.resource('dynamodb')
        table = dynamodb.Table(settings.ENV[self.stage]["TABLE_NAME"])
        table.put_item(Item=item)
    except Exception as e:
        logger.error("Fail to put item on DynamoDB: {0}".format(str(e)))
        raise
    logger.info("Item successfully written to DynamoDB")
    return item
Yasel
  • 2,920
  • 4
  • 40
  • 48