Disk Space Reporting through Lamba Functions- Windows servers

Solution Objective:

The solution provides detailed report related to hard disk space for all the Windows Ec2 instances in the AWS environment.

Requirements:

Mentioned below are the requirements the solution should be able to fulfil.

  • Gather information related to all mount points in all the Windows EC2 instances in the environment.
  • Able to generate cumulative report based on all instances in the environment.

3. Assumptions:

The following assumptions are considered

  • All the EC2 instances have SSM agent installed.
  • The personnel responsible for the configuration have some understanding of IAM Roles, S3 buckets and lambda functions

4. Solutions Description:

The following services provided by Amazon will be utilized to generate the report

  • PowerShell Scripts
  • AWS S3
  • AWS Lambda
  • AWS IAM Roles
  • Maintenances Windows

4.1      Linux Shell Script.

PowerShell Script will be utilized to generate information about the instance and the mount points space utilization.
Mentioned below script needs to be executed on all Windows Ec2 instances to generate the mount point information.

$instanceId = Invoke-WebRequest -Uri http://169.254.169.254/latest/meta-data/instance-id -UseBasicParsing
$instanceId.content
Get-WmiObject Win32_logicaldisk | select DeviceID,Size,Used,FreeSpace,PlaceHolder,VolumeName | ft -Autosize

4.1      AWS S3

The result of the shell script will be posted to an S3 bucket for further use.
The EC2 instances will need write access to the nominated S3 bucket for certificate Maintenance.
S3 Bucket Name: eomreport ( sample name )

4.2      AWS Lambda Functions

Lambda Functions will be used to perform the following activities.

  • Acquire the result of the Shell script from the S3 bucket
  • Generate a Report
  • Email the report to the relevant recipient

The Lambda Functions would need read access to the S3 bucket and access to AWS SES to send emails to recipients.
Mentioned below is the Lambda Functions that performs the mentioned above tasks.

import boto3
import codecs
import pprint
from datetime import datetime, date, time
def lambda_handler(event,Context):
    s3 = boto3.resource('s3')
    mybucket = s3.Bucket('diskspacewindows')
    resulthtml = ["<h1>Report : Hard disk Space Client Name </h1>"] # Adds heading to the email body
    resulthtml.append('<html><body><table border="1">') # Creates a table
    resulthtml.append('<tr><td><b>InstanceID</b></td><td><b>Drive Letter</b></td><td><b> FreeSpace</b></td><td><b>Total Space </b></td></b></tr>')
    for file_key in mybucket.objects.all():
        complete_string = str(file_key)
        search = "stdout"
        check = complete_string.find(search)
        if check > 0 :
            body = file_key.get()['Body'].read().decode('utf-8')
            complete=body.splitlines() #splits data into lines.
            id="".join(complete[0])
            details=complete[4:]
            resulthtml.append(("<td>'{}'</td><td></td><td></td><td></td></tr>").format(id)) # for the HTML email to be sent.
            for line in details:
                    output_word=line.split()
                    dstr="".join(line)
                    #print(output_word)
                    #print(len(output_word))
                    if len(output_word) > 0:
                      resulthtml.append(("<td></td><td>'{}'</td><td>'{}'</td><td>'{}'</td></tr>").format(output_word[0],output_word[1],output_word[2])) # for the HTML email to be sent.
    resulthtml.append('</table></body></html>')
    final=str("".join(resulthtml))
    final=final.replace("'","")
    print(final)
    sender = "syed.naqvi@kloud.com.au"
    recipient = "syed.naqvi@kloud.com.au"
    awsregion = "us-east-1"
    subject = "Client Hard Disk Space - Windows "
    charset = "UTF-8"
    mylist="mylist update"
    client = boto3.client('ses',region_name=awsregion)
    try:
        response = client.send_email(
           Destination={
               'ToAddresses': [
                   recipient,
                ],
            },
         Message={
                  'Body': {
                      'Html': {
                        'Charset': charset,
                        'Data': final,
                             },
                    'Text': {
                     'Charset': charset,
                     'Data': mylist,
                    },
                },
                'Subject': {
                    'Charset': charset,
                    'Data': subject,
                },
            },
            Source=sender,
        )
    # Display an error if something goes wrong.
    except Exception as e:
        print( "Error: ", e)
    else:
       print("Email sent!")

 
