Skip to content

Instantly share code, notes, and snippets.

@burck1
Created March 12, 2020 22:44
Show Gist options
  • Save burck1/4b02192d861068846cc95e5e6037f47b to your computer and use it in GitHub Desktop.
Save burck1/4b02192d861068846cc95e5e6037f47b to your computer and use it in GitHub Desktop.
AWS Lambda Secure Configuration
import os
import boto3
import json
CONFIG_PREFIX = os.getenv('CONFIG_PREFIX')
if not CONFIG_PREFIX:
raise Exception('The CONFIG_PREFIX environment variable is not set. Set this value to continue.')
ssm = boto3.client('ssm')
# Note: run this code here rather than within my_handler so that the config
# settings are only gotten on startup and not with every execution
app_config_parameter_name = f'{CONFIG_PREFIX}/config'
response = ssm.get_parameter(Name=app_config_parameter_name, WithDecryption=True)
app_config_json = response['Parameter']['Value']
app_config = json.loads(app_config_json)
def my_handler(event, context):
print(app_config['username'])
print(app_config['password'])
if __name__ == "__main__":
# Note: this section is only executed when running this file
# locally with "python test.py" and is not executed when
# running in AWS Lambda
my_handler(None, None)
locals {
dept = "engineering"
team = "TODO"
lifecycle = "dev"
product = "TODO"
product_short = "TODO"
region = "us-east-1"
account_id = "TODO"
}
provider "aws" {
region = "${local.region}"
assume_role {
# TODO: set this role the your app's deployer role
role_arn = "arn:aws:iam::${local.account_id}:role/IMO-${local.product_short}-Deployer"
}
}
resource "aws_lambda_function" "this" {
filename = "PATH/TO/lambda_function.zip"
source_code_hash = "${base64sha256(file("PATH/TO/lambda_function.zip"))}"
function_name = "${local.product_short}-${local.lifecycle}"
description = "TODO"
handler = "lambda_handler.my_handler"
runtime = "python3.7"
memory_size = 128
timeout = 10
role = "${aws_iam_role.this.arn}"
environment = {
variables = {
# This environment variable is used by the lambda function as the
# prefix for the SSM Parameter store config
CONFIG_PREFIX = "/${local.product_short}/${local.lifecycle}"
}
}
tags = {
Name = "${local.product_short}-${local.lifecycle}"
Dept = "${local.dept}"
Team = "${local.team}"
LifeCycle = "${local.lifecycle}"
Product = "${local.product}"
ProductShort = "${local.product_short}"
}
}
data "aws_kms_alias" "ssm" {
name = "alias/aws/ssm"
}
resource "aws_ssm_parameter" "config" {
name = "/${local.product_short}/${local.lifecycle}/config"
description = "TODO"
value = "{\"username\":\"CHANGE_ME\",\"password\":\"CHANGE_ME\"}"
type = "SecureString"
key_id = "${data.aws_kms_alias.ssm.name}"
tags = {
Name = "/${local.product_short}/${local.lifecycle}/config"
Dept = "${local.dept}"
Team = "${local.team}"
LifeCycle = "${local.lifecycle}"
Product = "${local.product}"
ProductShort = "${local.product_short}"
}
# this setting tells terraform to ignore any changes to the "value"
# of this ssm parameter so that you can update the value and terraform
# will not override it
lifecycle {
ignore_changes = ["value"]
}
}
resource "aws_iam_role" "this" {
name = "${local.product_short}-${local.lifecycle}-lambda-execution-role"
assume_role_policy = "${data.aws_iam_policy_document.lambda_assume_role.json}"
tags = {
Name = "${local.product_short}-${local.lifecycle}-lambda-execution-role"
Dept = "${local.dept}"
Team = "${local.team}"
LifeCycle = "${local.lifecycle}"
Product = "${local.product}"
ProductShort = "${local.product_short}"
}
}
data "aws_iam_policy_document" "lambda_assume_role" {
statement {
effect = "Allow"
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}
}
}
resource "aws_iam_role_policy" "access" {
name = "access"
role = "${aws_iam_role.this.id}"
policy = "${data.aws_iam_policy_document.logging.json}"
}
data "aws_iam_policy_document" "logging" {
statement {
sid = "CloudWatchLogsAccess"
actions = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
]
resources = ["arn:aws:logs:*:*:*"]
}
statement {
sid = "SSMParametersAccess"
actions = ["ssm:GetParameter"]
resources = ["arn:aws:ssm:${local.region}:${local.account_id}:parameter/${local.product_short}/${local.lifecycle}/*"]
}
statement {
sid = "SSMParametersDecryptAccess"
actions = ["kms:Decrypt"]
resources = ["${data.aws_kms_alias.ssm.target_key_arn}"]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment