How to create function url for the lambda function via template.

0

I created Lambda function and created the function url in the configuration section for the same by referring this https://docs.aws.amazon.com/lambda/latest/dg/urls-configuration.html#create-url-console. Now, I want to create it via the template. Can anyone please tell me how to do it?

AWSTemplateFormatVersion: 2010-09-09
Description: CloudFormation template for deploying an app using Fargate with EBS storage.

Parameters:
  Image:
    Type: String
  ServiceName:
    Type: String
  ContainerPort:
    Type: Number
    Default: 7000
  AccessKeyId:
    Type: String
  SecretAccessKey:
    Type: String
  DefaultRegion:
    Type: String
  ServerName:
    Type: String
  DatabaseName:
    Type: String
  AdminUsername:
    Type: String
  AdminPassword:
    Type: String
  lambdaFunctionName:
    Type: String
    AllowedPattern: '[a-zA-Z0-9]+[a-zA-Z0-9-]+[a-zA-Z0-9]+'
    Default: corenlpfunction123
  RDSInstanceIdentifier:
    Type: String
  RDSEngine:
    Type: String
    Default: sqlserver-ex
  RDSUsername:
    Type: String
    Default: musigma
  RDSPassword:
    Type: String
    Default: Crunchdata!
  RDSAllocatedStorage:
    Type: Number
    Default: 20
  RDSInstanceClass:
    Type: String
    Default: db.t2.micro
  RDSBackupRetentionPeriod:
    Type: Number
    Default: 7