4.1 AWS IAM Roles
Roles will be used to grant

  • AWS S3 write access to all the EC2 instances as they will submit the output of the  the S3 bucket
  • AWS SES access to Lambda Functions to send emails to relevant recipients.

4.2 AWS SES

Amazon Simple Email Service (Amazon SES) evolved from the email platform that Amazon.com created to communicate with its own customers. In order to serve its ever-growing global customer base, Amazon.com needed to build an email platform that was flexible, scalable, reliable, and cost-effective. Amazon SES is the result of years of Amazon’s own research, development, and iteration in the areas of sending and receiving email.( Ref. From https://aws.amazon.com/ses/).
We would be utilizing AWS SES to generate emails using AWS lambda.
The configuration of the Lambda functions can be modified to send emails to a distribution group to provide Certificate reporting, or it can be used to send emails to ticketing system in order to provide alerting and ticket creation in case a certificate expiration date crosses a configured threshold.

5Solution Configuration

5.1 Configure IAM Roles

The following Roles should be configured

  • IAM role for Lambda Function.
  • IAM for EC2 instances for S3 bucket Access

5.1.1 Role for Lambda Function

Lambda function need the following access

  • Read data from the S3 bucket
  • Send Emails using Amazon S3

To accomplish the above the following policy should be created and attached to the IAM Role

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1501474857000",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::S3BucketName/*"
            ]
        },
        {
            "Sid": "Stmt1501474895000",
            "Effect": "Allow",
            "Action": [
                "ses:SendEmail"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

6.1.2  Role for EC2 instance

All EC2 instances should have access to store the Shell output in the S3 bucket.
To accomplish the above , the following policy should be assigned to the EC2 roles

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1501475224000",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::eomreport"
            ]
        }
    ]
}

6.2 Configure Maintenance Window.

The following tasks need to be performed for the maintenance window

  • Register a Run Command with Run-Shell Script using the script in section 4.1
  • Register targets based on the requirements
  • Select the schedule based on your requirement

Maintenance Window Ref : 
http://docs.aws.amazon.com/systems-manager/latest/userguide/what-is-systems-manager.html

6.3 Configure Lambda Function:

The following tasks need to be performed for the Lambda Function

  • Create a blank lambda function with the S3 put event as the trigger\lambda function
  • Click on Next
  • Enter the Name and Description
  • Select run time Python 3.6
  • Copy and paste the lambda function mentioned in section 4.3

    6.4 Configuring AWS SES

The following tasks need to be completed before the execution of the Run-commands.

  • Email Addresses should be added to the AWS SES section of the tenant.
  • The email addresses should be verified.

 7. Result:

Based on the above configuration, whenever the run command is executed, the following report is generated and sent to the nominated email account.

Replacing the service desk with bots using Amazon Lex and Amazon Connect (Part 3)

Hopefully you’ve had the chance to follow along in parts 1 and 2 where we set up our Lex chatbot to take and validate input. In this blog, we’ll interface with our Active Directory environment to perform the password reset function. To do this, we need to create a Lambda function that will be used as the logic to fulfil the user’s intent. The Lambda function will be packaged with the python LDAP library to modify the AD password attribute for the user. Below are the components that need to be configured.

Active Directory Service Account

To begin, we need to start by creating a service account in Active Directory that has permissions to modify the password attribute for all users. Our Lambda function will then use this service account to perform password resets. To do this, create a service account in your Active Directory domain and perform the following to delegate the required permissions:

  1. Open Active Directory Users and Computers.
  2. Right click the OU or container that contains organisational users and click Delegate Control
  3. Click Next on the Welcome Wizard.
  4. Click Add and enter the service account that will be granted the reset password permission.
  5. Click OK once you’ve made your selection, followed by Next.
  6. Ensure that Delegate the following common tasks is enabled, and select Reset user passwords and force password change at next logon.
  7. Click Next, and Finish.

KMS Key for the AD Service Account

