<?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: Hai Tran</title>
    <description>The latest articles on DEV Community by Hai Tran (@entest).</description>
    <link>https://dev.to/entest</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%2F813854%2F41f04e8f-4572-4d8f-b656-f3ef5d142504.jpeg</url>
      <title>DEV Community: Hai Tran</title>
      <link>https://dev.to/entest</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/entest"/>
    <language>en</language>
    <item>
      <title>Setup VSCode SSH with Cloud9 using CDK</title>
      <dc:creator>Hai Tran</dc:creator>
      <pubDate>Wed, 27 Apr 2022 14:50:43 +0000</pubDate>
      <link>https://dev.to/entest/setup-vscode-ssh-with-cloud9-using-cdk-3h9k</link>
      <guid>https://dev.to/entest/setup-vscode-ssh-with-cloud9-using-cdk-3h9k</guid>
      <description>&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;There are some benefit when using Cloud9, here is the &lt;a href="https://aws.amazon.com/blogs/architecture/field-notes-use-aws-cloud9-to-power-your-visual-studio-code-ide/"&gt;aws blog vscode cloud9&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Auto hibernate after 30 minutes idle&lt;/li&gt;
&lt;li&gt;Auto turn on when open vscode&lt;/li&gt;
&lt;li&gt;No open port
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--b8omg3Cf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/20411077/165545940-4ddcdfb7-2d39-431c-a47f-288dc12a4e1e.jpg" alt="aws_devops-Expriment (1)" width="880" height="436"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  CDK stack to create a cloud9 environment
&lt;/h3&gt;

&lt;p&gt;There are multiple way to launch a cloud9 such as AWS console, CLI, CloudFormation, I go with a CDK stack as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { aws_cloud9, Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class Cloud9CdkStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    // cloud9 environment
    const cloud9 = new aws_cloud9.CfnEnvironmentEC2(
      this,
      'CdkCloud9Example',
      {
        automaticStopTimeMinutes: 30,
        instanceType: 't2.large',
        name: 'CdkCloud9Example',
        connectionType: 'CONNECT_SSM',
        ownerArn: `arn:aws:iam::${this.account}:user/YOUR_IAM_USER_NAME`
      }
    )

    // access the ec2 and attach volume

  }
}

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configure ssh for the local machine
&lt;/h3&gt;

&lt;p&gt;Generate ssh private and public key&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh-keygen -b 4096 -C 'VS Code Remote SSH user' -t rsa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the public key from the local machine&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat ~/.ssh/id_rsa.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Paste the key to authorized_keys in ec2 instance&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo 'key pub' &amp;gt;&amp;gt; authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure ssh config for the local machine&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Host cloud9
    IdentityFile ~/.ssh/id_rsa_cloud9
    User ec2-user
    HostName INSTANCE_ID
    ProxyCommand sh -c "~/.ssh/ssm-proxy.sh %h %p"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Download the &lt;a href="https://github.com/aws-samples/cloud9-to-power-vscode-blog/blob/main/scripts/ssm-proxy.sh"&gt;ssm-proxy script from here&lt;/a&gt;.It will check it the Cloud9-EC2 is running or not.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If the EC2 running, it starts a ssm session and ssh tunnel via the session.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the EC2 is stopped, it will start the instance first, then start the ssm session and tunnel ssh.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; chmod +x ~/.ssh/ssm-proxy.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Setup vscode ssh remote to a private EC2 instance via ssm</title>
      <dc:creator>Hai Tran</dc:creator>
      <pubDate>Tue, 26 Apr 2022 13:46:34 +0000</pubDate>
      <link>https://dev.to/entest/setup-vscode-ssh-remote-to-a-private-ec2-instance-via-ssm-dm7</link>
      <guid>https://dev.to/entest/setup-vscode-ssh-remote-to-a-private-ec2-instance-via-ssm-dm7</guid>
      <description>&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With AWS system manager (SSM), it is possible to setup vscode ssh remote to a EC2 in a private subnet, and without open 22 port. &lt;a href="https://github.com/entest-hai/vscode-ssh-ssm-ec2" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setup a connection to a private EC2 via SSM&lt;/li&gt;
&lt;li&gt;Setup vscode ssh remote to the EC2 by proxyCommand&lt;/li&gt;
&lt;li&gt;Create the infrastructure by a CDK stack&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/architecture/field-notes-use-aws-cloud9-to-power-your-visual-studio-code-ide/" rel="noopener noreferrer"&gt;vscode cloud9 setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/setup-create-vpc.html" rel="noopener noreferrer"&gt;SSM VPC endpoint&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/cli/latest/reference/ssm/start-session.html" rel="noopener noreferrer"&gt;aws ssm start-session&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Architecture
&lt;/h3&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%2Fuser-images.githubusercontent.com%2F20411077%2F165264406-14a840a7-af5b-47e1-a5fe-7b32018ae996.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%2Fuser-images.githubusercontent.com%2F20411077%2F165264406-14a840a7-af5b-47e1-a5fe-7b32018ae996.jpg" alt="aws_devops-Expriment"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  CDK Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;create a VPC with a S3 VPC endpoint&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

    const vpc = new aws_ec2.Vpc(
      this,
      'VpcWithS3Endpoint',
      {
        gatewayEndpoints: {
          S3: {
            service: aws_ec2.GatewayVpcEndpointAwsService.S3
          }
        }
      }
    )


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

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;add system manager VPC interface endpoint&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

    vpc.addInterfaceEndpoint(
      'VpcIterfaceEndpointSSM',
      {
        service: aws_ec2.InterfaceVpcEndpointAwsService.SSM
      }
    )


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

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;create an IAM role for the EC2&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

    const role = new aws_iam.Role(
      this,
      'RoleForEc2ToAccessS3',
      {
        roleName: 'RoleForEc2ToAccessS3',
        assumedBy: new aws_iam.ServicePrincipal('ec2.amazonaws.com'),
      }
    )


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

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;role for EC2 to communicate with SSM&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

    role.addManagedPolicy(
      aws_iam.ManagedPolicy.fromManagedPolicyArn(
        this,
        'PolicySSMMangerAccessS3',
        'arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore'
      )
    )


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

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;policy for EC2 to access S3&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

    role.attachInlinePolicy(
      new aws_iam.Policy(
        this,
        'PolicyForEc2AccessS3',
        {
          policyName: 'PolicyForEc2AccessS3',
          statements: [
            new aws_iam.PolicyStatement(
              {
                actions: ['s3:*'],
                resources: ['*']
              }
            ),
          ]
        }
      )
    )



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

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;launch an EC2 in a private subnet&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

    const ec2 = new aws_ec2.Instance(
      this,
      'Ec2ConnectVpcEndpointS3',
      {
        role: role,
        keyName: 'hai_ec2_t4g_large',
        vpc: vpc,
        instanceName: 'Ec2ConnectVpcEndpointS3',
        instanceType: aws_ec2.InstanceType.of(aws_ec2.InstanceClass.T2, aws_ec2.InstanceSize.SMALL),
        machineImage: aws_ec2.MachineImage.latestAmazonLinux(),
        securityGroup: sg,
        vpcSubnets: {
          subnetType: aws_ec2.SubnetType.PRIVATE
        }
      }
    )


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Setup a connection to private EC2 via SSM
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html" rel="noopener noreferrer"&gt;follow this to&lt;/a&gt; install ssm plugin for the local machine&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;start a ssm session from the local machine&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

aws ssm start-session --target "EC2-INSTANCE-ID"


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Setup vscode ssh remote to the EC2
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh" rel="noopener noreferrer"&gt;follow this to &lt;/a&gt;nstall ssh remote extension for vscode&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;generate SSH key pair from the local machine&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

ssh-keygen -b 4096 -C 'VS Code Remote SSH user' -t rsa



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

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;configure the ~/.ssh/config file&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Host ssm-private-ec2
  IdentityFile ~/.ssh/id_rsa
  HostName i-026bb5f5caaf16aa1
  User ec2-user
  ProxyCommand sh -c "~/.ssh/ssm-private-ec2-proxy.sh %h %p"


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

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;create a ssm-private-ec2-proxy.sh file&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#!/bin/bash

AWS_PROFILE=''
AWS_REGION=''
MAX_ITERATION=5
SLEEP_DURATION=5

# Arguments passed from SSH client
HOST=$1
PORT=$2

echo $HOST

# Start ssm session
aws ssm start-session --target $HOST \
  --document-name AWS-StartSSHSession \
  --parameters portNumber=${PORT} \
  --profile ${AWS_PROFILE} \
  --region ${AWS_REGION}


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

&lt;/div&gt;

&lt;p&gt;vscode will create a ssh connection to the EC2 via the &lt;strong&gt;ProxyCommand&lt;/strong&gt; script which creates a SSM session under the hood. This is the way &lt;a href="https://aws.amazon.com/blogs/architecture/field-notes-use-aws-cloud9-to-power-your-visual-studio-code-ide/" rel="noopener noreferrer"&gt;vscode ssh remote with cloud9 works&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>AWS IoT Demo with CDK and Amplify</title>
      <dc:creator>Hai Tran</dc:creator>
      <pubDate>Fri, 15 Apr 2022 04:54:59 +0000</pubDate>
      <link>https://dev.to/entest/aws-iot-demo-with-cdk-and-amplify-1i69</link>
      <guid>https://dev.to/entest/aws-iot-demo-with-cdk-and-amplify-1i69</guid>
      <description>&lt;h2&gt;
  
  
  Architecture
&lt;/h2&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%2Fuser-images.githubusercontent.com%2F20411077%2F163437200-3690b0c2-b3de-4257-a54c-995a6de32ada.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%2Fuser-images.githubusercontent.com%2F20411077%2F163437200-3690b0c2-b3de-4257-a54c-995a6de32ada.jpg" alt="aws_devops-Expriment (2)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Demo&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://master.d2s0cqpzgt11ee.amplifyapp.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;demo react web&lt;/strong&gt;&lt;/a&gt; no real-time here because we need to publish data from the test/test_pub.py&lt;/li&gt;
&lt;li&gt;&lt;a href="https://haitran-swincoffee-demo.s3.ap-southeast-1.amazonaws.com/aws-iot-cdk-amplify-demo.mp4" rel="noopener noreferrer"&gt;&lt;strong&gt;video demo&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/entest-hai/aws-iot-demo" rel="noopener noreferrer"&gt;GitHub here&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;CDK &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create an IoT thing, attach a policy to X509 certificate, then attach the cert to the IoT thing&lt;/li&gt;
&lt;li&gt;Create IoT rules to deliver data to Kinesis Firehose, DB&lt;/li&gt;
&lt;li&gt;Create a Lambda function to query from DB &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Amplify &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cognito and PubSub to subscribe to IoT topics &lt;/li&gt;
&lt;li&gt;Attach an AWS IoT policy to the Cognito ID&lt;/li&gt;
&lt;li&gt;Pre-built authentication UI (useAuthenticator)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;CharJs&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Plot and update two simple charts &lt;/li&gt;
&lt;li&gt;Chart 1. Keep pulling data from DB via an API&lt;/li&gt;
&lt;li&gt;Chart 2. Subscribe to an IoT topic&lt;/li&gt;
&lt;li&gt;Amplify to host the react app &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;IoT Thing and Certificate &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Attach a X509 certificate to the physical IoT device&lt;/li&gt;
&lt;li&gt;Attach a AWS IoT policy to the X509 ceritifcate to allow read/write AWS IoT topics&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;AWS IoT topic rules&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Attach a role to a rule to enable AWS IoT rules write to S3, Firehose, DyanmoDB &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Check AWS IoT Service Endpoint
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws iot describe-endpoint --region ap-southeast-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Download AWS CA certificate
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Download one of the CA certificate which required to configure mqtt client. &lt;a href="https://github.com/aws-samples/aws-iot-device-management-workshop/blob/master/bin/create-root-ca-bundle.sh" rel="noopener noreferrer"&gt;reference 1&lt;/a&gt; and &lt;a href="https://docs.aws.amazon.com/iot/latest/developerguide/server-authentication.html#server-authentication-certs" rel="noopener noreferrer"&gt;reference 2&lt;/a&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    https://www.amazontrust.com/repository/AmazonRootCA1.pem \
    https://www.amazontrust.com/repository/AmazonRootCA2.pem \
    https://www.amazontrust.com/repository/AmazonRootCA3.pem \
    https://www.amazontrust.com/repository/AmazonRootCA4.pem \
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;An alternative way is to create a CA certificate &lt;a href="https://docs.aws.amazon.com/iot/latest/developerguide/create-your-CA-cert.html" rel="noopener noreferrer"&gt;reference 3&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl genrsa -out root_CA_key_filename.key 2048
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl req -x509 -new -nodes \
    -key root_CA_key_filename.key \
    -sha256 -days 1024 \
    -out root_CA_cert_filename.pem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create key and certificate
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;I have to create key and certificates from CLI or AWS console. To create them from CDK, follow this custom resource &lt;a href="https://github.com/awslabs/aws-iot-greengrass-accelerators/tree/main/v2/base/cdk/lib/IotThingCertPolicy" rel="noopener noreferrer"&gt;reference 4&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws iot create-keys-and-certificate \
--set-as-active \
--certificate-pem-outfile esp-certificate.crt \
--public-key-outfile esp-public.key \
--private-key-outfile esp-private.key \
--region ap-southeast-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Take not the &lt;strong&gt;CERTIFICATE_ARN&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Re-download the certificate given its ID &lt;br&gt;
configure aws cli output as text&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws iot describe-certificate --certificate-id 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  IoT Thing, X509 Certificate, and Policy
&lt;/h2&gt;

