<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tathagata</title>
    <description>The latest articles on DEV Community by Tathagata (@tathagata).</description>
    <link>https://dev.to/tathagata</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F131402%2F8325915c-c7b3-4cfd-90e1-e690895aa544.jpeg</url>
      <title>DEV Community: Tathagata</title>
      <link>https://dev.to/tathagata</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tathagata"/>
    <language>en</language>
    <item>
      <title>Moving your cron jobs to AWS lambda with SAM cli </title>
      <dc:creator>Tathagata</dc:creator>
      <pubDate>Sun, 31 Mar 2019 02:35:59 +0000</pubDate>
      <link>https://dev.to/tathagata/moving-your-cron-jobs-to-aws-lambdas-with-sam-cli-4k1i</link>
      <guid>https://dev.to/tathagata/moving-your-cron-jobs-to-aws-lambdas-with-sam-cli-4k1i</guid>
      <description>&lt;p&gt;Every now and then, you need to a script to run at regular interval and do something interesting. Before the advent of serverless computing, cron jobs were the defacto way of doing this. But now we have several options that are more cost effective. &lt;a href="https://docs.aws.amazon.com/AmazonECS/latest/developerguide/scheduling_tasks.html"&gt;ECS scheduled tasks&lt;/a&gt; and &lt;a href="https://aws.amazon.com/lambda/"&gt;lambdas&lt;/a&gt; are two serverless alternatives for task scheduling in AWS. Depending on your workload you can decide which option would be the right choice for you. Lambdas, with 15-minute runtime limit are ideal for small workloads. Let's explore how we can get this working.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install SAM cli
&lt;/h2&gt;

&lt;p&gt;AWS Sam cli is a tool with an adorable chipmunk as mascot. It simplifies building and deploying lambdas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--user&lt;/span&gt; aws-sam-cli
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Create a project
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;sam init &lt;span class="nt"&gt;--name&lt;/span&gt; lambda-cron &lt;span class="nt"&gt;--runtime&lt;/span&gt; python3.7
&lt;span class="o"&gt;[&lt;/span&gt;+] Initializing project structure...

Project generated: ./lambda-cron

Steps you can take next within the project folder
&lt;span class="o"&gt;===================================================&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; Invoke Function: sam &lt;span class="nb"&gt;local &lt;/span&gt;invoke HelloWorldFunction &lt;span class="nt"&gt;--event&lt;/span&gt; event.json
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; Start API Gateway locally: sam &lt;span class="nb"&gt;local &lt;/span&gt;start-api

Read lambda-cron/README.md &lt;span class="k"&gt;for &lt;/span&gt;further instructions

&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; Project initialization is now &lt;span class="nb"&gt;complete&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Lets take a look at the generated code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;tree lambda-cron/
lambda-cron/
|-- README.md
|-- event.json
|-- hello_world
|   |-- __init__.py
|   |-- __pycache__
|   |   |-- __init__.cpython-37.pyc
|   |   &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nt"&gt;--&lt;/span&gt; app.cpython-37.pyc
|   |-- app.py
|   &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nt"&gt;--&lt;/span&gt; requirements.txt
|-- template.yaml
&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nt"&gt;--&lt;/span&gt; tests
    &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nt"&gt;--&lt;/span&gt; unit
        |-- __init__.py
        |-- __pycache__
        |   |-- __init__.cpython-37.pyc
        |   &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nt"&gt;--&lt;/span&gt; test_handler.cpython-37.pyc
        &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nt"&gt;--&lt;/span&gt; test_handler.py

5 directories, 12 files
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This might seem an overkill of artifacts compared to a line in your cron tab. But if you think you are getting rid of the entire server, this doesn't look that unreasonable. Let's take a look at the non-obvious files.&lt;/p&gt;

&lt;h3&gt;
  
  
  event.json
&lt;/h3&gt;

&lt;p&gt;sam's scaffolding is targets  the most popular lambda use case - a function servicing an API gateway endpoint. We can ignore this.&lt;/p&gt;

&lt;h3&gt;
  
  
  app.py
&lt;/h3&gt;