Our Lambda function will need to use the credentials for the service account to perform password resets. We want to avoid storing credentials within our Lambda function, so we’ll store the password as an encrypted Lambda variable and allow our Lambda function to decrypt it using Amazon’s Key Management Service (KMS). To create the KMS encryption key, perform the following steps:

  1. In the Amazon Console, navigate to IAM
  2. Select Encryption Keys, then Create key
  3. Provide an Alias (e.g. resetpw) then select Next
  4. Select Next Step for all subsequent steps then Finish on step 5 to create the key.

IAM Role for the Lambda Function

Because our Lambda function will need access to several AWS services such as SNS to notify the user of their new password and KMS to decrypt the service account password, we need to provide our function with an IAM role that has the relevant permissions. To do this, perform the following steps:

  1. In the Amazon Console, navigate to IAM
  2. Select Policies then Create policy
  3. Switch to the JSON editor, then copy and paste the following policy, replacing the KMS resource with the KMS ARN created above
    {
       "Version": "2012-10-17",
       "Statement": [
         {
           "Effect": "Allow",
           "Action": "sns:Publish",
           "Resource": "*"
         },
         {
           "Effect": "Allow",
           "Action": "kms:Decrypt",
           "Resource": "<KMS ARN>"
         }
       ]
    }
  4. Provide a name for the policy (e.g. resetpw), then select Create policy
  5. After the policy has been created, select Roles, then Create Role
  6. For the AWS Service, select Lambda, then click Next:Permissions
  7. Search for and select the policy you created in step 5, as well as the AWSLambdaVPCAccessExecutionRole and AWSLambdaBasicExecutionRole policies then click Next: Review
  8. Provide a name for the role (e.g. resetpw) then click Create role

Network Configuration for the Lambda Function

To access our Active Directory environment, the Lambda function will need to run within a VPC or a peered VPC that hosts an Active Directory domain controller. Additionally, we need the function to access the internet to be able to access the KMS and SNS services. Lambda functions provisioned in a VPC are assigned an Elastic network Interface with a private IP address from the subnet it’s deployed in. Because the ENI doesn’t have a public IP address, it cannot simply leverage an internet gateway attached to the VPC for internet connectivity and as a result, must have traffic routed through a NAT Gateway similar to the diagram below.

Password Reset Lambda Function

Now that we’ve performed all the preliminary steps, we can start building the Lambda function. Because the Lambda execution environment uses Amazon Linux, I prefer to build my Lambda deployment package on a local Amazon Linux docker container to ensure library compatibility. Alternatively, you could deploy a small Amazon Linux EC2 instance for this purpose, which can assist with troubleshooting if it’s deployed in the same VPC as your AD environment.
Okay, so let’s get started on building the lambda function. Log in to your Amazon Linux instance/container, and perform the following:

  • Create a project directory and install python-ldap dependencies, gcc, python-devel and openldap-devel
    Mkdir ~/resetpw
    sudo yum install python-devel openldap-devel gcc
  • Next, we’re going to download the python-ldap library to the directory we created
    Pip install python-ldap -t ~/resetpw
  • In the resetpw directory, create a file called reset_function.py and copy and paste the following script
  • Now, we need to create the Lambda deployment package. As the package size is correlated with the speed of Lambda function cold starts, we need to filter out anything that’s not necessary to reduce the package size. The following zip’s the script and LDAP library:
    Cd ~/resetpw
    zip -r ~/resetpw.zip . -x "setuptools*/*" "pkg_resources/*" "easy_install*"
  • We need to deploy this package as a Lambda function. I’ve got AWSCLI installed in my Amazon Linux container, so I’m using the following CLI to create the Lambda function. Alternatively, you can download the zip file and manually create the Lambda function in the AWS console using the same parameters specified in the CLI below.
    aws lambda create-function --function-name reset_function --region us-east-1 --zip-file fileb://root/resetpw.zip --role resetpw --handler reset_function.lambda_handler --runtime python2.7 --timeout 30 --vpc-config SubnetIds=subnet-a12b3cde,SecurityGroupIds=sg-0ab12c30 --memory-size 128
  • For the script to run in your environment, a number of Lambda variables need to be set which will be used at runtime. In the AWS Console, navigate to Lambda then click on your newly created Lambda function. In the environment variables section, create the following variables:
    • Url – This is the LDAPS URL for your domain controller. Note that it must be LDAP over SSL.
    • Domain_base_dn – The base distinguished name used to search for the user
    • User – The service account that has permissions to change the user password
    • Pw – The password of the service account
  • Finally, we need to encrypt the Pw variable in the Lambda console. Navigate to the Encryption configuration and select Enable helpers for encryption in transit. Select your KMS key for both encryption in transit and at reset, then select the Encrypt button next to the pw variable. This will encrypt and mask the value.

  • Hit Save in the top right-hand corner to save the environment variables.