Resources:
  MyVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: MyVPC

  SubnetA:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: 10.0.0.0/24
      AvailabilityZone: us-east-1a
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: SubnetA

  SubnetB:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: us-east-1b
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: SubnetB

  MyInternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: MyInternetGateway

  MyInternetGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref MyVPC
      InternetGatewayId: !Ref MyInternetGateway

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref MyVPC
      Tags:
        - Key: Name
          Value: PublicRouteTable

  DefaultRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref MyInternetGateway

  SubnetARouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref SubnetA
      RouteTableId: !Ref PublicRouteTable

  SubnetBRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref SubnetB
      RouteTableId: !Ref PublicRouteTable

  MySecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: My Security Group
      VpcId: !Ref MyVPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 7000
          ToPort: 7000
          CidrIp: 0.0.0.0/0
      SecurityGroupEgress:
        - IpProtocol: '-1'
          FromPort: 0
          ToPort: 65535
          CidrIp: 0.0.0.0/0

  RDSDatabase:
    Type: AWS::RDS::DBInstance
    Properties:
      DBInstanceIdentifier: !Ref RDSInstanceIdentifier
      Engine: !Ref RDSEngine
      MasterUsername: !Ref RDSUsername
      MasterUserPassword: !Ref RDSPassword
      AllocatedStorage: !Ref RDSAllocatedStorage
      DBInstanceClass: !Ref RDSInstanceClass
      BackupRetentionPeriod: !Ref RDSBackupRetentionPeriod
      VPCSecurityGroups:
        - !Ref MySecurityGroup
      AvailabilityZone: us-east-1a
      DBSubnetGroupName: !ImportValue DbSubnetGroupNameImportedValue


  lambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        ImageUri: 934271694309.dkr.ecr.us-east-1.amazonaws.com/cloudops:lambda
      Description: Example Lambda function using Docker image
      FunctionName: !Ref lambdaFunctionName
      Role: !GetAtt lambdaIAMRole.Arn
      Architectures:
      - x86_64
      PackageType: Image
      Timeout: 300 # 5 minutes (timeout is in seconds)
      MemorySize: 1024 # 1024 MB
      Environment:
        Variables:
          FUNCTION_APP_AUTH_TYPE: AWS_IAM
      

  lambdaIAMRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
      Policies:
        - PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                  - ecr:GetDownloadUrlForLayer
                  - ecr:BatchGetImage
                  - lambda:InvokeFunction
                  - sts:GetCallerIdentity
                Effect: Allow
                Resource:
                  - !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${lambdaFunctionName}:*
          PolicyName: lambda

  Cluster:
    Type: AWS::ECS::Cluster
    Properties:
      ClusterName: !Join ['', [!Ref ServiceName, Cluster]]

  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      NetworkMode: awsvpc
      RequiresCompatibilities:
        - FARGATE
      Cpu: '4096'
      Memory: '16384'

      ExecutionRoleArn: !GetAtt ExecutionRole.Arn
      TaskRoleArn: !GetAtt TaskRole.Arn
      ContainerDefinitions:
        - Name: !Ref ServiceName
          Image: !Ref Image
          PortMappings:
            - ContainerPort: !Ref ContainerPort
          Essential: true
          Environment:
            - Name: AWS_ACCESS_KEY_ID
              Value: !Ref AccessKeyId
            - Name: AWS_SECRET_ACCESS_KEY
              Value: !Ref SecretAccessKey
            - Name: AWS_DEFAULT_REGION
              Value: !Ref DefaultRegion
            - Name: SERVER_NAME
              Value: !Ref ServerName
            - Name: DATABASE_NAME
              Value: !Ref DatabaseName
            - Name: ADMIN_USERNAME
              Value: !Ref AdminUsername
            - Name: ADMIN_PASSWORD
              Value: !Ref AdminPassword
            - Name: LAMBDA_FUNCTION_NAME
              Value: !Ref lambdaFunctionName 
      
      EphemeralStorage:
        SizeInGiB: 150

  ExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: muNLQExecutionRole
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service: ecs-tasks.amazonaws.com
            Action: 'sts:AssumeRole'
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy'

  TaskRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: muNLQTaskRole
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service: ecs-tasks.amazonaws.com
            Action: 'sts:AssumeRole'
  
  FargateService:
    Type: AWS::ECS::Service
    Properties:
      Cluster: !Ref Cluster
      LaunchType: FARGATE
      ServiceName: munlq-service
      DesiredCount: 1
      TaskDefinition: !Ref TaskDefinition
      LoadBalancers:
        - ContainerName: !Ref ServiceName
          ContainerPort: !Ref ContainerPort
          TargetGroupArn: !Ref TargetGroup
      NetworkConfiguration:
        AwsvpcConfiguration:
          AssignPublicIp: ENABLED
          SecurityGroups:
            - !Ref MySecurityGroup  # Corrected reference to MySecurityGroup
            - !GetAtt RDSDatabase.Endpoint.SecurityGroups[0]  # Add this line to reference RDS security group

          Subnets:
            - !Ref SubnetA
            - !Ref SubnetB
      DeploymentConfiguration:
        MaximumPercent: 200
        MinimumHealthyPercent: 100
        DeploymentCircuitBreaker:
          Enable: true
          Rollback: true


  LoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: !Join ['', [!Ref ServiceName, LoadBalancer]]
      Type: application
      Subnets:
        - !Ref SubnetA
        - !Ref SubnetB
      SecurityGroups:
        - !Ref MySecurityGroup

  TargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      HealthCheckPath: /
      Name: !Join ['', [!Ref ServiceName, TargetGroup]]
      Port: !Ref ContainerPort
      Protocol: HTTP
      VpcId: !Ref MyVPC
      HealthCheckProtocol: HTTP
      TargetType: ip
      LoadBalancerArns:
        - !Ref LoadBalancer
      Matcher:
        HttpCode: '200,308,404'


  Listener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: forward
          TargetGroupArn: !Ref TargetGroup
      LoadBalancerArn: !Ref LoadBalancer
      Port: 7000
      Protocol: HTTP
asked 8 months ago299 views
1 Answer
3
Accepted Answer

It'd be done using AWS::Lambda::Url function. Please refer AWS Cloudformation Documentation.

In addition to this, you'll need to add function URL permissions to lambda function using cloudformation function AWS::Lambda::Permission

    Action: 'lambda:InvokeFunctionUrl'
    Principal: <based on your requirement, it can be *>
    Resource: <Lambda function>

Also you can consider adding condition while adding permission for lambda:FunctionUrlAuthType: "NONE/AWS_IAM"

Hope you find this useful.

Comment here if you have additional questions, happy to help.

Abhishek

profile pictureAWS
EXPERT
answered 8 months ago
profile picture
EXPERT
reviewed 5 months ago
profile pictureAWS
EXPERT
iBehr
reviewed 8 months ago
profile pictureAWS
EXPERT
reviewed 8 months 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