&lt;p&gt;This file is of primary importance, as this is where your code goes. By default, &lt;code&gt;lambda_handler&lt;/code&gt; is the name of the function which you populate. For now, we will just limit it to a printing a string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Do something interesting!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  requirements.txt
&lt;/h3&gt;

&lt;p&gt;Standard stuff - your package dependencies go here.&lt;/p&gt;

&lt;h3&gt;
  
  
  template.yaml
&lt;/h3&gt;

&lt;p&gt;This file is responsible for orchestrating the serverless-ness. It declaratively specifies what components make up your &lt;code&gt;stack&lt;/code&gt;, where the stack is your entire software architecture deployed as one unit in AWS CloudFromation. If this is not magic, I don't know what is. I am a big fan of CloudFormation.&lt;/p&gt;

&lt;p&gt;Note this file was generated to build a lambda function that gets triggered by an HTTP request to the API gateway endpoint. But our goal is to run it at scheduled intervals. Take a look at the section which describes the events.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;      &lt;span class="na"&gt;Events&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;HelloWorld&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Api&lt;/span&gt; &lt;span class="c1"&gt;# More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api&lt;/span&gt;
          &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;Path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/hello&lt;/span&gt;
            &lt;span class="na"&gt;Method&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;get&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We need to replace it with the schedule information. Sam template &lt;a href="https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#schedule"&gt;supports&lt;/a&gt; schedule expression in both &lt;code&gt;cron&lt;/code&gt; syntax and a simpler &lt;code&gt;rate&lt;/code&gt; expression.&lt;/p&gt;

&lt;p&gt;Every minute using rate&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;      &lt;span class="na"&gt;Events&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;HelloWorld&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Schedule&lt;/span&gt;
          &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;Schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rate(1 minute)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Every minute using cron&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;      &lt;span class="na"&gt;Events&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;HelloWorld&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Schedule&lt;/span&gt;
          &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;Schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cron(1 * * * ? *)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  test_handler.py
&lt;/h3&gt;

&lt;p&gt;This is pre-generated unittest stubs for pytest. You can install pytest (&lt;code&gt;pip install pytest&lt;/code&gt;) and run &lt;code&gt;pytest&lt;/code&gt; like usual.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build
&lt;/h2&gt;

&lt;p&gt;With your tests passing, it is now time to do the builds&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;lambda-cron/
t lambda-cron &lt;span class="nv"&gt;$ &lt;/span&gt;sam build &lt;span class="nt"&gt;--use-container&lt;/span&gt;
2019-03-30 19:42:24 Starting Build inside a container
2019-03-30 19:42:24 Building resource &lt;span class="s1"&gt;'HelloWorldFunction'&lt;/span&gt;

Fetching lambci/lambda:build-python3.7 Docker container image......
2019-03-30 19:42:25 Mounting /Users/t/projects/python/playground/lambda-deep-dive/lambda-cron/hello_world as /tmp/samcli/source:ro inside runtime container

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
&lt;span class="o"&gt;=========================&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; Invoke Function: sam &lt;span class="nb"&gt;local &lt;/span&gt;invoke
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; Package: sam package &lt;span class="nt"&gt;--s3-bucket&lt;/span&gt; &amp;lt;yourbucket&amp;gt;

Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note the first time you run this, it will download the docker image it needs for running.&lt;/p&gt;

&lt;h2&gt;
  
  
  Local testing
&lt;/h2&gt;

&lt;p&gt;One of the best functionality that sam offers is the ability to test your code locally in a docker container. This makes quick iteration possible without having to acutally deploy on AWS lambda environment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;sam &lt;span class="nb"&gt;local &lt;/span&gt;invoke &lt;span class="nt"&gt;--no-event&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; template.yaml
2019-03-30 21:01:43 Found credentials &lt;span class="k"&gt;in &lt;/span&gt;shared credentials file: ~/.aws/credentials
2019-03-30 21:01:43 Invoking app.lambda_handler &lt;span class="o"&gt;(&lt;/span&gt;python3.7&lt;span class="o"&gt;)&lt;/span&gt;