That’s it! The Lambda function is now configured. A summary of the Lambda function’s logic is as follows:

  1. Collect the Lambda environment variables and decrypt the service account password
  2. Perform a secure AD bind but don’t verify the certificate (I’m using a Self-Signed Cert in my lab)
  3. Collect the user’s birthday, start month, telephone number, and DN from AD
  4. Check the user’s verification input
  5. If the input is correct, reset the password and send it to the user’s telephone number, otherwise exit the function.

Update and test Lex bot fulfillment

The final step is to add the newly created Lambda function to the Lex bot so it’s invoked after input is validated. To do this, perform the following:

  1. In the Amazon Console, navigate to Amazon Lex and select your bot
  2. Select Fulfillment for your password reset intent, then select AWS Lambda function
  3. Choose the recently created Lambda function from the drop down box, then select Save Intent

That should be it! You’ll need to build your bot again before testing…

My phone buzzes with a new SMS…

Success! A few final things worth noting:

  • All Lambda execution logs will be written to CloudWatch logs, so this is the best place to begin troubleshooting if required
  • Modification to the AD password attribute is not possible without a secure bind and will result in an error.
  • The interrogated fields (month started and date of birth) are custom AD attributes in my lab.
  • Password complexity in my lab is relaxed. If you’re using the default password complexity in AD, the randomly generated password in the lambda function may not meet complexity requirements every time.

Hope to see you in part 4, where we bolt on Amazon Connect to field phone calls!

Certificate Management using PowerShell and Lambda Functions

Certificate Management

1. Why Certificate Management is required.

Certificates installed on client machines are one of the critical resources in the client’s infrastructure. Monitoring certificates is critical to any company willing to successfully provide Certificate Management service. The process of manually reporting certificate details is tedious is time consuming, so it better to automate it.
The following document will explain the steps to configure AWS services to provide certificate management for customers with AWS hosted infrastructure.

2. Solution Requirements

Mentioned below are the requirements that should be fulfilled to provide proper certificate management services.

  • The Solution should scan all instances for installed Certificates
  • The solution should be able to generate Reports which include the following information
    • Instance ID of the machine the certificate is installed on
    • Subject of the Certificate
    • Days till expiration
  • The solution should be able to generate an alert if the “days to expire” falls below 30 Days.
  • The alert should be able to create a ticket which can later be worked on to rectify the situation

Note: The requirements for certificate management are prone to change based on the requirements for the clients.

3. Assumptions:

The following assumptions are considered while configuring certificate management:

  • All the EC2 instances are running proper windows PowerShell.
  • All the EC2 instances have SSM agent installed.
  • The personnel responsible for the configuration of certificate management have some understanding of IAM Roles, S3 buckets and lambda functions

4. Solutions Description:

The following services provided by Amazon will be utilized to provide certificate management

  • Windows PowerShell
  • AWS S3
  • AWS Lambda
  • AWS IAM Roles
  • Maintenances Windows

4.1      Windows PowerShell

PowerShell will be utilized to generate information about the certificate and instance id for the AMI.
Mentioned below script needs to be executed on all AMI’s to generate the certificate information.

Set-Location Cert:\LocalMachine\my #Sets the location
$CertificateDetails = get-childitem # Get all the machine certificates
$instanceId = Invoke-WebRequest -usebasicparsing -Uri http://169.254.169.254/latest/meta-data/instance-id # Gets the instance ID
foreach ($i in $CertificateDetails) # writes the output with certificate Thumbprint , Subject, Instance ID and Expiration Date
{ 
Write-host "Thumbprint=" $i.Thumbprint " Expiration Date="$i.NotAfter " InstanceID ="$instanceID.Content" Subject="$i.Subject 
}

