AWS cloudformation template

0

How to write a cloudformation template which create a website hosted on AWS amplify with a button which on click will invoke a lambda function

1 Answer
0

Hi Keerthi,

Please try this below solution and go through the below documentation links, i hope it will helps to resolve your issue.

  1. Create an AWS Amplify App and Deployment: This sets up your web hosting.

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-amplify-app.html

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-amplify-branch.html

  1. Create a Lambda Function: This will be invoked when the button is clicked.

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-permission.html

  1. Create an API Gateway: This will serve as the endpoint for invoking the Lambda function.

  2. Deploy Your Website with the Button: This will include the frontend code with a button that calls the API Gateway endpoint.

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-restapi.html

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-resource.html

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-method.html

Here’s an example of how to structure your CloudFormation template:


AWSTemplateFormatVersion: '2010-09-09'
Resources:
  # Define the Amplify App
  MyAmplifyApp:
    Type: AWS::Amplify::App
    Properties:
      Name: MyAmplifyApp
      Repository: https://github.com/your-repo/your-app
      OauthToken: !Ref GitHubToken  # Provide your GitHub token here
      BuildSpec: |
        version: 1
        frontend:
          phases:
            preBuild:
              commands:
                - npm install
            build:
              commands:
                - npm run build
          artifacts:
            baseDirectory: build
            files:
              - '**/*'
          cache:
            paths:
              - node_modules/**/*

  # Define the Amplify Branch
  MyAmplifyBranch:
    Type: AWS::Amplify::Branch
    Properties:
      AppId: !Ref MyAmplifyApp
      BranchName: main

  # Define the Lambda Function
  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: MyLambdaFunction
      Handler: index.handler
      Role: !GetAtt LambdaExecutionRole.Arn
      Code:
        ZipFile: |
          exports.handler = async (event) => {
            return {
              statusCode: 200,
              body: JSON.stringify('Hello from Lambda!'),
            };
          }
      Runtime: nodejs14.x

  # Define the Lambda Execution Role
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: LambdaExecutionPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: '*'

  # Define the API Gateway
  MyApiGateway:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Name: MyApiGateway
      Description: Invoke Lambda function via API Gateway

  MyApiGatewayResource:
    Type: AWS::ApiGateway::Resource
    Properties:
      ParentId: !GetAtt MyApiGateway.RootResourceId
      PathPart: lambda
      RestApiId: !Ref MyApiGateway

  MyApiGatewayMethod:
    Type: AWS::ApiGateway::Method
    Properties:
      AuthorizationType: NONE
      HttpMethod: POST
      ResourceId: !Ref MyApiGatewayResource
      RestApiId: !Ref MyApiGateway
      Integration:
        IntegrationHttpMethod: POST
        Type: AWS_PROXY
        Uri: !Sub
          - arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyLambdaFunction.Arn}/invocations
          - MyLambdaFunction.Arn: !GetAtt MyLambdaFunction.Arn

  # Grant API Gateway permission to invoke the Lambda function
  ApiGatewayLambdaInvokePermission:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !Ref MyLambdaFunction
      Principal: apigateway.amazonaws.com
      SourceArn: !Sub
        - arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${MyApiGateway}/*
        - MyApiGateway: !Ref MyApiGateway

  # Outputs
  ApiEndpoint:
    Description: "API Gateway Endpoint"
    Value: !Sub "https://${MyApiGateway}.execute-api.${AWS::Region}.amazonaws.com/prod/lambda"
    Export:
      Name: ApiEndpoint

Parameters:
  GitHubToken:
    Type: String
    Description: "GitHub OAuth Token for Amplify"
    NoEcho: true

In your front-end code (e.g., in the React app), you can add a button that calls the API Gateway endpoint:


import React from 'react';

const App = () => {
  const handleClick = async () => {
    const response = await fetch('https://your-api-id.execute-api.region.amazonaws.com/prod/lambda', {
      method: 'POST',
    });
    const data = await response.json();
    console.log(data);
  };

  return (
    <div>
      <button onClick={handleClick}>Invoke Lambda</button>
    </div>
  );
};

export default App;



Above CloudFormation template creates the required resources, and the example code demonstrates how to invoke the Lambda function from your front-end application. Be sure to replace placeholder values with your actual configuration.

EXPERT
answered 13 days ago
profile picture
EXPERT
reviewed 13 days ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions