Terraform-provider-aws: Support for AWS Serverless Application Model and Repository

Created on 29 Mar 2018  路  23Comments  路  Source: hashicorp/terraform-provider-aws

_This issue was originally opened by @obierlaire as hashicorp/terraform#17729. It was migrated here as a result of the provider split. The original body of the issue is below._


AWS offers now a repository of serverless applications.
Basically, it's a SAM (Serverless Application Model) repository, where anybody can publish or use serverless application templates (similar as Cloudformation templates)

Terraform supports Cloudformation Data sources and Cloudformation Resources, but no SAM Data source/resource.

The API supports publishing SAM to SAR and consuming SAM from SAR (https://docs.aws.amazon.com/serverlessrepo/latest/devguide/resources.html)

new-resource servicserverlessapplicationrepository

Most helpful comment

This needs some love.

All 23 comments

This needs some love.

I'll work on a data source for serverless applications. The current API is a little lacking, especially for searching the public repositories.

@obierlaire, @cornfeedhobo & everyone else, what are your usecases for the Serverless Application Repo? I'm starting with using applications from the public repo, since that's my current need.

Does anyone need other cases?

@gdavison the next few weeks will be tight with conferences. I'll do my best to put together a solid example use case, as my current repo has just worked around this.

This has gotten a little more complicated. I've created the data source, but I can't use the template to create a Cloud Formation stack because CreateStack cannot be used with templates containing Transforms. Time to dig deeper!

This looks related to #132

I've figured it out. I can now spin up an application from the Repo. It needs more config, more outputs, and update functionality

It would be great to see this, I need to deploy the same "Serverless Application" from the repository in many many regions

Would love to be able to setup Lambdas by specifying a source in the Serverless Application Repository.

We are using GuardDuty SumoLogic app (https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:956882708938:applications~sumologic-guardduty-events-processor) and I am tasked to decide how to include it in out terraform repo.
This functionality would be great, but it seems like I will have to write a terraform module from scratch.

@stepps I'm trying to do the same thing. Do you end up finding a solution?

@nealharris No, this item is stuck in my backlog for the time being.

Still no SAM Data Source Resource for terraform 12.0???

Any luck on this issue?? :keep-watching:

Adding another voice that is looking for this...any updates?

Any update on this one. This could be really helpful +1

@gdavison my use case is trying to follow these instructions from Datadog:

  1. From the Lambda Management Console, create a new Lambda Function. Your Lambda function must be in the same region as the KMS key you created.
  2. Choose Serverless Application Repository, search for and select Datadog-RDS-Enhanced
  3. Give the application a unique name.
  4. Paste the Id of the key created in the previous section in the KMSKeyId parameter and deploy.
    ...

https://docs.datadoghq.com/integrations/amazon_rds/#create-your-lambda-function

Ok, I'm finally picking this back up.

When I last worked on it, I had it set up so that you could specify a version, or it would use the latest version if not specified. The version could be updated if it was specified.

I stalled out with a number of refinement decisions and not needing it for my day job. I'll rebase onto the current codebase and verify that it works.

@bflad any comments/feedback on how version updates should work?

Could I get a quick thumbs-up/thumbs-down poll in the reactions below this comment?
馃憤 if you want/need terraform import,
馃憥 if you don't want/need it, this includes not needing it yet.

@bflad your guidance would be good here.

I have the resource created to create and deploy an application from the Serverless Application Repository. The hold-up is import, because I need to suppress some tags that AWS automatically adds, but they shouldn't be modified nor should they show a diff in terraform plan.

I'm fairly confident that this is doable, but I need to learn the internals of Terraform a whole lot better.

The drawback with adding import later is that the stored state could change significantly, causing pain when updating the provider.

So I see the options as:
1. Delay the resource until import is available (馃憤 option above)
* Pros:
* Complete
* Cons:
* Unknown delay
2. Release now and backfill the import (馃憥 option above)
* Pros:
* Can be used sooner
* Cons:
* Possible complications when users update the provider

Ok, the results are pretty clear :)