The following output is generated as a result of the PowerShell script.
 

Thumbprint= ****************** Expiration Date= 1/1/2040 10:59:59 AM InstanceID = i-******* Subject= CN=SubjectName Blah Blah Blah
Thumbprint= ****CYXZ********** Expiration Date= 1/1/2040 10:59:59 AM InstanceID = i-******* Subject= CN=SubjectName Blah Blah Blah
Thumbprint= ****************** Expiration Date= 1/1/2040 10:59:59 AM InstanceID = i-******* Subject= CN=SubjectName Blah Blah Blah
Thumbprint= ****************** Expiration Date= 1/1/2040 10:59:59 AM InstanceID = i-******* Subject= CN=SubjectName Blah Blah Blah
Thumbprint= ****************** Expiration Date= 1/1/2040 10:59:59 AM InstanceID = i-******* Subject= CN=SubjectName Blah Blah Blah

Where * represents different values for different certificates.

4.1      AWS S3

The result of the PowerShell script will be posted to an S3 bucket for further use.
The EC2 instances will need write access to the nominated S3 bucket for certificate Maintenance.
S3 Bucket Name: CertificateManagement

4.2      AWS Lambda Functions

Lambda Functions will be used to perform the following activities.

  • Acquire the result of the PowerShell script from the S3 bucket
  • Process the data to determine the Days till expiration of all the certificates
  • Generate a Report
  • Email the report to the relevant recipient

The Lambda Functions would need read access to the S3 bucket and access to AWS SES to send emails to recipients.
Mentioned below is the Lambda Functions that performs the mentioned above tasks.

import boto3
import codecs
import pprint
from datetime import datetime, date, time
def lambda_handler(event,Context):
    s3 = boto3.resource('s3')
    mybucket = s3.Bucket('CertificateManagement')
    result=["this is the result","\n"]
    for file_key in mybucket.objects.all():
        print("\n")
        body = file_key.get()['Body'].read().decode('utf-8')
        output_lines=body.splitlines() #splits data into lines.
        resulthtml = ["<h1>Client Certificate Report</h1>"] # Adds heading to the email body
        resulthtml.append('<html><body><table border="1">') # Creates a table
        resulthtml.append('<tr><b><td>InstanceID</td><td>Thumbprint</td><td>Subject</td><td>Days to Expiration</td></b></tr>')
        try:
            for line in output_lines:
                x=1
                output_word=line.split() # splits every line into words
                cnlist=output_word[10:] # gets the complete subject name and adds into an array
                cnstr=" ".join(cnlist) # joins the array to create a string.
                dt = datetime.strptime(str(output_word[4]), "%m/%d/%Y") # Converts the Date values string into a date format.
                ct=datetime.now()
                difference=dt-ct # Gets the difference between the date value and current date.
                Values = str(difference) # converts the difference into string
                Valuelist=Values.split() # converts the string into arrays.
                Days = Valuelist[0] # selcts the first value in the array which is Number of days.
                result.append(("Certificate with '{}' will expire in '{}'").format(cnstr,difference)) # to display output when testing the script in the lambda section.
                resulthtml.append(("<td>'{}'</td><td>'{}'</td><td>'{}'</td><td>'{}'</td></tr>").format(output_word[9],output_word[1],cnstr,Days)) # for the HTML email to be sent.
            resulthtml.append('</table></body></html>')
        except:
            print("some errors encountered")
        for i in result: # prints the result in the testing window in the Lambda console
            print(i)
    myhtmllist = str(''.join(resulthtml)) # converts all the resulthtml into string to be used in Email.
    myhtmllist = myhtmllist.replace("'","") #removes the "'" from the data.
    textbody="this is a text body default"
    sender = "syed.naqvi@kloud.com.au"
    recipient = "syed.naqvi@kloud.com.au"
    awsregion = "us-east-1"
    subject = "Certificate Update list"
    charset = "UTF-8"
    client = boto3.client('ses',region_name=awsregion)
    try:
        response = client.send_email(
           Destination={
               'ToAddresses': [
                   recipient,
                ],
            },
         Message={
                  'Body': {
                      'Html': {
                        'Charset': charset,
                        'Data': myhtmllist,
                             },
                    'Text': {
                     'Charset': charset,
                     'Data': mylist,
                    },
                },
                'Subject': {
                    'Charset': charset,
                    'Data': subject,
                },
            },
            Source=sender,
        )
    # Display an error if something goes wrong.
    except Exception as e:
        print( "Error: ", e)
    else:
       print("Email sent!")

 4.1 AWS IAM Roles
