Developing lambdas - AWS SAM with VSCode and Linux

From EnigmaGuy Wiki
Revision as of 13:28, 21 July 2020 by Enigmaguy (talk | contribs)
Jump to navigation Jump to search

IN DEVELOPMENT

Developing lambdas with AWS SAM, Linux, and VS Code

Why this solution

When I first started to develop a lambda functions it was a small one. I mostly developed them from a web console and exported files which I saved into a git repository. Soon I started to work on more complex functions that contained several files, lambda layers, and connection to other services such as Amazon Aurora. Soon development in web console becomes a headache. A small window with no debugging and autocomplete facilities where on every iteration I had to export function and save into a git repository. At the end of development, I had to write the Cloudformation template, test it, and deploy it. Every small change meant exporting code, saving into a git repository, zipping files, and deploying with test stack into a cloud.

Soon I decided to try AWS SAM. It got me a little excited. I have got a code in Visual Studio Code with all functionalities like access to a git repository, Python Linter, Python debugger, autocomplete, access to local MySQL database with integrated PHPMyAdmin, and deploying an application into AWS was a matter of one click.

Why Windows VSCode with Ubuntu Linux in HyperV?

To be honest I love Linux. It is so powerful tool where you can customize everything. I worked as Linux admin for more than ten years so I feel pretty much at home. But at the same time, I hate Linux for its graphical interface and working functionality on the computer. Linux is great on the server or command line but has major shortcomings as the main operating system at desktop computer or laptop. Let's name a few - not well functioning sleep mode on laptops, sometimes trouble with a clipboard in GUI, terrible remote access in GUI (Remote Desktop in Windows is one hundred times better than VNC) and the worst - missing a large number of productivity apps (Office 365, etc...)

For the desktop I strongly prefer Windows and I changed my opinion about Microsoft since it started to support open source a lot. I have tried Windows Subsystem for Linux (WSL) and I cannot recommend it for this scenario. The trouble with WSL is not only that it is terribly slow (that does not matter so much for app development, just installing tools takes too long). The main trouble is that WSL is a container service.

That means you cannot install Docker into WSL and have to install it into Windows. You also cannot install any other service such as MySQL. For these reasons, I have decided to use HyperV with Ubuntu 20.04. I also do not recommend using VirtualBox because HyperV offers you the functionality to start your virtual machine during boot without any modifications.

And reasons for the Visual Studio Code? I love it, simply. I used to be a fan of VIM but VIM is just an editor, not a complete IDE. I found that the main benefit of Visual Studio Code lays in the number of available extensions, particularly in one I like most - Remote SSH development. It is so easy to connect your Visual Studio Code editor with Linux not mentioning you can very easily use an integrated terminal window for your Linux server in HyperV.

Let's start with installing Linux into HyperV

I prefer Ubuntu Linux. Because we are going to just use command line recommended distribution is Ubuntu Linux Server Edition 20.04. For using HyperV the Windows 10 Pro edition is needed. You can install HyperV by simply searching "Programs and Features" in START Menu and clicking on "Turn Windows Features on and off" and selecting HyperV.

Network settings

Default installation use default network. The trouble with default network in HyperV is that you are unable to connect to machine from host computer through IP. Only thing which is activated is NAT. I have tried to create only one internal network and install routing tools to Windows and route all traffic through NAT on hypervisor but the trouble was when using VPN service to company network. It just did not work. I was unable to connect to Cisco VPN. For this reason I am using two network cards, one use default HyperV NAT and second just internal network without internet access used only to access HyperV host.

When you are configuring second network adapter it is necessary to manually configure IP address. You can use any free network range, in my case I use 192.168.200.0/24 with hypervisor address 192.168.200.1 and host address 192.168.200.10. You should configure hypervisor address in network adapter settings in Windows and host IP address during Ubuntu installation (that's most convenient way).

Visual Studio Code Extensions

  • Visual Studio Code Remote - SSH: Editing Configuration Files
  • Visual Studio Code Remote - SSH
  • AWS Toolkit
  • CloudFormation Linter
  • Python

Visual Studio SSH connection

1. Install all extensions

2. Generate and save private key with Puttygen (I recommend without password, more about it later)

3. In Windows set rights more permissive

4. Import OpenSSH key to Linux - https://www.cyberciti.biz/faq/how-to-set-up-ssh-keys-on-linux-unix/

5. Set config key and connect (use icon in left down corner of Visual Studio Code)

Disable SUDO password

Add NOPASSWD for sudo group

sudo visudo
%sudo   ALL=(ALL:ALL) NOPASSWD:ALL

SSH agent for all user sessions

There are many tutorials how to make ssh agent working, one of main problems is that they are usually valid only for one bash session. This is not really usable for VS Code because every new terminal start with a new bash session and you do not want to reenter password every time.

Furthermore because you have locally stored SSH key without password to access your linux machine you should also have a real private key on your linux machine to e.g. commit changes to a GIT repository. For this purpose I have a tutorial with background SSH agent service which will run as a daemon and ssh agent will be valid for all user sessions.

/etc/rc.local

#!/bin/bash
sudo -umkonicek ssh-agent > /home/mkonicek/.ssh-agent

/etc/systemd/system/rc-local.service

[Unit]
 Description=/etc/rc.local Compatibility
 ConditionPathExists=/etc/rc.local

[Service]
 Type=forking
 ExecStart=/etc/rc.local start
 TimeoutSec=0
 StandardOutput=tty
 RemainAfterExit=yes
 SysVStartPriority=99

[Install]
 WantedBy=multi-user.target

Enable service

systemctl start rc-local
systemctl enable rc-local

~/.bashrc

. ~/.ssh-agent