Fetching lambci/lambda:python3.7 Docker container image....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
2019-03-30 21:02:53 Mounting /Users/t/projects/python/playground/lambda-deep-dive/lambda-cron/hello_world as /var/task:ro inside runtime container
START RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72 Version: &lt;span class="nv"&gt;$LATEST&lt;/span&gt;
Do something intersting!
END RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72
REPORT RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72  Duration: 16.52 ms  Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 22 MB
null
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Package your code
&lt;/h2&gt;

&lt;p&gt;Let's create a bucket and pass it to the packaging command. Note we are passing a file called packaged.yaml which is the generated cloud formation template that we will be using in the next command to deploy it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3 mb s3://lambda-cron-bucket
sam package &lt;span class="nt"&gt;--s3-bucket&lt;/span&gt; lambda-cron-bucket &lt;span class="nt"&gt;--output-template-file&lt;/span&gt; packaged.yaml

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Deploy
&lt;/h2&gt;

&lt;p&gt;Finally deploy your cron job. You'll need to provide a name for your stack and tell cloudformation explicitly that you are ok with the creation of IAM related resources by passing the &lt;code&gt;CAPABILITY_IAM&lt;/code&gt; flag.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;aws cloudformation deploy &lt;span class="nt"&gt;--template-file&lt;/span&gt; /absolute/path/packaged.yaml &lt;span class="nt"&gt;--stack-name&lt;/span&gt; lambda-cron &lt;span class="nt"&gt;--capabilities&lt;/span&gt; CAPABILITY_IAM
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Validate
&lt;/h2&gt;