Roles will be used to grant

  • AWS S3 write access to all the EC2 instances as they will submit the output of the PowerShell script in the S3 bucket
  • AWS SES access to Lambda Functions to send emails to relevant recipients.

4.2 AWS SES

Amazon Simple Email Service (Amazon SES) evolved from the email platform that Amazon.com created to communicate with its own customers. In order to serve its ever-growing global customer base, Amazon.com needed to build an email platform that was flexible, scalable, reliable, and cost-effective. Amazon SES is the result of years of Amazon’s own research, development, and iteration in the areas of sending and receiving email.( Ref. From https://aws.amazon.com/ses/).
We would be utilizing AWS SES to generate emails using AWS lambda.
The configuration of the Lambda functions can be modified to send emails to a distribution group to provide Certificate reporting, or it can be used to send emails to ticketing rsystem in order to provide alerting and ticket creation in case a certificate expiration date crosses a configured threshold.

5. Solution Work Flow

Mentioned below is the workflow for the tasks.
workflow

6Solution Configuration

6.1 Configure IAM Roles

The following Roles should be configured

  • IAM role for Lambda Function.
  • IAM for EC2 instances for S3 bucket Access

6.1.1 Role for Lambda Function

Lambda function need the following access

  • Read data from the S3 bucket
  • Send Emails using Amazon S3

To accomplish the above the following policy should be created and attached to the IAM Role

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1501474857000",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::S3BucketName/*"
            ]
        },
        {
            "Sid": "Stmt1501474895000",
            "Effect": "Allow",
            "Action": [
                "ses:SendEmail"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

6.1.2  Role for EC2 instance

All EC2 instances should have access to store the PowerShell output in the S3 bucket.
To accomplish the above , the following policy should be assigned to the EC2 roles

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1501475224000",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::CertificateMaintenance"
            ]
        }
    ]
}

6.2 Configure Maintenance Window.

The following tasks need to be performed for the maintenance window

  • Register a Run Command with Run-PowerShell Script using the script in section 4.1
  • Register targets based on the requirements
  • Select the schedule based on your requirement

Maintenance Window Ref : 
http://docs.aws.amazon.com/systems-manager/latest/userguide/what-is-systems-manager.html

6.3 Configure Lambda Function:

The following tasks need to be performed for the Lambda Function

  • Create a blank lambda function with the S3 put event as the triggerlambda function
  • Click on Next
  • Enter the Name and Description
  • Select run time Python 3.6
  • Copy and paste the lambda function mentioned in section 4.3

6.4 Configuring AWS SES

The following tasks need to be completed before the execution of the Run-commands.

  • Email Addresses should be added to the AWS SES section of the tenant.
  • The email addresses should be verified.

 7. Result:

Based on the above configuration, whenever the run command is executed, the following report is generated and sent to the nominated email account.
report

8. Next Steps:

We can modify the script to only report on Certificate expiring in 45 days or less.
We can also use SNS instead of SES to send out SMS to relevant teams as well.
That will be catered in another blog

Code Management in Serverless Computing – AWS Lambda and Azure Functions

In the Serverless world, we don’t need to setup server. We just take care of codes (called functions). However, one of the major drawbacks of the current FaaS (Function as a Service) providers in the Serverless world is they support lack of code management features. In this post, we’ll compare both AWS Lambda (Lambda) and Azure Functions (Functions) in regards to the source code management.

AWS Lambda

Lambda doesn’t natively support code management. We can do version management by uploading a .zip file as an artifact.

However, this is not an option from a DevOps perspective because we should manually upload the artifact. Web editor doesn’t store any change history. So, what should we do for Lambda? Fortunately, there a nice open-source tool called Apex. Apex claims that it helps us manage codes for testing and deployment. Sounds awesome, doesn’t it? Let’s have a look.

AWS CLI