&lt;p&gt;To allow the IoT thing can write data to AWS IoT core, we need to attach a X509 certificate the the physical IoT device. We also need to attach a policy to the X509 certificate in AWS to specify ALLOW actions. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a policy for the X509 certificate
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const policy = new aws_iot.CfnPolicy(
      this,
      'PolicyForDemoDevice',
      {
        policyName: 'PolicyForDemoDevice',
        policyDocument: new aws_iam.PolicyDocument(
          {
            statements: [
              new aws_iam.PolicyStatement(
                {
                  actions: ['iot:*'],
                  resources: ['*'],
                  effect: aws_iam.Effect.ALLOW
                }
              )
            ]
          }
        )
      }
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Attach the policy to the X509 certificate
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const attachPolicy = new aws_iot.CfnPolicyPrincipalAttachment(
      this,
      'AttachPolicyForDemoDevice',
      {
        policyName: policy.policyName!.toString(),
        principal: props.certificateArn
      }
    )

    attachPolicy.addDependsOn(
      policy
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Attach the X509 certificate to the IoT thing
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const attachCert = new aws_iot.CfnThingPrincipalAttachment(
      this,
      'AttachCertificiateToThing',
      {
        thingName: thing.thingName!.toString(),
        principal: props.certificateArn
      }
    )

    attachCert.addDependsOn(
      thing
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  IoT Rules and Role
&lt;/h2&gt;

&lt;p&gt;To allow IoT rules to delivery data to other services such as S3, DynamoDB, Firehose, we need to attach a role to each rule. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a role
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; const role = new aws_iam.Role(
      this,
      'RoleForIoTCoreToAccessS3',
      {
        roleName: 'RoleForIoTCoreToAccessS3',
        assumedBy: new aws_iam.ServicePrincipal('iot.amazonaws.com')
      }
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Attach inline policies to the role
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; role.attachInlinePolicy(
      new aws_iam.Policy(
        this,
        'PolicyForIoTcoreToAccessS3',
        {
          policyName: 'PolicyForIoTcoreToAccessS3',
          statements: [
            new aws_iam.PolicyStatement(
              {
                actions: ['s3:*'],
                resources: ['arn:aws:s3:::bucketName/*']
              }
            ),
            new aws_iam.PolicyStatement(
              {
                actions: ['firehose:*'],
                resources: ['*']
              }
            ),
            new aws_iam.PolicyStatement(
              {
                actions: ['dynamodb:*'],
                resources: ['*']
              }
            )
          ]
        }
      )
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create rules with actions and attached the role
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const topicRule = new aws_iot.CfnTopicRule(
      this,
      'TopicRuleDemo',
      {
        ruleName: 'TopicRuleDemo',
        topicRulePayload: {
          actions: [
            {
              firehose: {
                deliveryStreamName: firehoseDeilvery.deliveryStreamName,
                roleArn: role.roleArn
              }
            },
            {
              s3: {
                bucketName: 'bucketName',
                key: 'iot-one',
                roleArn: role.roleArn
              },
            },
            {
              dynamoDb: {
                hashKeyField: 'id',
                hashKeyValue: 'device01',
                hashKeyType: 'STRING',
                rangeKeyField: 'timestamp',
                rangeKeyValue: '${timestamp()}',
                rangeKeyType: 'STRING',
                roleArn: role.roleArn,
                tableName: table.tableName
              }
            }
          ],
          sql: `SELECT *, cast(timestamp() as STRING) AS timestamp FROM 'topic/subtopic'`
        }
      }
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Amplify, Cognito and AWS IoT Policy
&lt;/h2&gt;

&lt;p&gt;To allow Amplify (react web app) subscribe to an AWS IoT topic, we need to attach policy to Conigto ID. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Find the Cognito ID from the react web app as following
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Amplify, { Auth, PubSub } from 'aws-amplify';
Auth.currentCredentials().then(creds =&amp;gt; console.log(creds));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The Cognito ID can be found from the creds log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Attach AWS IoT policy to the Cognito ID as following
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws iot attach-policy --policy-name 'PolicyForDemoDevice' --target ap-southeast-1:41f19265-5ecd-4c86-8b34-cc58dee6c2f0
aws iot attach-policy --policy-name 'PolicyForDemoDevice' --target ap-southeast-1:2d1afbd5-2d7d-43ec-b906-a40ac2416c10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Remote Access Private EC2 Instances via System Manager</title>
      <dc:creator>Hai Tran</dc:creator>
      <pubDate>Sun, 10 Apr 2022 00:19:27 +0000</pubDate>
      <link>https://dev.to/entest/remote-access-private-ec2-instances-via-system-manager-42en</link>
      <guid>https://dev.to/entest/remote-access-private-ec2-instances-via-system-manager-42en</guid>
      <description>&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;System manager enable remote access to EC2 instances (both private and public subnet) without using SSH and opening port 22. In addition, from the private EC2, it is possible to access other services such as S3 via VPC service endpoints. In this post, I would like share how to deploy these by using CDK. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Remote access a prviate EC2 by system mananger&lt;/li&gt;
&lt;li&gt;The private EC2 can access S3 via VPC endpoint&lt;/li&gt;
&lt;li&gt;Deply by a CDK stack&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/entest-hai/aws-devops/tree/system-manager-vpc-endpoint"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0Zjr9iig--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/20411077/162595535-59610cf8-233c-423f-9a13-bb3f1cffacc3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0Zjr9iig--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/20411077/162595535-59610cf8-233c-423f-9a13-bb3f1cffacc3.png" alt="aws_devops-Expriment drawio" width="880" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  CDK Stack
&lt;/h2&gt;

&lt;p&gt;Create a VPC with a S3 VPC endpoint&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const vpc = new aws_ec2.Vpc(
      this,
      'VpcWithS3Endpoint',
      {
        gatewayEndpoints: {
          S3: {
            service: aws_ec2.GatewayVpcEndpointAwsService.S3
          }
        }
      }
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add system manager VPC interface endpoint&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    vpc.addInterfaceEndpoint(
      'VpcIterfaceEndpointSSM',
      {
        service: aws_ec2.InterfaceVpcEndpointAwsService.SSM
      }
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create an IAM role for the EC2&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const role = new aws_iam.Role(
      this,
      'RoleForEc2ToAccessS3',
      {
        roleName: 'RoleForEc2ToAccessS3',
        assumedBy: new aws_iam.ServicePrincipal('ec2.amazonaws.com'),
      }
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Role for EC2 to communicate with SSM&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    role.addManagedPolicy(
      aws_iam.ManagedPolicy.fromManagedPolicyArn(
        this,
        'PolicySSMMangerAccessS3',
        'arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore'
      )
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Policy for EC2 to access S3&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    role.attachInlinePolicy(
      new aws_iam.Policy(
        this,
        'PolicyForEc2AccessS3',
        {
          policyName: 'PolicyForEc2AccessS3',
          statements: [
            new aws_iam.PolicyStatement(
              {
                actions: ['s3:*'],
                resources: ['*']
              }
            ),
          ]
        }
      )
    )

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

&lt;/div&gt;



&lt;p&gt;Launch an EC2 in a private subnet&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const ec2 = new aws_ec2.Instance(
      this,
      'Ec2ConnectVpcEndpointS3',
      {
        role: role,
        keyName: 'hai_ec2_t4g_large',
        vpc: vpc,
        instanceName: 'Ec2ConnectVpcEndpointS3',
        instanceType: aws_ec2.InstanceType.of(aws_ec2.InstanceClass.T2, aws_ec2.InstanceSize.SMALL),
        machineImage: aws_ec2.MachineImage.latestAmazonLinux(),
        securityGroup: sg,
        vpcSubnets: {
          subnetType: aws_ec2.SubnetType.PRIVATE
        }
      }
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Arm Gravition Versus X86 on Fibonaci and FFT Running Time</title>
      <dc:creator>Hai Tran</dc:creator>
      <pubDate>Wed, 23 Mar 2022 00:12:42 +0000</pubDate>
      <link>https://dev.to/entest/arm-gravition-versus-x86-on-fibonaci-and-fft-running-time-57jm</link>
      <guid>https://dev.to/entest/arm-gravition-versus-x86-on-fibonaci-and-fft-running-time-57jm</guid>
      <description>&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;According to &lt;a href="https://aws.amazon.com/blogs/compute/migrating-aws-lambda-functions-to-arm-based-aws-graviton2-processors/"&gt;AWS Graviton2&lt;/a&gt; the Arm Graviton provides 34% better price performance than X86. In some sense, it runs faster 34% compared with X86. So I do a small experiment to check this. AWS CDK and CodeBuild with Arm based instance makes it easy to setup. &lt;strong&gt;So the Graviton does run about 30% faster than X86&lt;/strong&gt;. &lt;a href="https://github.com/entest-hai/graviton-x86-lambda/blob/master/README.md"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Runtime Python 3.8&lt;/li&gt;
&lt;li&gt;Numpy 1.22.1&lt;/li&gt;
&lt;li&gt;Lambda memory 2048MB&lt;/li&gt;
&lt;li&gt;Lambda timeout 10 seconds&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  CDK Pipeline
&lt;/h3&gt;

&lt;p&gt;CDK make it very friendly to build this pipeline, feeling like pure programming infrastructure. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P_D6PPaG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/20411077/159539715-aabce252-113c-4a07-babf-ae7a0d8b948c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P_D6PPaG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/20411077/159539715-aabce252-113c-4a07-babf-ae7a0d8b948c.png" alt="156108554-8f6f728f-cf18-4a08-b0df-2d9773e860aa" width="880" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Running time for Fibonaci
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def recur_fibo(n):
    if n &amp;lt;= 1:
        return n
    else:
        return(recur_fibo(n-1) + recur_fibo(n-2))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;n = 30 used for testing. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K8i4TCbY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/20411077/159539282-5b9b3574-03ea-4f5f-82b2-7a7e302bc0ce.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K8i4TCbY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/20411077/159539282-5b9b3574-03ea-4f5f-82b2-7a7e302bc0ce.png" alt="123456" width="880" height="522"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Running time for FFT single thread
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data = np.random.rand(8192, 8192)
np.fft.fft(data, axis=0)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fMyGnyJK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/20411077/159596938-37fb8b83-b98b-4b21-9007-b4b4b97fcc82.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fMyGnyJK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/20411077/159596938-37fb8b83-b98b-4b21-9007-b4b4b97fcc82.png" alt="single_thread_fft" width="880" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Running time for FFT multi-thread (Lambda memory 10240MB)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data = [np.random.rand(8192, 2048) for k in range(4)]
with ThreadPoolExecutor(max_worker=4) as executor:
  for x in data:
    executor.submit(np.fft.fft, x, axis=0)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PIT0tUzn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/20411077/159552054-3b5b84e7-6b35-4c2a-9332-7801f92d5de4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PIT0tUzn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/20411077/159552054-3b5b84e7-6b35-4c2a-9332-7801f92d5de4.png" alt="multi_thread_fft_1" width="880" height="530"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>CI/CD Pipeline to Deploy Lambda with Latest ECR Image Tag Using SSM Parameter Store</title>
      <dc:creator>Hai Tran</dc:creator>
      <pubDate>Tue, 01 Mar 2022 05:13:41 +0000</pubDate>
      <link>https://dev.to/entest/cicd-pipeline-to-deploy-lambda-with-latest-ecr-image-tag-using-ssm-parameter-store-2o5g</link>
      <guid>https://dev.to/entest/cicd-pipeline-to-deploy-lambda-with-latest-ecr-image-tag-using-ssm-parameter-store-2o5g</guid>
      <description>&lt;h3&gt;
  
  
  CI/CD Pipeline for Lambda with ECR and SSM for updating tag
&lt;/h3&gt;

&lt;p&gt;This note shows using SSM parameter in CI/CD for passing ECR image tag from CodeBuild to deployment stacks. So the latest ECR image is used in the latest deployed stack such as a lambda function. The default ecr tag is latest and this might cause CloudFormation think that there is not update after pushing an image to ecr. So, it is better to push image with a tag by build number, &lt;strong&gt;CODEBUILD_RESOLVED_SOURCE_VERSION&lt;/strong&gt;, or Git SHA, etc. There are other solutions such as exported variables in CodeBuild, then overrideParameter in deployment stacks. Here SSM is an easy way.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CodeBuild to build a Docker image, tag, and push to an ecr repository&lt;/li&gt;
&lt;li&gt;The tag written to SSM (system parameter store)&lt;/li&gt;
&lt;li&gt;CodeBuild CDK synth application stack&lt;/li&gt;
&lt;li&gt;CodeDeploy deploy the application stack, and the latest ecr tag is read from the SSM&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Architecture
&lt;/h3&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%2Fuser-images.githubusercontent.com%2F20411077%2F156108554-8f6f728f-cf18-4a08-b0df-2d9773e860aa.png" 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%2Fuser-images.githubusercontent.com%2F20411077%2F156108554-8f6f728f-cf18-4a08-b0df-2d9773e860aa.png" alt="aws_devops drawio (1)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  CodeBuild role to push ecr and put-paraemter to ssm
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const role = new aws_iam.Role(
  this,
  'IamRoleForCodeBuildPushEcr',
  {
    assumedBy: new aws_iam.ServicePrincipal('codebuild.amazonaws.com')
  }
)

role.attachInlinePolicy(
  new aws_iam.Policy(
    this,
    "PushEcrPolicy", {
      statements: [
        new aws_iam.PolicyStatement({
          effect: aws_iam.Effect.ALLOW,
          actions: ['ecr:*'],
          resources: ['*']
        }),
        new aws_iam.PolicyStatement({
          effect: aws_iam.Effect.ALLOW,
          actions: ['ssm:*'],
          resources: ['*']
        })
      ]
    }
  )
)

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  CodeBuild project
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// codebuild project
    const codeBuild = new aws_codebuild.PipelineProject(
      this,
      'CodeBuildProject',
      {
        role: role,
        environmentVariables: {
          AWS_ACCOUNT_ID: {value: 'AWS_ACCOUNT_ID'}
        },
        environment: {
          buildImage: aws_codebuild.LinuxBuildImage.STANDARD_5_0,
          computeType: aws_codebuild.ComputeType.MEDIUM,
          privileged: true
        },
        buildSpec: aws_codebuild.BuildSpec.fromObject({
          version: '0.2',
          phases: {
            install: {
              commands: [
                'echo Logging in to Amazon ECR...'
              ]
            },
            // login in ecr
            pre_build: {
              commands: [
                'aws ecr get-login-password --region ap-southeast-1 | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.ap-southeast-1.amazonaws.com'
              ]
            },
            // build ecr image
            build: {
              commands: [
                'docker build -t  ecr-image-name:${CODEBUILD_RESOLVED_SOURCE_VERSION} ./lib/lambda/',
                'docker tag ecr-image-name:${CODEBUILD_RESOLVED_SOURCE_VERSION} ${AWS_ACCOUNT_ID}.dkr.ecr.ap-southeast-1.amazonaws.com/ecr-image-name:${CODEBUILD_RESOLVED_SOURCE_VERSION}'
              ]
            },
            // push ecr image
            post_build: {
              commands: [
                'export imageTag=${CODEBUILD_RESOLVED_SOURCE_VERSION}',
                'docker push ${AWS_ACCOUNT_ID}.dkr.ecr.ap-southeast-1.amazonaws.com/ecr-image-name:${CODEBUILD_RESOLVED_SOURCE_VERSION}',
                'echo ${CODEBUILD_RESOLVED_SOURCE_VERSION}',
                'aws ssm put-parameter --name FhrEcrImageTagDemo --type String --value ${CODEBUILD_RESOLVED_SOURCE_VERSION} --overwrite'
              ]
            }
          },
          env: {
            'exported-variables': [
              'imageTag'
            ]
          }
        })
      }
    )

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  SSM parameters for CI/CD
&lt;/h3&gt;

&lt;p&gt;create a ssm&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws ssm put-parameter --name 'parameterName' --description 'keep track ecr image tag' --value 'b05517a66933f6fde060efe2ecd78784767f6ce1' --type 'String'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;get a ssm&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws ssm get-parameter --name 'parameterName'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;update a ssm&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws ssm put-parameter --name 'parameterName' --type 'String' --value 'b05517a66933f6fde060efe2ecd78784767f6ce1' --overwrite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws ssm put-parameter --name parameterName --type String --value '0a95b18303e05f2de9315bbb385da173398b9661' --overwrite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Entire pipeline
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { 
  aws_codebuild,
  aws_codecommit, 
  aws_codepipeline, 
  aws_codepipeline_actions, 
  aws_ecr, 
  aws_iam, 
  aws_lambda, 
  aws_s3, 
  aws_ssm, 
  Duration, 
  Stack, 
  StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class CodebuildPushEcrStack extends Stack {

  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    // role and polices for codebuild to push ecr image
    const role = new aws_iam.Role(
      this,
      'IamRoleForCodeBuildPushEcr',
      {
        assumedBy: new aws_iam.ServicePrincipal('codebuild.amazonaws.com')
      }
    )

    role.attachInlinePolicy(
      new aws_iam.Policy(
        this, 
        "PushEcrPolicy", {
          statements: [
            new aws_iam.PolicyStatement({
              effect: aws_iam.Effect.ALLOW,
              actions: ['ecr:*'],
              resources: ['*']
            }),
            new aws_iam.PolicyStatement({
              effect: aws_iam.Effect.ALLOW,
              actions: ['ssm:*'],
              resources: ['*']
            })
          ]
        }
      )
    )

    // codecommit 
    const repository = aws_codecommit.Repository.fromRepositoryName(
      this, 
      'CodeCommitRepository',
      `codebuild-push-ecr-${this.account}`
    )

    // codepipeline artifact 
    const artifactBucket = aws_s3.Bucket.fromBucketName(
      this, 
      'ArtifactBucket',
      'fhr-codepipeline-artifact'
    )

    // artifact folders for source, codebuild 
    const sourceOutput = new aws_codepipeline.Artifact('SourceOutput')
    const codeBuildOutput = new aws_codepipeline.Artifact("CodeBuildOutput")
    const cdkBuildOutput = new aws_codepipeline.Artifact('CdkBuildOutput')


    // codebuild project 
    const codeBuild = new aws_codebuild.PipelineProject(
      this, 
      'CodeBuildProject',
      {
        role: role,
        environmentVariables: {
          AWS_ACCOUNT_ID: {value: 'AWS_ACCOUNT_ID'}
        },
        environment: {
          buildImage: aws_codebuild.LinuxBuildImage.STANDARD_5_0,
          computeType: aws_codebuild.ComputeType.MEDIUM,
          privileged: true
        },
        buildSpec: aws_codebuild.BuildSpec.fromObject({
          version: '0.2', 
          phases: {
            install: {
              commands: [
                'echo Logging in to Amazon ECR...'
              ]
            },
            // login in ecr 
            pre_build: {
              commands: [
                'aws ecr get-login-password --region ap-southeast-1 | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.ap-southeast-1.amazonaws.com'
              ]
            },
            // build ecr image 
            build: {
              commands: [
                'docker build -t  fhr-ecr-image:${CODEBUILD_RESOLVED_SOURCE_VERSION} ./lib/lambda/',
                'docker tag fhr-ecr-image:${CODEBUILD_RESOLVED_SOURCE_VERSION} ${AWS_ACCOUNT_ID}.dkr.ecr.ap-southeast-1.amazonaws.com/fhr-ecr-image:${CODEBUILD_RESOLVED_SOURCE_VERSION}'
              ]
            },
            // push ecr image 
            post_build: {
              commands: [
                'export imageTag=${CODEBUILD_RESOLVED_SOURCE_VERSION}',
                'docker push ${AWS_ACCOUNT_ID}.dkr.ecr.ap-southeast-1.amazonaws.com/fhr-ecr-image:${CODEBUILD_RESOLVED_SOURCE_VERSION}',
                'echo ${CODEBUILD_RESOLVED_SOURCE_VERSION}',
                'aws ssm put-parameter --name FhrEcrImageTagDemo --type String --value ${CODEBUILD_RESOLVED_SOURCE_VERSION} --overwrite'
              ]
            }
          }, 
          env: {
            'exported-variables': [
              'imageTag'
            ]
          }
        })
      }
    )

    //
    const buildAction = new aws_codepipeline_actions.CodeBuildAction({
      actionName: 'BuildEcrImage',
      project: codeBuild, 
      input: sourceOutput, 
      outputs: [codeBuildOutput]
    })


    // CodeBuild project for cdk build 
    const cdkBuild = new aws_codebuild.PipelineProject(
      this, 
      'CdkBuikd',
      {
        environment: {
          buildImage: aws_codebuild.LinuxBuildImage.STANDARD_5_0
        },
        buildSpec: aws_codebuild.BuildSpec.fromObject({
          version: '0.2',
          phases: {
            install: {
              commands: [
                'npm install'
              ]
            },
            pre_build: {
              commands: [
                'npm run build',
                'npm run cdk synth -- -o dist'
              ]
            }
          },
          artifacts: {
            'base-directory': 'dist',
            files: [
              '*template.json'
            ]
          }
        })
      }
    )

    // codepipeline 
    new aws_codepipeline.Pipeline(
      this, 
      'CodePiplineProject', 
      {
        artifactBucket: artifactBucket,
        stages: [
          {
            stageName: 'Source',
            actions: [
              new aws_codepipeline_actions.CodeCommitSourceAction({
                actionName: 'ConnectRepository',
                repository: repository, 
                output: sourceOutput
              })
            ]
          }, 
          {
            stageName: 'Build', 
            actions: [
              buildAction,
              new aws_codepipeline_actions.CodeBuildAction({
                actionName: 'BuildStack',
                project: cdkBuild,
                input: sourceOutput,
                outputs: [cdkBuildOutput]
              })
            ]
          },

          {
            stageName: 'Deploy',
            actions: [
              new aws_codepipeline_actions.CloudFormationCreateUpdateStackAction({
                actionName: 'DeployLambdaEcrDemo',
                templatePath: cdkBuildOutput.atPath('ApplicationStack.template.json'),
                stackName: 'ApplicationStackEcrTagDemo',
                parameterOverrides: {
                },
                adminPermissions: true
              })
            ]
          }
        ]
      }
    )

  }
}


export class ApplicationStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props)

    // lambda fron ecr image uri
    const fn = new aws_lambda.Function(
      this,
      'LambdaFromEcrDemo',
      {
        runtime: aws_lambda.Runtime.FROM_IMAGE,
        handler: aws_lambda.Handler.FROM_IMAGE,
        timeout: Duration.seconds(90),
        environment: {
          'FHR_ENV': 'DEPLOY'
        },
        code: aws_lambda.Code.fromEcrImage(
          aws_ecr.Repository.fromRepositoryName(
            this,
            'EcrImageRepositoryDemo',
            'fhr-ecr-image',
          ),
          {
            tag: aws_ssm.StringParameter.valueForStringParameter(
              this, 
              'FhrEcrImageTagDemo'
            )
          }
        )
      }
    )
  }
}

export class RepositoryStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props)

    // create a repository 
    new aws_codecommit.Repository(
      this, 
      "CodeBuildPushEcrRepository", 
      {
        repositoryName: `codebuild-push-ecr-${this.account}`
      }
    )

  }
}

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

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>CloudWatch Monitoring and Alarm Notification for
Lambda</title>
      <dc:creator>Hai Tran</dc:creator>
      <pubDate>Tue, 22 Feb 2022 02:31:35 +0000</pubDate>
      <link>https://dev.to/entest/cloudwatch-monitoring-and-alarm-notification-forlambda-a0l</link>
      <guid>https://dev.to/entest/cloudwatch-monitoring-and-alarm-notification-forlambda-a0l</guid>
      <description>&lt;p&gt;This note show a basic example how to use CloudWatch to monitor a Lambda function and notify when number of invocation greater than X within several minutes. &lt;/p&gt;

&lt;h2&gt;
  
  
  Metrics to monitor
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;CloudWatch metrics for a Lambda fuction

&lt;ul&gt;
&lt;li&gt;Number of invocation within 5 minutes (period)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;CloudWatch alarm

&lt;ul&gt;
&lt;li&gt;Compare the metric with a threshold &amp;gt; X&lt;/li&gt;
&lt;li&gt;Evaluation period 1 &lt;/li&gt;
&lt;li&gt;Action sends SNS notification&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;CloudWatch dashboard

&lt;ul&gt;
&lt;li&gt;Number of invocation within each data point of 5 minutes &lt;/li&gt;
&lt;li&gt;Average duration of invocation&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some notes&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CloudWatch logs are stored for 15 months, need to save to S3 if need longer &lt;/li&gt;
&lt;li&gt;Lambda sends logs to CloudWatch per 1 minute &lt;/li&gt;
&lt;li&gt;Principle to prevent premature/false alarm by M out of N (the trailing window) 
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--T-4Pa5BY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/20411077/155051909-2b1754df-0518-413f-9562-e15edf94ac91.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--T-4Pa5BY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/20411077/155051909-2b1754df-0518-413f-9562-e15edf94ac91.png" alt="111" width="797" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LLn04cpm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/20411077/155051926-3a8972b0-4fd5-45df-a257-f302d412d3ed.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LLn04cpm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/20411077/155051926-3a8972b0-4fd5-45df-a257-f302d412d3ed.png" alt="113" width="812" height="597"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Stack in CDK
&lt;/h2&gt;

&lt;p&gt;create a lambda function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fn = new aws_lambda.Function(
    this,
    "LambdaCloudWatchAlarmDemo",
    {
    runtime: aws_lambda.Runtime.PYTHON_3_8,
    handler: "index.handler",
    timeout: Duration.seconds(90),
    code: aws_lambda.Code.fromAsset(
        path.join(__dirname, "lambda")
    )
    }
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create cloudwatch alarm&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const alarm = new aws_cloudwatch.Alarm(
      this,
      "LambdaInvocationAlarmDemo",
      {
        metric: fn.metricInvocations(
          {
            statistic: 'sum',
            period: Duration.minutes(5)
          }
        ),
        threshold: 5,
        evaluationPeriods: 1
      }
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;add alarm action&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; alarm.addAlarmAction(
      new aws_cloudwatch_actions.SnsAction(aws_sns.Topic.fromTopicArn(
        this,
        "CodePipelineNotification",
        "arn:aws:sns:ap-southeast-1:account_id:CodePipelineNotification"
      ))
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;cloudwatch dashboard&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// title
dashboard.addWidgets(
      new aws_cloudwatch.TextWidget({
        markdown: `# Dashboard: ${fn.functionName}`,
        height: 1,
        width: 24
      })
    )
// number of invocation
 dashboard.addWidgets(
      new aws_cloudwatch.GraphWidget({
        title: "Invocation",
        left: [fn.metricInvocations(
          {
            statistic: 'sum',
            period: Duration.minutes(1)
          }
        )],
        width: 24
      })
    )
// duration 
 dashboard.addWidgets(
      new aws_cloudwatch.GraphWidget({
        title: "Duration",
        left: [fn.metricDuration()],
        width: 24
      })
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>CDK to deploy a Lambda function </title>
      <dc:creator>Hai Tran</dc:creator>
      <pubDate>Sat, 12 Feb 2022 04:35:28 +0000</pubDate>
      <link>https://dev.to/entest/cdk-to-deploy-a-lambda-function-4pe8</link>
      <guid>https://dev.to/entest/cdk-to-deploy-a-lambda-function-4pe8</guid>
      <description>&lt;p&gt;There are may options to deploy a Lambda fuction: &lt;br&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;zip the code and upload to S3 &lt;/li&gt;
&lt;li&gt;share large dependencies via EFS&lt;/li&gt;
&lt;li&gt;inline funtion with CloudFormation 
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this note, I would like to share three ways to deploy a Lambda function using AWS CDK, and integrate multiple Lambda functions with a API Gateway for testing. &lt;/p&gt;

&lt;h2&gt;
  
  
  1. Deploy a lambda function by files
&lt;/h2&gt;

&lt;p&gt;install dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python -m pip install --target path-to-lambda numpy 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;aws_lambda.Function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;handler_file = aws_lambda.Function(
            self,
            id="lambda-handler-wo-dependencies",
            code=aws_lambda.Code.from_asset(path.join(dirname, "lambda")),
            handler="handler.handler_file",
            runtime=aws_lambda.Runtime.PYTHON_3_8,
            memory_size=512,
            timeout=Duration.seconds(90)
        )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Deploy a lambda function by ecr image
&lt;/h2&gt;

&lt;p&gt;Note that the docker image is built from the local machine in this case. Here is the project structure&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- aws_devops
    - lambda
        - Dockerfile
        - .dockerignore
        - handler.py
        - requirements.txt
     -aws_devops_stack.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;handler_ecr = aws_lambda.Function(
            self,
            id="lambda-ecr-build-local",
            code=aws_lambda.EcrImageCode.from_asset_image(
                directory=path.join(dirname, "lambda")
            ),
            handler=aws_lambda.Handler.FROM_IMAGE,
            runtime=aws_lambda.Runtime.FROM_IMAGE,
            memory_size=512,
            timeout=Duration.seconds(90)
        )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Deploy a lambda function with an existring ecr image
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;handler = aws_lambda.Function(
            self,
            id="EcrImageId",
            code=aws_lambda.EcrImageCode.from_ecr_image(
                repository=aws_ecr.Repository.from_repository_name(
                    self,
                    id="EcrImageId",
                    repository_name="EcrRepositoryName"
                )
            ),
            architecture=aws_lambda.Architecture.ARM_64,
            handler=aws_lambda.Handler.FROM_IMAGE,
            runtime=aws_lambda.Runtime.FROM_IMAGE,
            memory_size=512,
            timeout=Duration.seconds(90),
        )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Integrate an API Gateway with multiple lambdas
&lt;/h2&gt;

&lt;p&gt;create an api gateway&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;api_gw = aws_apigateway.RestApi(
            self,
            id="ApiGatewayLambdaDeployOptions",
            rest_api_name="api-lambda-deploy-options"
        )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create api resource&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;api_file_resource = api_gw.root.add_resource(
            path_part="file"
        )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create lambda integration&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; api_file_intetgration = aws_apigateway.LambdaIntegration(
            handler=handler_file
        )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;add method to the resource&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; api_file_resource.add_method(
            http_method="GET",
            integration=api_file_intetgration
        )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Graviton versus M1, vs x86 on FFT Performance</title>
      <dc:creator>Hai Tran</dc:creator>
      <pubDate>Sat, 12 Feb 2022 04:02:25 +0000</pubDate>
      <link>https://dev.to/entest/graviton-versus-m1-vs-x86-on-fft-performance-1mef</link>
      <guid>https://dev.to/entest/graviton-versus-m1-vs-x86-on-fft-performance-1mef</guid>
      <description>&lt;p&gt;AWS states that Graviton (ARM) is 30% faster than x86, however, I find out that FFT on the Graviton is slower than about 10% compared with the x86. Below is setup and results, hopefully, I have not correctly setup the numpy for Graviton. Anyway, multithread is 4x faster than single thread, in this case the 10240MB lambda has 6 vCPUs, I think &lt;br&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F20411077%2F152672757-269e8a97-7d1d-4be0-b307-64b843b34642.png" 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%2Fuser-images.githubusercontent.com%2F20411077%2F152672757-269e8a97-7d1d-4be0-b307-64b843b34642.png" alt="FFT_single_thread_x86_graviton"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F20411077%2F152672759-98c37a28-476b-46c2-9676-587de929698e.png" 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%2Fuser-images.githubusercontent.com%2F20411077%2F152672759-98c37a28-476b-46c2-9676-587de929698e.png" alt="FFT_multi_thread_x86_graviton"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Lambda configuration
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;memory 10240 MB&lt;/li&gt;
&lt;li&gt;timeout 90 seconds&lt;/li&gt;
&lt;li&gt;deploy via ecr image and CDK &lt;/li&gt;
&lt;li&gt;EC2 ARM64 to build the image for the Graviton&lt;/li&gt;
&lt;li&gt;language python&lt;/li&gt;
&lt;li&gt;numpy 1.22.1 and numpy.fft.fft&lt;/li&gt;
&lt;li&gt;np.fft.fft(np.random.randint(0, 1000, (4098, 600)))&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  I deploy lambda by ecr image
&lt;/h2&gt;

&lt;p&gt;Docker file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM public.ecr.aws/lambda/python:3.8

# create code dir inside container
RUN mkdir ${LAMBDA_TASK_ROOT}/source

# copy code to container
COPY . ${LAMBDA_TASK_ROOT}/source

# copy handler function to container
COPY ./handler.py ${LAMBDA_TASK_ROOT}

# install dependencies for running time environment
RUN pip3 install -r ./source/requirements.txt --target "${LAMBDA_TASK_ROOT}"

# set the CMD to your handler
CMD [ "handler.lambda_handler"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;lambda handler&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import json
import numpy as np
from concurrent.futures import ThreadPoolExecutor
from datetime import datetime

def single_thread_fft(sig):
    """
    normal fft
    """
    start_time = datetime.now()
    for x in sig:
        np.fft.fft(x, axis=0)
    end_time = datetime.now()
    delta_time = end_time.timestamp() - start_time.timestamp()
    print("single thread running time {0} ms".format(delta_time * 1000))
    return delta_time

def multi_thread_fft(sig):
    """
    thread fft
    """
    start_time = datetime.now()
    with ThreadPoolExecutor(max_workers=4) as executor:
        for x in sig:
            executor.submit(np.fft.fft, x, axis=0)
    end_time = datetime.now()
    delta_time = end_time.timestamp() - start_time.timestamp()
    print("multi thread running time {0} ms".format(delta_time * 1000))
    return delta_time


def lambda_handler(event, context):
    """
    Lambda handler
    """
    # signal for one channel
    sig = [np.random.randint(0, 1000, (4098, 600)) for k in range(4)]
    # single thread
    single_thread_time = single_thread_fft(sig)
    # multi thread
    multi_thread_time = multi_thread_fft(sig)
    # response
    return {
        'statusCode': 200,
        'headers': {
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Headers": "Content-Type",
            "Access-Control-Allow-Methods": "OPTIONS,GET"
        },
        'body': json.dumps({"single thread: {0}, multi thread: {1}".format(single_thread_time * 1000, multi_thread_time*1000)},
                           indent=4,
                           sort_keys=True,
                           default=str)
    }

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

&lt;/div&gt;



&lt;p&gt;CDK lambda api gateway stack&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class LambdaFFTArm(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -&amp;gt; None:
        super().__init__(scope, construct_id, **kwargs)
        # The code that defines your stack goes here
        handler = aws_lambda.Function(
            self,
            id="LambdaFFTArm",
            code=aws_lambda.EcrImageCode.from_ecr_image(
                repository=aws_ecr.Repository.from_repository_name(
                    self,
                    id="LambdaFFTArmImage",
                    repository_name="lambda-fft-arm-image"
                )
            ),
            architecture=aws_lambda.Architecture.ARM_64,
            handler=aws_lambda.Handler.FROM_IMAGE,
            runtime=aws_lambda.Runtime.FROM_IMAGE,
            memory_size=10240,
            timeout=Duration.seconds(90),
        )
        # api gateway
        api_gw = aws_apigateway.LambdaRestApi(
            self,
            id="ApiLambdaFFTArm",
            handler=handler
        )
        # get api endpoint
        self.url_output = CfnOutput(self, "Url", value=api_gw.url)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
  </channel>
</rss>