Any updates on this? 馃槉

馃憢 Many of us are finding this issue as they are following the Datadog RDS enhanced monitoring guide.
This isn't quite yet possible in Terraform so you have to do some things by yourself.
The one thing the snippet below cannot do is encrypting data at rest! This means in Terraform Plan, TF State, Lambda console, and in transit your datadog keys will be plaintext visible.

I have the following stored in /python/*.py -- referenced below in archive.

##############################################################################
# KMS key for Datadog Agent & Lambda
##############################################################################

resource "aws_kms_key" "datadog_lambda" {
  description             = "Used by Lambda pushing data to Datadog"
  deletion_window_in_days = 30
  enable_key_rotation     = true
}

resource "aws_kms_alias" "datadog_lambda" {
  name          = "alias/${var.namespace}-${var.stage}-datadog"
  target_key_id = aws_kms_key.datadog_lambda.key_id
}

#################################################
# Archive Lambda script & Create Lambda Function
#################################################

data "archive_file" "lambda_zip" {
  type        = "zip"
  source_dir  = "${path.module}/python"
  output_path = "${path.module}/python/rds_enhanced_monitoring.zip"
}

resource "aws_lambda_function" "datadog_postresql" {
  function_name    = "${var.namespace}-${var.stage}-datadog-rds-enhanced-monitoring"
  description      = "Pushes RDS Enhanced metrics to Datadog"
  role             = aws_iam_role.datadog_lambda.arn
  runtime          = "python2.7"
  handler          = "rds_enhanced_monitoring.lambda_handler"
  filename         = data.archive_file.lambda_zip.output_path
  source_code_hash = data.archive_file.lambda_zip.output_base64sha256
  publish          = true
  timeout          = 10
  kms_key_arn      = aws_kms_key.datadog_lambda.arn
  memory_size      = 128
  environment {
    variables = {
      kmsEncryptedKeys = jsonencode({ "api_key" = var.datadog_api_key, "app_key" = var.datadog_app_key })
    }
  }
}

##############################################################################
# Lambda IAM Execution Role
##############################################################################

resource "aws_iam_role" "datadog_lambda" {
  name               = "${var.namespace}-${var.stage}-datadog-rds-lambda"
  path               = "/"
  assume_role_policy = data.aws_iam_policy_document.datadog_lambda_assume_role.json
}

data "aws_iam_policy_document" "datadog_lambda_assume_role" {
  statement {
    effect  = "Allow"
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["lambda.amazonaws.com"]
    }
  }
}

data "aws_iam_policy_document" "datadog_lambda" {
  statement {
    sid       = "KMS"
    effect    = "Allow"
    resources = [aws_kms_key.datadog_lambda.arn]
    actions = [
      "kms:Decrypt"
    ]
  }
}

resource "aws_iam_policy" "datadog_lambda" {
  name   = "${var.namespace}-${var.stage}-datadog-rds-lambda"
  path   = "/"
  policy = data.aws_iam_policy_document.datadog_lambda.json
}

resource "aws_iam_role_policy_attachment" "datadog_lambda" {
  role       = aws_iam_role.datadog_lambda.name
  policy_arn = aws_iam_policy.datadog_lambda.arn
}

in absence of a native tf resource for SAR, one can always create an aws_cloudformation_stack resource and then from the inline code, call the resource from the serverless app...

resource "aws_cloudformation_stack" "myappstack" {
  name = "myapp-stack"

  parameters = {
    VPCCidr = "10.0.0.0/16"
  }

  template_body = <<STACK
Resources:
  mySAR:
    Type: AWS::Serverless::Application
    Properties:
      Location:
        ApplicationId: arn:aws:serverlessrepo:us-west-2:012345678912:applications/myapp1
        SemanticVersion: 0.1.1
      Parameters:
        Subnets: !Ref Subnets
        VpcId: !Ref VpcId

STACK
}
Was this page helpful?
0 / 5 - 0 ratings