In order to use Apex we should have AWS CLI installed on our local machine (and build server, too). Take an appropriate installation method based on our OS (let’s say Windows in this context). Once we install AWS CLI, then we can check if it’s properly installed by typing command like:

Now, we’ve got AWS CLI installed on our dev box. Let’s configure my AWS settings. Type aws configure and enter AWS Access Key ID, AWS Secret Access Key, Default region name and Default output format like:

We’re ready for Apex. Let’s move on.

Apex

Apex is platform-agnostic. Its binary can be downloaded from their repository. Make sure once download a binary, rename it to apex for your convenience (of course you can use its original name, if you prefer to do so). Then run the following command:

By giving a project name and description, Apex is ready for deploy.

After running apex init, several files and folders are generated.

Run the following command:

Now, we have a Lambda function deployed to AWS.

Note that deployed functions through Apex cannot be modified directly on the web as it’s zipped and uploaded by Apex.

We have looked how Apex sets up and deploys functions to Lambda. Now, we just simply type git init and push this to our build server. From now on, we can manage our code history.

Azure Functions

Managing codes in Functions is far much easier than how it is done in Lambda, with being helped by Apex. Functions natively supports git, so we can simply take the repository URL from Azure Portal and use it.

If we choose Local Git Repository, access details will be automatically displayed on the display panel.

With this git access details, we can integrate our build server to manage code change history.

Note that deployed functions through git cannot be modified directly on the web.

So far, we’ve briefly looked at both AWS Lambda and Azure Functions with regards to the code change management. Serverless is surely an attractive and emerging technology, so it would be worth watching how it grows up.

Building .NET Core Application on Amazon Linux

In order to run .NET applications on Linux operating systems, Mono used to be the only option. Now, Microsoft has released .NET Core that can build and run .NET applications on any OS including Windows, OSX and Linux. In this post, we are going to install both .NET Core Framework RC1 and RC2, build and run a simple Hello World application, and compare RC1 to RC2.

Installing .NET Core RC1

By following the official document, Installing ASP.NET 5 On Linux, we can install .NET Core Framework onto Amazon Linux, which is a variation of RHEL/CentOS. In addition to this, we have to install Mono to run DNX because, in RC1, .NET Core only supports full framework like Mono.

However, the official document from Mono doesn’t work well on Amazon Linux. When we follow the steps, we’re facing the dependency error:

This needs to be sorted out before installing Mono. This post describes steps to install the missing dependencies on Amazon Linux. Once we install dependencies, then Mono can be easily installed.

Now, we’ve got Mono installed, and DNVM, DNU and DNX installed onto Amazon Linux. Then clone the following repository and run the console application sample.

There is a very high chance that our Amazon Linux VM doesn’t have git installed. In this case, before cloning the repo, git should be installed first. Then build and run it like:

Once we successfully run the code, we’ll be able to see like:

.NET Core also provides an interesting option, called --native. This enables developers to build an OS specific native binaries. With this native binaries, we can run that natively compiled binary on another Amazon Linux without .NET Core being installed. Follow the code bits and we should be able to see the natively compiled binaries.

However, we see a disappointing result back like:

Because we cannot install .NET Core CLR onto Amazon Linux, this native build is not possible.

Installing .NET Core RC2

Releasing .NET Core RC2 makes Amazon Linux build and run .NET Core applications with Core CLR runtime. Mono is not required any longer. Follow the official document to install .NET Core on Amazon Linux. Again, Amazon Linux is a variation of RHEL/CentOS so we can use their instructions.

Once installation is complete, run the sample Hello World app from the instruction and we’ll be able to see the screen like:

How about the --native option in RC2?

When we check this option on either dotnet build or dotnet publish, we can’t find it. According to the issue on the GitHub repository, the --native option was excluded. Microsoft is planning to put this option back after the 1.0 official release.

Why Is the --native Option Important?

Now, we might have a question.

Why is the --native option important to us?

Actually, running .NET Core applications itself, there is no problem at all, with/without the option. However, there is a clear requirement to use native binary. For example, if we want to use our own binaries with AWS Lambda, that native binary build option should be necessary. We hope this option is coming back sooner or later.

Follow Us!

Kloud Solutions Blog - Follow Us!