&lt;p&gt;Lets take a look if our cron is executing every minute.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;sam logs &lt;span class="nt"&gt;-n&lt;/span&gt; HelloWorldFunction &lt;span class="nt"&gt;--stack-name&lt;/span&gt; lambda-cron &lt;span class="nt"&gt;--tail&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You should see something like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;2019-03-30 20:35:19 Found credentials &lt;span class="k"&gt;in &lt;/span&gt;shared credentials file: ~/.aws/credentials
2019/03/31/[&lt;span class="nv"&gt;$LATEST&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;7cc1e71b6eb14c89881cb91d6c29b920 2019-03-31T01:29:12.613000 START RequestId: c2c8a898-dfab-450f-944b-d43d77741c35 Version: &lt;span class="nv"&gt;$LATEST&lt;/span&gt;
2019/03/31/[&lt;span class="nv"&gt;$LATEST&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;7cc1e71b6eb14c89881cb91d6c29b920 2019-03-31T01:29:12.618000 Do something intersting!
2019/03/31/[&lt;span class="nv"&gt;$LATEST&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;7cc1e71b6eb14c89881cb91d6c29b920 2019-03-31T01:29:12.638000 END RequestId: c2c8a898-dfab-450f-944b-d43d77741c35
2019/03/31/[&lt;span class="nv"&gt;$LATEST&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;7cc1e71b6eb14c89881cb91d6c29b920 2019-03-31T01:29:12.638000 REPORT RequestId: c2c8a898-dfab-450f-944b-d43d77741c35  Duration: 24.83 ms  Billed Duration: 100 ms     Memory Size: 128 MB Max Memory Used: 63 MB
2019/03/31/[&lt;span class="nv"&gt;$LATEST&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;7cc1e71b6eb14c89881cb91d6c29b920 2019-03-31T01:30:12.272000 START RequestId: 93645e34-850b-47b0-a4a3-00d10e502057 Version: &lt;span class="nv"&gt;$LATEST&lt;/span&gt;
2019/03/31/[&lt;span class="nv"&gt;$LATEST&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;7cc1e71b6eb14c89881cb91d6c29b920 2019-03-31T01:30:12.278000 Do something intersting!
2019/03/31/[&lt;span class="nv"&gt;$LATEST&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;7cc1e71b6eb14c89881cb91d6c29b920 2019-03-31T01:30:12.298000 END 
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Congratulations on your first serverless cron job!&lt;/p&gt;

&lt;h2&gt;
  
  
  What's with the cover picture?
&lt;/h2&gt;

&lt;p&gt;Keeping with the theme of my other dev.to posts, it has nothing to do with the post. It's view of our beautiful city, Chicago, from my balcony.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>lambdas</category>
      <category>cron</category>
    </item>
    <item>
      <title>Raspberry Pi on your TV</title>
      <dc:creator>Tathagata</dc:creator>
      <pubDate>Sat, 09 Feb 2019 17:42:35 +0000</pubDate>
      <link>https://dev.to/tathagata/raspberry-pi-on-your-tv-2kl6</link>
      <guid>https://dev.to/tathagata/raspberry-pi-on-your-tv-2kl6</guid>
      <description>&lt;p&gt;I had a raspberry pi that was gathering dust for a few months. Earlier last month I hooked it up to a usb keyboard, mouse and a monitor and got the WiFi set up. But with all the messy wires and the dedicated real estate for the screen, it defeated the purpose of being a pocket size computer. &lt;br&gt;
Last weekend I finally got it to a setup that I am happy with. Optional bluetooth keyboard and mouse, so no messy wires.&lt;/p&gt;
&lt;h3&gt;
  
  
  Using the TV as a monitor
&lt;/h3&gt;

&lt;p&gt;The idiot box is a vice of mine that sucks up all the productive time. Since it has a dedicated place already in my living room already, plugged it to the TV. So fun that I have a linux machine hidden behind all the trinkets on TV cabinet!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fwsm472onfe8sneswehcy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fwsm472onfe8sneswehcy.jpg" alt="pi tv"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A small settings change was needed so that I can instantly switch over to the pi when I turn on my TV or switch over from other HDMI inputs. Edit the lightdm configuration &lt;code&gt;/etc/lightdm/lightdm.conf&lt;/code&gt; as root and uncomment the line &lt;code&gt;xserver-command=X&lt;/code&gt; to &lt;code&gt;xserver-command=X -s 0 dpms&lt;/code&gt;. Save and &lt;code&gt;reboot&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Phone Apps to replace mouse and keyboard
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Terminal emulator
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://www.termius.com/" rel="noopener noreferrer"&gt;Termius&lt;/a&gt; - A beautiful terminal emulator that is fast, feature packed and best of all - free for my purposes. Just install, connect to the raspberry pi’s up address and boom you are on the shell. It amazes me how beautifully the ncurses screens renders on Termius!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fz2gvvi6vaudueme80gjw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fz2gvvi6vaudueme80gjw.jpg" alt="drawing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Side note: &lt;a href="https://www.fing.com/" rel="noopener noreferrer"&gt;Fing&lt;/a&gt; is a nice little app to find the up addresses of devices on your network.&lt;/p&gt;
&lt;h4&gt;
  
  
  GUI access with Phone/Ipad
&lt;/h4&gt;

&lt;p&gt;Install &lt;a href="https://www.realvnc.com/en/connect/download/viewer/" rel="noopener noreferrer"&gt;VNC Viewer&lt;/a&gt; on your iPhone or iPad. On the pi, install realvnc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get update 
sudo apt-get install realvnc-vnc-server
reboot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After rebooting &lt;code&gt;sudo raspi-config&lt;/code&gt; &amp;gt; &lt;em&gt;Advanced Options&lt;/em&gt; &amp;gt; &lt;em&gt;VNC&lt;/em&gt; Enable. 👍&lt;/p&gt;

&lt;p&gt;That’s it! You a running Linux desktop on your TV that you can use with your phone or tablet. So theoretically, I can go from Netflix n chill to a linux desktop, with the flick of a button on the remote.&lt;/p&gt;

&lt;h3&gt;
  
  
  (Optional) Bluetooth Keyboard &amp;amp; Mouse
&lt;/h3&gt;

&lt;p&gt;While realVNC works better than I expected from the free app, it wouldn't be bad to throw in a bluetooth keyboard and mouse to the mix. My Magic Keyboard and Mouse are small and wireless - would probably be useful at times.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo bluetoothctl
scan on
connect ma:ca:dd:re:ss:00
pair ma:ca:dd:re:ss:00 
remove ma:ca:dd:re:ss:00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fcumy1ii7rmbqp3xafwi2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fcumy1ii7rmbqp3xafwi2.jpg" alt="mousenkeyboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tip: Here's how to find the mac address of your bluetooth device, if you have them connected to your mac: click on the apple menu , hold down option key, click on System information and click on Bluetooth.&lt;/p&gt;

&lt;h4&gt;
  
  
  Wait. What does the cover picture have to do with this post?
&lt;/h4&gt;

&lt;p&gt;Not a single thing. This is a picture I took at Sorrento. ❤️ Italy, can't wait to go back!&lt;/p&gt;

</description>
      <category>raspberrypi</category>
    </item>
    <item>
      <title>Ecto drop Postgres database on AWS RDS</title>
      <dc:creator>Tathagata</dc:creator>
      <pubDate>Thu, 24 Jan 2019 06:59:03 +0000</pubDate>
      <link>https://dev.to/tathagata/ecto-drop-postgres-database-on-aws-rds-17gn</link>
      <guid>https://dev.to/tathagata/ecto-drop-postgres-database-on-aws-rds-17gn</guid>
      <description>&lt;p&gt;Lets say during your development cycles, you have screwed your postgres database and the easiest way to get out of the mess is to drop the database and restart fresh. In this example we will look at a &lt;a href="https://phoenixframework.org/"&gt;Phoenix&lt;/a&gt; project that uses a Postgres database.&lt;/p&gt;

&lt;h3&gt;
  
  
  Warning
&lt;/h3&gt;

&lt;p&gt;To make it clear, dropping the database is a bad idea if you haven't taken snapshots. Dropping deletes all data; so do it only in non-prod.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem: Dropping a database fails due to immortal rdsadmin
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mix do ecto.drop, ecto.create, ecto.migrate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This nicely works on your local postgres instance.&lt;br&gt;
However, if the database is on AWS RDS, you'll be greeted by this interesting message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mix ecto.drop
** (Mix) The database for SuperPetStore.Repo couldn't be dropped, reason given: ERROR:  55006: database "petdb" is being accessed by other users
DETAIL:  There is 1 other session using the database.
LOCATION:  dropdb, dbcommands.c:840
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you look at the number of connections&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; select * from pg_stat_activity;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Sure enough, there will be one persistent connection from &lt;code&gt;rdsadmin&lt;/code&gt;. It is AWS RDS user that takes care of backup, updates and maintenance. This connection gets in the way of dropping the db and starting afresh.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; use postgres;
You are now connected to database "postgres" as user "petuser"
Time: 0.078s
postgres&amp;gt; drop database petdb;
You're about to run a destructive command.
Do you want to proceed? (y/n): y
Your call!
database "petdb" is being accessed by other users
DETAIL:  There is 1 other session using the database.

Time: 5.031s (5 seconds), executed in: 5.030s (5 seconds)
postgres&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  pg_terminate_backend
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;select pg_terminate_backend(pid) from pg_stat_activity where datname='petdb';drop database pipeops;
You're about to run a destructive command.
Do you want to proceed? (y/n): y
Your call!
+------------------------+
| pg_terminate_backend   |
|------------------------|
| True                   |
+------------------------+
SELECT 1
DROP DATABASE
Time: 0.118s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;First &lt;code&gt;pg_terminate_backend&lt;/code&gt; allows you to terminate the &lt;code&gt;rdsadmin&lt;/code&gt; account and shoving in the &lt;code&gt;drop&lt;/code&gt; statement in the same line gets the job done before &lt;code&gt;rdsadmin&lt;/code&gt; spawns up and connects to &lt;code&gt;petdb&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With the database gone, you can now run ecto to create the db afresh!&lt;/p&gt;

&lt;h3&gt;
  
  
  Wait. What does the picture above have to do with this post?
&lt;/h3&gt;

&lt;p&gt;Not a single thing. This is a picture I took at Siena. ❤️ Italy, can't wait to go back! &lt;/p&gt;

</description>
      <category>aws</category>
      <category>elixir</category>
      <category>ecto</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Docker cross repository push</title>
      <dc:creator>Tathagata</dc:creator>
      <pubDate>Thu, 24 Jan 2019 05:38:10 +0000</pubDate>
      <link>https://dev.to/tathagata/docker-cross-repository-push-4pkn</link>
      <guid>https://dev.to/tathagata/docker-cross-repository-push-4pkn</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Faes0ixj8nlw39n6p9ibv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Faes0ixj8nlw39n6p9ibv.jpg" alt="header"&gt;&lt;/a&gt;&lt;br&gt;
I just found dev.to and immediately fell in love with the retro 🤣 look! Instead of putting in much thought, I started brain dumping - mainly about things that did not work on the first go. No effort has been made to be helpful - typos, errors, misinformation  may lay ahead. Welcome to the Internet!&lt;/p&gt;
&lt;h3&gt;
  
  
  Problem: Need to push a docker image from one AWS account to another
&lt;/h3&gt;

&lt;p&gt;ECR is the docker repository as a service provided by AWS. To have better separation of your environment, you would typically have a prod account and one or more non-prod accounts. Your CI pipeline would be running in your non-prod account allowing you to rapidly iterate and build new images. Once your testing cycle completes, you would want to promote this image to the production account. Below are the set of commands needed to promote your release candidate from non-prod to production.&lt;/p&gt;
&lt;h4&gt;
  
  
  Login to your docker registry of source account
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws ecr --profile dev --region us-east-1 get-login --no-include-email | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Pretty straight forward. Make a cli call which returns the &lt;code&gt;docker login&lt;/code&gt; command which is piped to execute in bash. &lt;code&gt;dev&lt;/code&gt; is the aws profile for the account which contains the docker image.&lt;/p&gt;
&lt;h4&gt;
  
  
  CI produced docker image
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker pull 123456789012.dkr.ecr.us-east-1.amazonaws.com/img:aa567e02ae7477a6b022da30fa50137a252dd143
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In 123456789012.dkr.ecr.us-east-1.amazonaws.com, &lt;code&gt;123456789012&lt;/code&gt; stands for the account number of aws account where our docker image lives.&lt;br&gt;
Lets say you have done your testing and you are now satisfied to promote this to prod.&lt;/p&gt;
&lt;h4&gt;
  
  
  Switch repository and try to push
&lt;/h4&gt;

&lt;p&gt;Login to prod&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws ecr --profile prod --region eu-west-1 get-login --no-include-email | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try to push&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker push 234567890121.dkr.ecr.us-east-1.amazonaws.com/img:ab77ad7b362d7552bc2c7a69f2650a5b50bcdcc1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And ...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The push refers to repository [234567890121.dkr.ecr.us-east-1.amazonaws.com/img]
tag does not exist: 234567890121.dkr.ecr.us-east-1.amazonaws.com/img:aa567e02ae7477a6b022da30fa50137a252dd143
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Uh oh forgot to tag
&lt;/h4&gt;

&lt;p&gt;This was not very obvious to me. But docker, awesome as it is, gives you the nice error message above telling exactly where things are going wrong. To push to the prod registry, you'll need to tag the image accordingly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker tag 123456789012.dkr.ecr.us-east-1.amazonaws.com/img:aa567e02ae7477a6b022da30fa50137a252dd143 234567890121.dkr.ecr.us-east-1.amazonaws.com/img:aa567e02ae7477a6b022da30fa50137a252dd143
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Push away
&lt;/h4&gt;

&lt;p&gt;Finally push the image and you are done.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker push 234567890121.dkr.ecr.us-east-1.amazonaws.com/img:ab77ad7b362d7552bc2c7a69f2650a5b50bcdcc1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations, you have promoted the image!&lt;/p&gt;

&lt;h4&gt;
  
  
  Wait. What does the picture above got to do with this post?
&lt;/h4&gt;

&lt;p&gt;Not a single thing. This is a picture I took at &lt;a href="https://en.wikipedia.org/wiki/Siena" rel="noopener noreferrer"&gt;Siena&lt;/a&gt;. ❤️Italy, can't wait to go back!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>aws</category>
      <category>ecr</category>
    </item>
  </channel>
</rss>
