<?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>Forem: Nutchanon Leelapornudom</title>
    <description>The latest articles on Forem by Nutchanon Leelapornudom (@nutchanon).</description>
    <link>https://forem.com/nutchanon</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%2F693772%2F8b6ca852-40e2-4121-bdb5-fc0880c24473.jpeg</url>
      <title>Forem: Nutchanon Leelapornudom</title>
      <link>https://forem.com/nutchanon</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/nutchanon"/>
    <language>en</language>
    <item>
      <title>Visualising your Amazon DynamoDB data with Amazon QuickSight</title>
      <dc:creator>Nutchanon Leelapornudom</dc:creator>
      <pubDate>Tue, 22 Mar 2022 15:25:57 +0000</pubDate>
      <link>https://forem.com/awscommunity-asean/visualising-your-amazon-dynamodb-data-with-amazon-quicksight-14n4</link>
      <guid>https://forem.com/awscommunity-asean/visualising-your-amazon-dynamodb-data-with-amazon-quicksight-14n4</guid>
      <description>&lt;p&gt;Please noted that this content is translated from Thai language on this &lt;a href="https://dev.to/awscommunity-asean/amazon-dynamodb-amazon-quicksight-4mcb"&gt;Blog&lt;/a&gt; because it has high demand for implementing this solution in real life.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Content
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Architecture Diagram&lt;/li&gt;
&lt;li&gt;Cost Estimation&lt;/li&gt;
&lt;li&gt;Step 1: Prepare AWS Services&lt;/li&gt;
&lt;li&gt;Step 2: Create Amazon Athena data source&lt;/li&gt;
&lt;li&gt;Step 3: Test query on your data in DynamoDB via Amazon Athena&lt;/li&gt;
&lt;li&gt;Step 4: Connect Amazon QuickSight and Amazon Athena with Federated Query&lt;/li&gt;
&lt;li&gt;Step 5: Create QuickSight dataset of DynamoDB via Athena&lt;/li&gt;
&lt;li&gt;Step 6: Create QuickSight analyse from DynamoDB dataset&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In modern application, NoSQL databases are used widely in the organisation, including Amazon DynamoDB, Amazon DocumentDB, Apache HBase, and so on, which each of them has their own query language. However, there is a demand that want to visualise those data in form of graphs for business purpose.&lt;/p&gt;

&lt;p&gt;AWS has Amazon QuickSight, a cloud-native business intelligent tool that help you to create a dashboard, visualise data, find insights, and has build-in Machine Learning capability. Amazon QuickSight support many &lt;a href="https://docs.aws.amazon.com/quicksight/latest/user/supported-data-sources.html" rel="noopener noreferrer"&gt;native build-in data source&lt;/a&gt;, such as Amazon RDS, Amazon Aurora, Self-Managed MySQL, or 3rd party software.&lt;/p&gt;

&lt;p&gt;But NoSQL databases, which mostly do not natively support SQL language, need to have data pipeline or data processing to store that data into somewhere else, for example Amazon S3, before visualising that data in the business intelligent tool.&lt;/p&gt;

&lt;p&gt;In this blog, I will show you how to visualise data on Amazon DynamoDB, one of AWS NoSQL database, without moving the data out, and natively update the data in near-real time on Amazon QuickSight.&lt;br&gt;
&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Architecture Diagram
&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr95r7hnbyynmf4j2vyud.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr95r7hnbyynmf4j2vyud.png" alt="Architecture Diagram" width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Cost Estimation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Pricing for Storage and Read Capacity Unit (RCU) of &lt;a href="https://aws.amazon.com/dynamodb/pricing/" rel="noopener noreferrer"&gt;Amazon DynamoDB&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Pricing for Data Scan of &lt;a href="https://aws.amazon.com/th/athena/pricing/" rel="noopener noreferrer"&gt;Amazon Athena&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Pricing for User and SPICE of &lt;a href="https://aws.amazon.com/quicksight/pricing/" rel="noopener noreferrer"&gt;Amazon QuickSight&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Pricing for Storage of &lt;a href="https://aws.amazon.com/s3/pricing" rel="noopener noreferrer"&gt;Amazon S3&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;ℹ️ Info: It might has a bit additional price for AWS Lambda and Data Transfer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: Prepare AWS Services
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Get started at Amazon Athena console, the engine version 2 is required, and prepare S3 Result Data bucket (e.g. nutchanon-athena-query-results).
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fye01n9o87zsf59t6s2zn.png" alt="AthenaS3" width="783" height="363"&gt;
&lt;/li&gt;
&lt;li&gt;Create an Amazon S3 bucket for Spill Bucket Data of Athena.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foal0s3mw6nlnevb02cqc.png" alt="Spill" width="800" height="438"&gt;
&lt;/li&gt;
&lt;li&gt;Go to Amazon QuickSight console - &lt;a href="https://docs.aws.amazon.com/quicksight/latest/user/setting-up.html" rel="noopener noreferrer"&gt;Setting Up for Amazon QuickSight&lt;/a&gt;.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frsirfu1rctrua2x9xwzn.png" alt="QuickSightStart" width="715" height="262"&gt;
&lt;/li&gt;
&lt;li&gt;Prepare Amazon DynamoDB table with the sample data (e.g.quicksight-ddb).
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fld0ayp6c54bua1qjttfv.png" alt="DDBData" width="800" height="491"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;ℹ️ Info: if you do not have the data in DynamoDB for testing, please check &lt;a href="https://dev.to/awscommunity-asean/csv-amazon-s3-amazon-dynamodb-3i2f"&gt;วิธีการนำข้อมูล CSV จาก Amazon S3 เข้า Amazon DynamoDB&lt;/a&gt; (English translation is required)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 2: Create Amazon Athena data source
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create new data source from "Connect data source".
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgkvfsggc8bajzan6qxkn.png" alt="AthenaData" width="703" height="375"&gt;
&lt;/li&gt;
&lt;li&gt;Choose "Query a data source" and "Amazon DynamoDB".
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7u8bs46kvkvbrnrvg3ad.png" alt="AtDataSrc" width="800" height="427"&gt;
&lt;/li&gt;
&lt;li&gt;Choose "Configure new AWS Lambda function" for creating Lambda Connector.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj6ubq2qqcol4e8218xvt.png" alt="Lambda Connector" width="668" height="178"&gt;
&lt;/li&gt;
&lt;li&gt;Choose "SpillBucket", "AthenaCatalogName" and confirm "Custom IAM Roles", and then click "Deploy". The system will automatically create AWS CloudFormation for Lambda Connector.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr2wk9f5jbpzyu03e4axk.png" alt="LambdaConfig" width="763" height="873"&gt;
&lt;/li&gt;
&lt;li&gt;Go back to choose Lambda Connector that you just created (might need a refresh), then provide the name of the catalog.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faejudjaod01k4z78alqu.png" alt="Lambda Connector2" width="699" height="520"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 3: Test query on your data in DynamoDB via Amazon Athena
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Choose "Data Source" to be your newly created catalog, then the table of DynamoDB will be able to selected. Let's try to query via DynamoDB data via Athena.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fymuno0t7uvrdjm8towj4.png" alt="AthenaDDB" width="800" height="355"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 4: Connect Amazon QuickSight and Amazon Athena with Federated Query
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Change QuickSight region to N.Virginia for edit configuration. Then go to "Manage QuickSight".
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyd8b95u33l13d0f2kvh3.png" alt="QSRegion" width="171" height="344"&gt;
&lt;/li&gt;
&lt;li&gt;Allocate SPICE capacity. (What QuickSight SPICE is? Please see &lt;a href="https://docs.aws.amazon.com/quicksight/latest/user/managing-spice-capacity.html" rel="noopener noreferrer"&gt;Managing SPICE Capacity&lt;/a&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg46tuju17simz020gvsi.png" alt="QSSPICEAllocate" width="583" height="205"&gt;
&lt;/li&gt;
&lt;li&gt;For "Security &amp;amp; Permission" choose "Add or Remove".
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4zfz0knssdxgr19bu5cx.png" alt="QSAdminSec" width="800" height="264"&gt;
&lt;/li&gt;
&lt;li&gt;Choose Amazon Athena (If it already has chosen, please click twice times), then you will see the window of permission for Amazon S3. Next, choose Athena Spill and Result Data Bucket with write permission.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmal9fmynwzu4ehnh03nb.png" alt="QSPermission" width="800" height="440"&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdplbglzzqggqu31xuaqp.png" alt="QSS3" width="800" height="602"&gt;
&lt;/li&gt;
&lt;li&gt;Change QuickSight region to Singapore (or your preferred region) for creating the dataset.&lt;/li&gt;
&lt;li&gt;Go back to AWS Management Console and go to "IAM" Service. Then go to IAM Role.&lt;/li&gt;
&lt;li&gt;Add policy at IAM Role "aws-quicksight-s3-consumers-role-v0", which the system automated generated when you grant S3 permission in QuickSight.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fas7jsb2eyhe84ynmecgw.png" alt="QSIAMRole" width="800" height="450"&gt;
Add "inline policy" name "InvokeAthenaFedereted" by follow JSON document as below.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️  Please change "aws_account_id" and Lambda Function name that you created in step 2 ("AthenaCatalogName").&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"InvokeAthenaFedereted"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lambda:InvokeFunction"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:lambda:ap-southeast-1:&amp;lt;aws_account_id&amp;gt;:function:dynamocatalog"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Create QuickSight dataset of DynamoDB via Athena
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create dataset from Athena Data Source with the connection name, e.g."athena-dynamodb".
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzl43y44pat7g4udhebj6.png" alt="QSAthenaDDB" width="580" height="283"&gt;
&lt;/li&gt;
&lt;li&gt;Choose catalog name that you created in step 2, and the table.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feo5j1bxs9rk24wx7i3gd.png" alt="QSCatalog" width="579" height="478"&gt;
&lt;/li&gt;
&lt;li&gt;Choose to create from SPICE.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F25fu73ywfcogbr4ffb52.png" alt="QSSPICE" width="586" height="326"&gt;
&lt;/li&gt;
&lt;li&gt;Wait until the data is imported into SPICE.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3mzvhrxsashep79rspig.png" alt="QSSPICE/" width="330" height="122"&gt;
&lt;/li&gt;
&lt;li&gt;Change data type of each column appropriately for the data calculation and filtering in the future.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foee5q3kdtklry6m2ozap.png" alt="QSDataType" width="727" height="826"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Create QuickSight analyse from DynamoDB dataset
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;You can create analyse and dashboard directly from DynamoDB data.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fen839wel301qbs9w7bc0.png" alt="QSAnalyse" width="800" height="470"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;ℹ️  Info: Changing the data type of dataset directly affect how to do calculation on graphs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Amazon QuickSight can connect to non-directly support data source via Amazon Athena Federeted Query, which allow you to expand the functionality of building graph on many data source. By using Amazon Athena Federeted Query, you can even expand to NoSQL databases on AWS, such as Amazon DynamoDB, Amazon DocumentDB, or Amazon OpenSearch Service.&lt;/p&gt;

&lt;p&gt;This solution will help to you easily build dashboard or visualise data on Amazon QuickSight without data movement or need to build data pipeline platform. Also, the data that show in the dashboard will be refreshed in near real-time based-on the source of data as well.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3pp3cc9du87hqg20ugb.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3pp3cc9du87hqg20ugb.jpg" alt="CastleArm" width="800" height="577"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Reference
&lt;/h3&gt;

&lt;p&gt;[1] &lt;a href="https://aws.amazon.com/blogs/big-data/accessing-and-visualizing-data-from-multiple-data-sources-with-amazon-athena-and-amazon-quicksight/" rel="noopener noreferrer"&gt;https://aws.amazon.com/blogs/big-data/accessing-and-visualizing-data-from-multiple-data-sources-with-amazon-athena-and-amazon-quicksight/&lt;/a&gt;&lt;br&gt;
[2] &lt;a href="https://aws.amazon.com/blogs/big-data/query-any-data-source-with-amazon-athenas-new-federated-query/" rel="noopener noreferrer"&gt;https://aws.amazon.com/blogs/big-data/query-any-data-source-with-amazon-athenas-new-federated-query/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>quicksight</category>
      <category>dynamodb</category>
    </item>
    <item>
      <title>ตัวอย่างการนำข้อมูล CSV จาก Amazon S3 เข้า Amazon Elasticsearch Service</title>
      <dc:creator>Nutchanon Leelapornudom</dc:creator>
      <pubDate>Thu, 07 Oct 2021 08:10:19 +0000</pubDate>
      <link>https://forem.com/awscommunity-asean/csv-amazon-s3-amazon-elasticsearch-service-47hd</link>
      <guid>https://forem.com/awscommunity-asean/csv-amazon-s3-amazon-elasticsearch-service-47hd</guid>
      <description>&lt;h2&gt;
  
  
  สารบัญ (Table of Content)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;บทนำ&lt;/li&gt;
&lt;li&gt;แผนผังของระบบ&lt;/li&gt;
&lt;li&gt;การประเมินราคาเบื้องต้น&lt;/li&gt;
&lt;li&gt;ข้อจำกัดของตัวอย่างที่ควรรู้&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 1: นำข้อมูลตัวอย่างเข้า Amazon S3&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 2: สร้าง Amazon Elasticsearch Service domain&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 3: สร้าง AWS Cloud9 และเตรียม configuration&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 4: แก้ไข application configuration ให้พร้อมกับการใช้งาน&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 5: Execute import code บน AWS Cloud9&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 6: ตรวจสอบข้อมูลที่ import ที่ Amazon Elasticsearch Service&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  บทนำ
&lt;/h2&gt;

&lt;p&gt;หลาย ๆ ครั้ง ผู้ใช้งานมีความต้องการที่จะนำข้อมูล จากระบบฐานข้อมูลแบบตาราง (RDBMS) ซึ่งอยู่ในรูปแบบ CSV file นำเข้า (import) ไปยังระบบฐานข้อมูลแบบ NoSQL อย่างเช่น Amazon Elasticsearch Service เป็นต้น และผู้ใช้งานพบว่า Amazon Elasticsearch Service ไม่ได้มี feature อย่างเช่นการ import โดยตรง ทำให้ผู้ใช้งาน พบปัญหาเกี่ยวกับการเขียน application ขึ้นมาเอง และวิธีการกำหนดสิทธิต่าง ๆ&lt;/p&gt;

&lt;p&gt;ในบทความนี้จะเป็นตัวอย่างของการนำข้อมูล CSV file เข้า Amazon Elasticsearch Service โดยมีวิธีการ รวมถึงตัวอย่าง code ที่ผู้ใช้งานสามารถนำไปปรับใช้ให้เหมาะสมกับข้อมูลที่ผู้ใช้งานต้องการได้อีกด้วย&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  แผนผังของระบบ (Architecture Diagram)
&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Focqzdkio0b9c6p76u9q2.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Focqzdkio0b9c6p76u9q2.png" alt="Diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  การประเมินราคาเบื้องต้น (Cost Estimation)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ราคา Cluster ของ Amazon Elasticsearch Service - &lt;a href="https://aws.amazon.com/elasticsearch-service/pricing/" rel="noopener noreferrer"&gt;Amazon Elasticsearch Service Pricing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ราคา Storage ของ S3 - &lt;a href="https://aws.amazon.com/s3/pricing" rel="noopener noreferrer"&gt;Amazon S3 Pricing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;(option 1) ราคาของ AWS Cloud9 Instance - &lt;a href="https://aws.amazon.com/cloud9/pricing/" rel="noopener noreferrer"&gt;AWS Cloud9&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;(option 2) ราคาเครื่องของ Amazon EC2 - &lt;a href="https://aws.amazon.com/ec2/pricing/" rel="noopener noreferrer"&gt;Amazon EC2 Pricing&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;ℹ️  หมายเหตุ: อาจจะมีราคาอีกนิดหน่อยในส่วนของ Network ที่ยังไม่ได้รวม&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ข้อจำกัดของตัวอย่างที่ควรรู้
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;CSV file จะต้องมี header อยู่ที่ row แถวแรกของ file&lt;/li&gt;
&lt;li&gt;หากผู้ใช้เลือก Amazon EC2 ในการติดตั้ง application จะต้องทำการติดตั้ง Python Binary version 3.7 เป็นต้นไปด้วย แต่หากใช้ AWS Cloud9 จะทำการติดตั้งไว้ให้เรียบร้อยแล้ว&lt;/li&gt;
&lt;li&gt;ผู้ใช้งานสามารถเลือกใช้งาน Internet Gateway (IGW) หรือ VPC S3 Gateway Endpoint สำหรับเชื่อมต่อระหว่าง Amazon S3 กับ Internal VPC services ได้&lt;/li&gt;
&lt;li&gt;ในตัวอย่าง เป็นการเลือกติดตั้ง Amazon Elasticsearch Service บน VPC และเปิดการใช้งาน "Fine-grained Access Control" ผ่าน HTTP สำหรับ Username และ Password&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 1: นำข้อมูลตัวอย่างเข้า Amazon S3
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Download ข้อมูลตัวอย่าง &lt;a href="https://ee-assets-prod-us-east-1.s3.amazonaws.com/modules/337d5d05acc64a6fa37bcba6b921071c/v1/SaaS-Sales.csv" rel="noopener noreferrer"&gt;SaaS-Sales.csv&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Upload ข้อมูลตัวอย่างขึ้น S3 (e.g. nutchanon-es-importer)
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4sotebclez7zd7asb2y8.png" alt="S3Import"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 2: สร้าง Amazon Elasticsearch Service domain
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;สร้าง Amazon Elasticsearch cluster พร้อมกับปรับ configuration ด้านความปลอดภัยให้เหมาะสมตามนี้

&lt;ul&gt;
&lt;li&gt;กำหนด access control policy ใน "Fine-grained Access Control" เพื่อให้ user สามารถเขียนข้อมูลใน index ที่กำหนดได้&lt;/li&gt;
&lt;li&gt;เลือก deploy บน VPC และกำหนด security group สำหรับให้ Cloud9 หรือ EC2&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fforowcx9xxr04e8mrn6s.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fforowcx9xxr04e8mrn6s.png" alt="AmazonESCreation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 3: สร้าง AWS Cloud9 และเตรียม configuration
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;สร้าง AWS Cloud9 environment สำหรับใช้งาน
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgnt1uw2sn3b9zwanysbk.png" alt="cloud9"&gt;
&lt;/li&gt;
&lt;li&gt;ตรวจสอบ version ของ python ผ่าน command line โดยคาดหวังว่าจะเจอ Python version 3.7+
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 &lt;span class="nt"&gt;-V&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;ทำการ download code ตัวอย่างจาก &lt;a href="https://github.com/nutchanon-l/load-s3-to-es" rel="noopener noreferrer"&gt;Github:load-s3-to-es&lt;/a&gt;[1]
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/nutchanon-l/load-s3-to-es.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;ทำการติดตั้ง Python packages สำหรับ pre-requisite ที่จำเป็นผ่าน
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip3 &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; load-s3-to-es/requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;ทำการสร้าง IAM Role สำหรับ AWS Cloud9 ให้สามารถดึงข้อมูลจาก Amazon S3 ด้วย IAM Policy ดังตัวอย่าง (อย่าลืมเปลี่ยน Amazon S3 Bucket)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"S3ReadObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"s3:GetObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"s3:ListBucket"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::nutchanon-es-importer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::nutchanon-es-importer/*"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4au7x7z71bbfns9tbsn4.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4au7x7z71bbfns9tbsn4.png" alt="Cloud9Role"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ทำการ attach IAM role ไปยัง AWS Cloud9 Instance ผ่าน Amazon EC2 Console
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvbq1k1re2qay0wv4lnh6.png" alt="Cloud9Role2"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 4: แก้ไข application configuration ให้พร้อมกับการใช้งาน
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;แก้ไข config.json ไฟล์ (อย่าลืมเปลี่ยน Elasticsearch endpoint ด้วย)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"s3"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"bucket"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nutchanon-es-importer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"prefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"elasticsearch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"https://vpc-nutcha-es-01-jozw26jnqvxcufjccrpcmiowam.ap-southeast-1.es.amazonaws.com"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;443&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;your_username&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;your_password&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;แก้ไข metadata.json ไฟล์
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"index"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"es_index_as_filename"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"es_index_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"headers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Row ID"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Order ID"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Order Date"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Date Key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Contact Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Country"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"City"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Region"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Subregion"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Customer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Customer ID"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Industry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Segment"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Product"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"License"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Sales"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Quantity"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Discount"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Profit"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id_field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Row ID"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 5: Execute import code บน AWS Cloud9
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ทำการรัน code ด้วย command ดังต่อไปนี้
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;load-s3-to-es
python3 s3-to-es.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;รอจนสุดท้ายขึ้นว่า
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;INFO: Bulk write succeed: 9994 documents
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 6: ตรวจสอบข้อมูลที่ import ที่ Amazon Elasticsearch Service
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ตรวจสอบ index ที่ทำการ import จาก command ดังนี้ (อย่าลืมเปลี่ยน Elasticsearch endpoint ด้วย)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-u&lt;/span&gt; &amp;lt;your_username&amp;gt;:&amp;lt;your_password&amp;gt; &lt;span class="nt"&gt;-X&lt;/span&gt; GET &lt;span class="s2"&gt;"https://vpc-nutcha-es-01-jozw26jnqvxcufjccrpcmiowam.ap-southeast-1.es.amazonaws.com/_cat/indices?v&amp;amp;s=index"&lt;/span&gt;
health status index                uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   .kibana_1            cJyYpOa0RkOmvZHKCFAgMw   1   1          0            0       416b           208b
green  open   .opendistro_security 15W1rxD9TJOTfuld6W_p1g   1   2          9            4    172.9kb         59.6kb
green  open   saas-sales           KvhEecP2QvCO4UfThBki_A   5   1       9994            0      8.4mb          4.1mb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;ทดสอบการค้นหาข้อมูลด้วย search API ผ่าน "saas-sales" index (อย่าลืมเปลี่ยน Elasticsearch endpoint ด้วย)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-u&lt;/span&gt; &amp;lt;your_username&amp;gt;:&amp;lt;your_password&amp;gt; &lt;span class="nt"&gt;-X&lt;/span&gt; GET &lt;span class="s2"&gt;"https://vpc-nutcha-es-01-jozw26jnqvxcufjccrpcmiowam.ap-southeast-1.es.amazonaws.com/saas-sales/_search"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  แหล่งอ้างอิงอื่น ๆ
&lt;/h2&gt;

&lt;p&gt;[1] &lt;a href="https://github.com/nutchanon-l/load-s3-to-es" rel="noopener noreferrer"&gt;https://github.com/nutchanon-l/load-s3-to-es&lt;/a&gt;&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3pp3cc9du87hqg20ugb.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3pp3cc9du87hqg20ugb.jpg" alt="CastleArm"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>awsthai</category>
      <category>tutorial</category>
      <category>elasticsearch</category>
    </item>
    <item>
      <title>การแชร์ข้อมูลบน Amazon S3 ผ่าน Presigned URL</title>
      <dc:creator>Nutchanon Leelapornudom</dc:creator>
      <pubDate>Tue, 28 Sep 2021 04:55:28 +0000</pubDate>
      <link>https://forem.com/awscommunity-asean/amazon-s3-presigned-url-55lj</link>
      <guid>https://forem.com/awscommunity-asean/amazon-s3-presigned-url-55lj</guid>
      <description>&lt;h2&gt;
  
  
  สารบัญ (Table of Content)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;บทนำ&lt;/li&gt;
&lt;li&gt;การประเมินราคาเบื้องต้น&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 1: ทำการสร้าง IAM User&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 2: กำหนด Amazon S3 Bucket Policy&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 3: สร้าง presigned URL ของ Amazon S3 ผ่าน AWS CLI&lt;/li&gt;
&lt;li&gt;บทสรุป&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  บทนำ
&lt;/h2&gt;

&lt;p&gt;โดยปกติแล้ว ทุก ๆ object ใน Amazon S3 จะเป็นลักษณะ private คือไม่สามารถแชร์ให้กับผู้ที่ไม่มีสิทธิเข้าถึงได้ แต่ในบางกรณี ผู้ใช้งานต้องการที่จะแชร์ข้อมูลใน Amazon S3 Bucket ให้ผู้ใช้งานทั่วไปสามารถเข้าถึงได้แบบ public ในช่วงระยะเวลาหนึ่ง ๆ แบบจำกัด&lt;/p&gt;

&lt;p&gt;ทาง Amazon S3 มีความสามารถที่ให้ผู้ใช้งานสามารถสร้าง URL พิเศษ ที่มีสิทธิในการเข้าถึงข้อมูล Amazon S3 Bucket แบบ public เป็นการชั่วคราว เรียกว่า presigned URL โดยผู้ใช้งาน สามารถระบุเวลาที่จะให้หมดอายุได้อีกด้วย&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  การประเมินราคาเบื้องต้น (Cost Estimation)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ราคาการเรียกใช้งาน Amazon S3 - &lt;a href="https://aws.amazon.com/s3/pricing/" rel="noopener noreferrer"&gt;Amazon S3 Pricing&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 1: ทำการสร้าง IAM User
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ทำการสร้าง IAM User โดยไม่ต้องกำหนด permission ใด ๆ ให้เลย
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flxs18p38pzgjfdc2x6fl.png" alt="IAM User"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 2: กำหนด Amazon S3 Bucket Policy
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;หากผู้ใช้งานยังไม่มี Amazon S3 Bucket ให้ทำการสร้างก่อน&lt;/li&gt;
&lt;li&gt;ทำการกำหนดให้ IAM User ที่ต้องการให้สามารถอ่านข้อมูล object ใน Amazon S3 บน bucket ที่ระบุไว้ผ่าน Bucket Policy (อย่าลืมเปลี่ยน AWS_ACCOUNT_ID กับชื่อของ bucket&lt;/li&gt;
&lt;li&gt;ผู้ใช้งานยังสามารถกำหนด policy เฉพาะส่วนของ prefix ที่ต้องการได้ เพื่อความปลอดภัยที่มากขึ้นได้
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"s3-presigned-read-only"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"AWS"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:iam::&amp;lt;AWS_ACCOUNT_ID&amp;gt;:user/presigned"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"s3:GetObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::nutchanon-thailand-shared/*"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 3: สร้าง presigned URL ของ Amazon S3 ผ่าน AWS CLI
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ทำการติดตั้ง AWS CLI และสร้าง configuration profile ให้เรียบร้อย&lt;/li&gt;
&lt;li&gt;จากนั้นสร้าง presigned URL ด้วย command ดังต่อไปนี้

&lt;ul&gt;
&lt;li&gt;โดยผู้ใช้งานสามารถเลือก option "--expires-in" ในการกำหนดเวลาที่จะให้ presigned URL หมดอายุในหลักวินาทีได้อีกด้วย
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3 presign s3://&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;S3_BUCKET&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;S3_OBJECT&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;--expires-in&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;S3_EXPIRE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;--profile&lt;/span&gt; default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;ผู้ใช้งานจะได้รับ presigned URL เป็น response ที่สามารถนำไปแชร์ให้กับผู้อื่นได้ &lt;/li&gt;
&lt;li&gt;นอกจากวิธีการสร้าง presigned URL ผ่าน AWS CLI แล้ว ผู้ใช้งานยังสามารถสร้างจาก AWS SDK ในภาษาต่าง ๆ ได้อีกด้วย&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  บทสรุป
&lt;/h2&gt;

&lt;p&gt;ผู้ใช้งานสามารถเลือกที่จะแชร์ข้อมูลบน Amazon S3 ผ่าน Presigned URL ที่สามารถกำหนดให้ผู้อื่นเข้าถึงข้อมูลแบบชั่วคราวได้ โดยจะเป็นการเพิ่มความปลอดภัยให้กับข้อมูล และยังช่วยให้ผู้ใช้งานไม่ต้องจดจำสิทธิหรือ configuration ต่าง ๆ&lt;/p&gt;

&lt;p&gt;นอกจากนี้การทำ presigned URL บน Amazon S3 ยังสามารถนำไปประยุกต์ใช้กับระบบ automation ได้หลากหลาย ทั้งการติดต่อกับ Amazon API Gateway ในกรณีที่ต้องการ upload/download ข้อมูลขนาดใหญ่ผ่าน API ได้อีกด้วย[3]&lt;/p&gt;

&lt;h2&gt;
  
  
  แหล่งอ้างอิงอื่น ๆ
&lt;/h2&gt;

&lt;p&gt;[1] &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html&lt;/a&gt;&lt;br&gt;
[2] &lt;a href="https://github.com/nutchanon-l/s3-presigned-url" rel="noopener noreferrer"&gt;https://github.com/nutchanon-l/s3-presigned-url&lt;/a&gt;&lt;br&gt;
[3] &lt;a href="https://aws.amazon.com/blogs/compute/uploading-to-amazon-s3-directly-from-a-web-or-mobile-application/" rel="noopener noreferrer"&gt;https://aws.amazon.com/blogs/compute/uploading-to-amazon-s3-directly-from-a-web-or-mobile-application/&lt;/a&gt;&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3pp3cc9du87hqg20ugb.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3pp3cc9du87hqg20ugb.jpg" alt="CastleArm"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>awsthai</category>
      <category>s3</category>
      <category>presigned</category>
    </item>
    <item>
      <title>การทำ encrypt AWS Lambda Environment Variables ผ่าน AWS KMS</title>
      <dc:creator>Nutchanon Leelapornudom</dc:creator>
      <pubDate>Tue, 21 Sep 2021 03:38:56 +0000</pubDate>
      <link>https://forem.com/awscommunity-asean/encrypt-aws-lambda-environment-variables-aws-kms-177n</link>
      <guid>https://forem.com/awscommunity-asean/encrypt-aws-lambda-environment-variables-aws-kms-177n</guid>
      <description>&lt;h2&gt;
  
  
  สารบัญ (Table of Content)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;บทนำ&lt;/li&gt;
&lt;li&gt;แผนผังของระบบ&lt;/li&gt;
&lt;li&gt;การประเมินราคาเบื้องต้น&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 1: สร้าง AWS Lambda Function&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 2: สร้าง CMK บน AWS Key Management Service (KMS)&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 3.1: ทำการ encrypt Lambda Environment Variables ผ่าน AWS Management Console&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 3.2: ทำการ encrypt Lambda Environment Variables ผ่าน AWS CloudFormation&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 3.3: ทำการ encrypt Lambda Environment Variables ผ่าน AWS Serverless Application Model (SAM)&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 4: ทดลองเข้าใช้งานบน IAM User อื่น&lt;/li&gt;
&lt;li&gt;บทสรุป&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  บทนำ
&lt;/h2&gt;

&lt;p&gt;ในการใช้งาน AWS Lambda หลาย ๆ ครั้ง ผู้ใช้งานมักจะมีการเขียนข้อมูล parameter ที่ใช้ในการทำ Authetication กับระบบอื่น ๆ อย่าง Database Username/Password หรือ API Key บน Environment variables เพื่อให้ง่ายต่อการเรียกใช้งานหรือแก้ไข&lt;/p&gt;

&lt;p&gt;แม้ว่าผู้ใช้งานจะมีการปกป้องข้อมูลเหล่านั้นด้วยการใช้ Secrets Key/Value Software อย่าง AWS Systems Manager Parameter Store หรือ AWS Secrets Manager บน template อย่าง AWS CloudFormation หรือ AWS Serverless Application Model (SAM) แต่อย่างไรก็ตาม เมื่อตัว AWS Lambda Function ถูก deploy ในระบบแล้ว จะพบว่าผู้ใช้งาน สามารถเข้าไปยังหน้า AWS Management Console แล้วมองเห็นค่าจริงบน Environment variables ได้อยู่ดี&lt;/p&gt;

&lt;p&gt;ในบทความนี้ จะเป็นวิธีการนำ AWS Key Management Service (KMS) เข้ามาช่วยในการปกป้อง Environment variables ของ AWS Lambda ไม่ให้ผู้ใช้งานที่ไม่มีสิทธิในการเข้าถึงข้อมูลเหล่านี้ สามารถมองเห็นข้อมูลได้&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  แผนผังของระบบ (Architecture Diagram)
&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2owzm97avsqjq720ws7r.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2owzm97avsqjq720ws7r.png" alt="Diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  การประเมินราคาเบื้องต้น (Cost Estimation)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ราคาการเรียกใช้งาน Lambda - &lt;a href="https://aws.amazon.com/lambda/pricing/" rel="noopener noreferrer"&gt;AWS Lambda Pricing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ราคาการเรียกใช้งาน KMS - &lt;a href="https://aws.amazon.com/kms/pricing/" rel="noopener noreferrer"&gt;AWS KMS Pricing&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 1: สร้าง AWS Lambda Function
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;กรณีที่มีการใช้ AWS Lambda อยู่แล้ว สามารถใช้ตัวเดิมได้เลย&lt;/li&gt;
&lt;li&gt;เลือกตรวจสอบ Configuration -&amp;gt; Environment variables
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0wylwr4krqdbtfqbmdwy.png" alt="LambdaEnv"&gt;

&lt;ul&gt;
&lt;li&gt;โดยจะพบว่า ปกติแล้วจะมองเห็นค่า key/value ของ Environment variables ในลักษณะของ plain text เลย แม้ว่าจะมีการเขียน configuration ของ CloudFormation[1] หรือ Serverless Application Model (SAM)[2] ให้ทำการอ่านข้อมูลจาก AWS Systems Manager - Parameter Store หรือ AWS Secrets Manager ก็ตาม&lt;/li&gt;
&lt;li&gt;ส่งผลให้เกิด security risk ที่เกิดขึ้นในระบบ โดยผู้ใช้งานอื่น ๆ สามารถเข้ามาดูข้อมูลใน AWS Lambda ได้ แม้ว่าจะมีการแยก IAM User ให้กับแต่ละผู้ใช้งานแล้วก็ตาม&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 2: สร้าง CMK บน AWS Key Management Service (KMS)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ให้ทำการตรวจสอบ Lambda Execution Role จาก Configuration -&amp;gt; Permission
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0li6is5fvjph0oshnqq2.png" alt="LambdaRole"&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;สร้าง CMK ด้วย การเลือก Symmetric Key&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5lii0vsq34x43cruae9c.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5lii0vsq34x43cruae9c.png" alt="Symmetric"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ตั้งชื่อให้กับ CMK Key&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F08nx05vey24hiho7g1le.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F08nx05vey24hiho7g1le.png" alt="CMK"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;เลือก key administrator (ในตัวอย่างเลือก IAM Role ของ account)&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi89mym46zfktt9sdae77.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi89mym46zfktt9sdae77.png" alt="KeyAdmin"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;เลือก grant access ให้กับ IAM Role - โดยให้เลือกให้กับ Lambda Execution Role&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyppjc7fyc2w258t204bk.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyppjc7fyc2w258t204bk.png" alt="Keygrant"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 3.1: ทำการ encrypt Lambda Environment Variables ผ่าน AWS Management Console
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ไปที่ Lambda Function -&amp;gt; Configuration -&amp;gt; Environment variables แล้วเลือก "Edit" ที่ด้านขวาบน&lt;/li&gt;
&lt;li&gt;จากนั้นให้เลือก Encryption Configuration แล้วเลือก CMK ที่สร้างมา
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8x08w3iy80w880m7bmcq.png" alt="CMKEncrypt"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;ℹ️  หมายเหตุ: จะเห็นว่ามีอีก option ให้ผู้ใช้งานสามารถเลือก Encryption in transit ได้ โดยจะเป็นการ encrypt value ของ Environment variables ให้อยู่ในรูป BASE64 โดยต่อให้ผู้ใช้งานมีสิทธิมองเห็นค่าของ Environment variables ก็จะไม่สามารถดูเนื้อข้อมูลจริงได้ แต่การนำข้อมูลไปใช้งานต่อ ต้องทำการ decrypt ผ่าน CMK และ BASE64 ก่อนด้วย[3]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 3.2: ทำการ encrypt Lambda Environment Variables ผ่าน AWS CloudFormation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ตัวอย่าง AWS CloudFormation สำหรับ Lambda ที่ต้องใส่ให้ถูกต้องคือ "Role" และ "KmsKeyArn" (อย่าลืมแก้ไข AWS_ACCOUNT_ID)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;AWSTemplateFormatVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2010-09-09'&lt;/span&gt;
&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Lambda function demo&lt;/span&gt;
&lt;span class="na"&gt;Resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;HelloworldCFN&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;AWS::Lambda::Function&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;FunctionName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HelloworldCFN&lt;/span&gt;
      &lt;span class="na"&gt;Runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3.9&lt;/span&gt;
      &lt;span class="na"&gt;Role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arn:aws:iam::&amp;lt;AWS_ACCOUNT_ID&amp;gt;:role/service-role/HelloWorld-role-nj8898dr&lt;/span&gt;
      &lt;span class="na"&gt;Handler&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;index.lambda_handler&lt;/span&gt;
      &lt;span class="na"&gt;Code&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;ZipFile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;import json&lt;/span&gt;

          &lt;span class="s"&gt;def lambda_handler(event, context):&lt;/span&gt;
          &lt;span class="s"&gt;# TODO implement&lt;/span&gt;
            &lt;span class="s"&gt;return {&lt;/span&gt;
            &lt;span class="s"&gt;'statusCode': 200,&lt;/span&gt;
            &lt;span class="s"&gt;'body': json.dumps('Hello from Lambda!')&lt;/span&gt;
            &lt;span class="s"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;Environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;Variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;db_user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nutcha&lt;/span&gt;
          &lt;span class="na"&gt;db_pass&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nutchapass&lt;/span&gt;
      &lt;span class="na"&gt;KmsKeyArn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arn:aws:kms:ap-southeast-1:&amp;lt;AWS_ACCOUNT_ID&amp;gt;:key/f102024f-3ab8-4da9-8e80-13e163aa5cf9&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚠️ คำเตือน: ในการระบุ Environment variables ใน AWS CloudFormation ในการใช้งานจริง ควรใช้คู่กับ AWS Systems Manager - Parameter Store หรือ AWS Secrets Manager แทนการฝัง (hard coded) ตัว username และ password ไว้ใน template&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 3.3: ทำการ encrypt Lambda Environment Variables ผ่าน AWS Serverless Application Model (SAM)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ตัวอย่าง AWS Serverless Application Model (SAM) สำหรับ Lambda ที่ต้องใส่ให้ถูกต้องคือ "Role" และ "KmsKeyArn" (อย่าลืมแก้ไข AWS_ACCOUNT_ID)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;AWSTemplateFormatVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2010-09-09'&lt;/span&gt;
&lt;span class="na"&gt;Transform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::Serverless-2016-10-31&lt;/span&gt;
&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Sample SAM Template for Lambda Helloworld&lt;/span&gt;
&lt;span class="na"&gt;Resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;HelloWorldFunction&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;AWS::Serverless::Function&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;FunctionName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HelloworldSAM&lt;/span&gt;
      &lt;span class="na"&gt;CodeUri&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hello_world/&lt;/span&gt;
      &lt;span class="na"&gt;Handler&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app.lambda_handler&lt;/span&gt;
      &lt;span class="na"&gt;Runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3.8&lt;/span&gt;
      &lt;span class="na"&gt;Role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arn:aws:iam::&amp;lt;AWS_ACCOUNT_ID&amp;gt;:role/service-role/HelloWorld-role-nj8898dr&lt;/span&gt;
      &lt;span class="na"&gt;KmsKeyArn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arn:aws:kms:ap-southeast-1:&amp;lt;AWS_ACCOUNT_ID&amp;gt;:key/f102024f-3ab8-4da9-8e80-13e163aa5cf9&lt;/span&gt;
      &lt;span class="na"&gt;Environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;Variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;db_user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nutcha&lt;/span&gt;
          &lt;span class="na"&gt;db_pass&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nutchapass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚠️ คำเตือน: ในการระบุ Environment variables ใน AWS Serverless Application Model (SAM) ในการใช้งานจริง ควรใช้คู่กับ AWS Systems Manager - Parameter Store หรือ AWS Secrets Manager แทนการฝัง (hard coded) ตัว username และ password ไว้ใน template&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 4: ทดลองเข้าใช้งานบน IAM User อื่น
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ทดลองเข้าใช้งาน IAM User อื่น ที่แม้มีสิทธิ "AWSLambda_FullAccess" ก็จะไม่สามารถมองเห็นข้อมูลได้
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftxrw1g8pur7yw7w1yw0o.png" alt="LambdaAccess"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  บทสรุป
&lt;/h2&gt;

&lt;p&gt;ผู้ใช้งานสามารถทำการปกป้องข้อมูลใน Environment variables ของ AWS Lambda ได้โดยการใช้ CMK บน AWS KMS โดยเฉพาะผู้ที่มีสิทธิ์ถอดรหัส (decrypt) เท่านั้นที่จะสามารถมองเห็นค่าใน Environment variables บน AWS Management Console ได้&lt;/p&gt;

&lt;p&gt;โดยการเข้ารหัส (encrypt) นั้น ผู้ใช้งานสามารถทำได้ทั้งผ่าน AWS Management Console, AWS CloudFormation และ AWS Serverless Application Model (SAM)&lt;/p&gt;

&lt;h2&gt;
  
  
  แหล่งอ้างอิงอื่น ๆ
&lt;/h2&gt;

&lt;p&gt;[1] &lt;a href="https://aws.amazon.com/th/cloudformation/" rel="noopener noreferrer"&gt;https://aws.amazon.com/th/cloudformation/&lt;/a&gt;&lt;br&gt;
[2] &lt;a href="https://aws.amazon.com/serverless/sam/" rel="noopener noreferrer"&gt;https://aws.amazon.com/serverless/sam/&lt;/a&gt;&lt;br&gt;
[3] &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-encryption" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-encryption&lt;/a&gt;&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3pp3cc9du87hqg20ugb.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3pp3cc9du87hqg20ugb.jpg" alt="CastleArm"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>awsthai</category>
      <category>lambda</category>
      <category>kms</category>
    </item>
    <item>
      <title>วิธีการสร้างกราฟข้อมูลจาก Amazon DynamoDB ด้วย Amazon QuickSight</title>
      <dc:creator>Nutchanon Leelapornudom</dc:creator>
      <pubDate>Tue, 14 Sep 2021 03:20:25 +0000</pubDate>
      <link>https://forem.com/awscommunity-asean/amazon-dynamodb-amazon-quicksight-4mcb</link>
      <guid>https://forem.com/awscommunity-asean/amazon-dynamodb-amazon-quicksight-4mcb</guid>
      <description>&lt;h2&gt;
  
  
  สารบัญ (Table of Content)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;บทนำ&lt;/li&gt;
&lt;li&gt;แผนผังของระบบ&lt;/li&gt;
&lt;li&gt;การประเมินราคาเบื้องต้น&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 1: เตรียมความพร้อมของ AWS Services&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 2: สร้าง Amazon Athena Data source&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 3: ทดลอง Query ข้อมูล DynamoDB ผ่าน Amazon Athena&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 4: เชื่อมต่อ Amazon QuickSight กับ Amazon Athena ด้วย Federated Query feature&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 5: สร้าง QuickSight Dataset จาก DynamoDB ผ่าน Athena&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 6: ทดลองสร้าง QuickSight Analyse จาก DynamoDB Dataset&lt;/li&gt;
&lt;li&gt;บทสรุป&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  บทนำ
&lt;/h2&gt;

&lt;p&gt;บางครั้งในองค์กร อาจจะมีความต้องการที่จะนำข้อมูลที่อยู่ในระบบฐานข้อมูล (database) อย่าง Amazon DynamoDB, Amazon DocumentDB, Apache HBase, และอื่น ๆ นำมาแสดงผลในรูปของกราฟ (graph) หรือสร้าง dashboard เพื่อวิเคราะห์ หา insights จากข้อมูล&lt;/p&gt;

&lt;p&gt;ทาง AWS มี service ที่ใช้สำหรับทำ Business Intelligent (BI) tool ชื่อว่า Amazon QuickSight โดยสามารถใช้ service ในการสร้างกราฟหรือ dashboard จากฐานข้อมูลที่รองรับได้ เช่น Amazon RDS and Aurora, Amazon S3, Amazon Athena, และอื่น ๆ &lt;/p&gt;

&lt;p&gt;แต่ Amazon QuickSight ไม่ได้มี native support ระบบฐานข้อมูลแบบ NoSQL เช่น Amazon DynamoDB, Amazon DocumentDB เป็นต้น ทำให้ผู้ใช้งานต้องทำการย้ายข้อมูลไปยังถังข้อมูลอื่น ๆ ซึ่งจะเกิด overhead ในส่วนของ data synchronization และ การจัดการ application ที่ใช้ย้ายข้อมูล&lt;/p&gt;

&lt;p&gt;บทความนี้จะแสดงวิธีการเชื่อมต่อระหว่าง Amazon QuickSight ไปยังระบบฐานข้อมูลแบบ NoSQL เช่น Amazon DynamoDB โดยตรง โดยไม่มีการย้ายข้อมูลจากต้นทาง และทำให้ข้อมูลที่แสดงอยู่ในกราฟ มีความถูกต้องเหมือนข้อมูลต้นทาง&lt;br&gt;
&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  แผนผังของระบบ (Architecture Diagram)
&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr95r7hnbyynmf4j2vyud.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr95r7hnbyynmf4j2vyud.png" alt="Architecture Diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  การประเมินราคาเบื้องต้น (Cost Estimation)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ราคา Storage และ Read Capacity Unit (RCU) ของ DynamoDB - &lt;a href="https://aws.amazon.com/dynamodb/pricing/" rel="noopener noreferrer"&gt;Amazon DynamoDB Pricing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ราคา Data Scan ของ Athena - &lt;a href="https://aws.amazon.com/th/athena/pricing/" rel="noopener noreferrer"&gt;Amazon Athena Pricing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ราคา User และ SPICE ของ QuickSight - &lt;a href="https://aws.amazon.com/quicksight/pricing/" rel="noopener noreferrer"&gt;Amazon QuickSight Pricing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ราคา Storage ของ S3 - &lt;a href="https://aws.amazon.com/s3/pricing" rel="noopener noreferrer"&gt;Amazon S3 Pricing&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;ℹ️  หมายเหตุ: อาจจะมีราคาอีกนิดหน่อยในส่วนของ Lambda, Network ที่ยังไม่ได้รวม&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  ขั้นตอนที่ 1: เตรียมความพร้อมของ AWS Services
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;เริ่มใช้งาน Amazon Athena โดยต้องเป็น engine version 2 และกำหนด S3 Result Data bucket (e.g. nutchanon-athena-query-results)
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fye01n9o87zsf59t6s2zn.png" alt="AthenaS3"&gt;
&lt;/li&gt;
&lt;li&gt;สร้าง Amazon S3 สำหรับ Spill Bucket Data ของ Athena
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foal0s3mw6nlnevb02cqc.png" alt="Spill"&gt;
&lt;/li&gt;
&lt;li&gt;เริ่มใช้งาน Amazon QuickSight โดยการ Setup - &lt;a href="https://docs.aws.amazon.com/quicksight/latest/user/setting-up.html" rel="noopener noreferrer"&gt;Setting Up for Amazon QuickSight&lt;/a&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frsirfu1rctrua2x9xwzn.png" alt="QuickSightStart"&gt;
&lt;/li&gt;
&lt;li&gt;ตรวจสอบข้อมูลใน DynamoDB Table (e.g.quicksight-ddb) ว่าพร้อมสำหรับใช้งาน
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fld0ayp6c54bua1qjttfv.png" alt="DDBData"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;ℹ️  หมายเหตุ: โดยหากสำหรับผู้ที่ยังไม่มีข้อมูล DynamoDB ที่ใช้ในการทดลองสามารถดูวิธีการนำข้อมูลตัวอย่างจาก CSV file เข้าใน DynamoDB Table ได้จาก &lt;a href="https://dev.to/awscommunity-asean/csv-amazon-s3-amazon-dynamodb-3i2f"&gt;วิธีการนำข้อมูล CSV จาก Amazon S3 เข้า Amazon DynamoDB&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  ขั้นตอนที่ 2: สร้าง Amazon Athena Data source
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;สร้าง Data Source ใหม่จาก "Connect data source"
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgkvfsggc8bajzan6qxkn.png" alt="AthenaData"&gt;
&lt;/li&gt;
&lt;li&gt;เลือก "Query a data source" และ "Amazon DynamoDB"
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7u8bs46kvkvbrnrvg3ad.png" alt="AtDataSrc"&gt;
&lt;/li&gt;
&lt;li&gt;เลือก "Configure new AWS Lambda function" เพื่อสร้าง Lambda Connector
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj6ubq2qqcol4e8218xvt.png" alt="Lambda Connector"&gt;
&lt;/li&gt;
&lt;li&gt;เลือก "SpillBucket", "AthenaCatalogName" และยืนยัน "Custom IAM Roles" แล้วกด "Deploy" จากนั้นระบบจะทำการสร้าง Cloudformation สำหรับ Lambda Connector ให้
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr2wk9f5jbpzyu03e4axk.png" alt="LambdaConfig"&gt;
&lt;/li&gt;
&lt;li&gt;กลับมาเลือก Lambda Connector ที่เพิ่งสร้าง (อาจจะต้องกด refresh 1 ครั้ง) แล้วตั้งชื่อ catalog ให้เรียบร้อย
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faejudjaod01k4z78alqu.png" alt="Lambda Connector2"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  ขั้นตอนที่ 3: ทดลอง Query ข้อมูล DynamoDB ผ่าน Amazon Athena
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;เลือก "Data Source" เป็น catalog name ที่เพิ่งสร้าง หลังจากนั้นจะปรากฏข้อมูล table ของ DynamoDB ให้ทำการ select ข้อมูลดู
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fymuno0t7uvrdjm8towj4.png" alt="AthenaDDB"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  ขั้นตอนที่ 4: เชื่อมต่อ Amazon QuickSight กับ Amazon Athena ด้วย Federated Query feature
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;เปลี่ยน QuickSight region ไปที่ N.Virginia เพื่อแก้ไข configuration และเลือกไปที่ "Manage QuickSight"
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyd8b95u33l13d0f2kvh3.png" alt="QSRegion"&gt;
&lt;/li&gt;
&lt;li&gt;จองข้อมูล SPICE Capacity ให้เรียบร้อย (อ่านว่า SPICE คืออะไร ได้จาก &lt;a href="https://docs.aws.amazon.com/quicksight/latest/user/managing-spice-capacity.html" rel="noopener noreferrer"&gt;Managing SPICE Capacity&lt;/a&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg46tuju17simz020gvsi.png" alt="QSSPICEAllocate"&gt;
&lt;/li&gt;
&lt;li&gt;ในส่วนของ "Security &amp;amp; Permission" ให้เลือก "Add or Remove"
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4zfz0knssdxgr19bu5cx.png" alt="QSAdminSec"&gt;
&lt;/li&gt;
&lt;li&gt;ให้เลือก Amazon Athena (หากเลือกอยู่แล้ว ให้กด 2 ครั้ง) จะมีหน้าต่างให้เลือก permission สำหรับ Amazon S3 ให้เลือก Athena Spill และ Result Data Bucket พร้อมกับ write permission
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmal9fmynwzu4ehnh03nb.png" alt="QSPermission"&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdplbglzzqggqu31xuaqp.png" alt="QSS3"&gt;
&lt;/li&gt;
&lt;li&gt;เปลี่ยน QuickSight region ไปที่ Singapore (หรือต้นทางที่ใช้งาน) เพื่อเตรียมพร้อมสำหรับการสร้าง Dataset&lt;/li&gt;
&lt;li&gt;กลับไปที่หน้า AWS Management Console และไปยัง "IAM" Service และไปยัง IAM Role&lt;/li&gt;
&lt;li&gt;เพิ่ม policy ที่ IAM Role "aws-quicksight-s3-consumers-role-v0" ที่ทางระบบจะสร้างให้อัตโนมัติหลังจาก grant S3 permission ใน QuickSight
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fas7jsb2eyhe84ynmecgw.png" alt="QSIAMRole"&gt;
โดยทำการเพิ่ม "inline policy" ชื่อ "InvokeAthenaFedereted" ตาม JSON ด้านล่าง&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️  อย่าลืมแก้ "aws_account_id" และ Lambda Function name ที่กำหนดไว้ในขั้นตอนที่ 2 (ตัว "AthenaCatalogName")&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"InvokeAthenaFedereted"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lambda:InvokeFunction"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:lambda:ap-southeast-1:&amp;lt;aws_account_id&amp;gt;:function:dynamocatalog"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 5: สร้าง QuickSight Dataset จาก DynamoDB ผ่าน Athena
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;เลือกสร้าง Dataset จาก Athena Data Source โดยให้ตั้งชื่อ connection เช่น "athena-dynamodb"
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzl43y44pat7g4udhebj6.png" alt="QSAthenaDDB"&gt;
&lt;/li&gt;
&lt;li&gt;เลือก catalog name ที่สร้างเอาไว้ (ชื่อเดียวกับที่สร้างไว้ในขั้นตอนที่ 2) และ table ให้เรียบร้อย
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feo5j1bxs9rk24wx7i3gd.png" alt="QSCatalog"&gt;
&lt;/li&gt;
&lt;li&gt;เลือกสร้างข้อมูลจาก SPICE
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F25fu73ywfcogbr4ffb52.png" alt="QSSPICE"&gt;
&lt;/li&gt;
&lt;li&gt;รอจน import data เข้าไปที่ SPICE ให้เรียบร้อย
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3mzvhrxsashep79rspig.png" alt="QSSPICE/"&gt;
&lt;/li&gt;
&lt;li&gt;เปลี่ยน data type ของแต่ละ column ให้เหมาะสมกับต้นทาง ซึ่งจะมีผลกับการนำไปสร้างกราฟต่อ ๆ ไป
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foee5q3kdtklry6m2ozap.png" alt="QSDataType"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 6: ทดลองสร้าง QuickSight Analyse จาก DynamoDB Dataset
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ทดลองสร้างกราฟ จะพบว่า สามารถสร้างกราฟต่าง ๆ จากข้อมูล DynamoDB ได้โดยตรง
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fen839wel301qbs9w7bc0.png" alt="QSAnalyse"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;ℹ️  หมายเหตุ: การเปลี่ยน data type ของแต่ละ column ใน dataset มีผลต่อการสร้างกราฟอย่างมาก&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  บทสรุป
&lt;/h2&gt;

&lt;p&gt;Amazon QuickSight สามารถเชื่อมต่อโดยตรงกับระบบฐานข้อมูล หรือ data source ที่ไม่ได้ support โดยตรงผ่าน Amazon Athena Federeted Query ได้ โดยผู้ใช้งานสามารถสร้าง Lambda Connector ไปเชื่อมต่อระบบฐานข้อมูลอย่าง Amazon DynamoDB หรือ Amazon DocumentDB ได้&lt;/p&gt;

&lt;p&gt;ซึ่งจะช่วยให้ผู้ใช้งาน สามารถสร้างกราฟจากข้อมูลต่าง ๆ ที่อยู่บนระบบฐานข้อมูลโดยไม่จำเป็นต้องย้ายข้อมูลไปที่อื่น ไม่จำเป็นต้องจัดการ application ที่ใช้สำหรับย้ายข้อมูล และยังได้ข้อมูลที่นำมาแสดงผลแบบ real-time อีกด้วย&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3pp3cc9du87hqg20ugb.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3pp3cc9du87hqg20ugb.jpg" alt="CastleArm"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  แหล่งอ้างอิง
&lt;/h3&gt;

&lt;p&gt;[1] &lt;a href="https://aws.amazon.com/blogs/big-data/accessing-and-visualizing-data-from-multiple-data-sources-with-amazon-athena-and-amazon-quicksight/" rel="noopener noreferrer"&gt;https://aws.amazon.com/blogs/big-data/accessing-and-visualizing-data-from-multiple-data-sources-with-amazon-athena-and-amazon-quicksight/&lt;/a&gt;&lt;br&gt;
[2] &lt;a href="https://aws.amazon.com/blogs/big-data/query-any-data-source-with-amazon-athenas-new-federated-query/" rel="noopener noreferrer"&gt;https://aws.amazon.com/blogs/big-data/query-any-data-source-with-amazon-athenas-new-federated-query/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>awsthai</category>
      <category>quicksight</category>
      <category>dynamodb</category>
    </item>
    <item>
      <title>วิธีการนำข้อมูล CSV จาก Amazon S3 เข้า Amazon DynamoDB</title>
      <dc:creator>Nutchanon Leelapornudom</dc:creator>
      <pubDate>Tue, 07 Sep 2021 05:16:20 +0000</pubDate>
      <link>https://forem.com/awscommunity-asean/csv-amazon-s3-amazon-dynamodb-3i2f</link>
      <guid>https://forem.com/awscommunity-asean/csv-amazon-s3-amazon-dynamodb-3i2f</guid>
      <description>&lt;h2&gt;
  
  
  สารบัญ (Table of Content)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;บทนำ&lt;/li&gt;
&lt;li&gt;แผนผังของระบบ&lt;/li&gt;
&lt;li&gt;การประเมินราคาเบื้องต้น&lt;/li&gt;
&lt;li&gt;ข้อจำกัดของตัวอย่างที่ควรรู้&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 1: นำข้อมูลตัวอย่างเข้า Amazon S3&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 2: สร้าง DynamoDB Table และเตรียม configuration&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 3: สร้าง Lambda Function และเตรียม configuration&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 4: Copy python code สำหรับ import ไปยัง Lambda&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 5: Execute Lambda Function&lt;/li&gt;
&lt;li&gt;ขั้นตอนที่ 6: ตรวจสอบข้อมูลที่ import ที่ DynamoDB&lt;/li&gt;
&lt;li&gt;วิธีการอื่น ๆ เพิ่มเติม&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  บทนำ
&lt;/h2&gt;

&lt;p&gt;หลาย ๆ ครั้ง ผู้ใช้งานมีความต้องการที่จะนำข้อมูล จากระบบฐานข้อมูลแบบตาราง (RDBMS) ซึ่งอยู่ในรูปแบบ CSV file นำเข้า (import) ไปยังระบบฐานข้อมูลแบบ NoSQL อย่างเช่น Amazon DynamoDB เป็นต้น และผู้ใช้งานพบว่า Amazon DynamoDB ไม่ได้มี feature อย่างเช่นการ import โดยตรง ทำให้ผู้ใช้งาน พบปัญหาเกี่ยวกับการเขียน application ขึ้นมาเอง และวิธีการกำหนดสิทธิต่าง ๆ&lt;/p&gt;

&lt;p&gt;ในบทความนี้จะเป็นตัวอย่างของการนำข้อมูล CSV file เข้า Amazon DynamoDB โดยมีวิธีการ รวมถึงตัวอย่าง code ที่ผู้ใช้งานสามารถนำไปปรับใช้ให้เหมาะสมกับข้อมูลที่ผู้ใช้งานต้องการได้อีกด้วย&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  แผนผังของระบบ (Architecture Diagram)
&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv0311a587n0vulf9x7be.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv0311a587n0vulf9x7be.png" alt="Architect"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  การประเมินราคาเบื้องต้น (Cost Estimation)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ราคา Storage, Write Capacity Unit (WCU) และ Read Capacity Unit (RCU) ของ DynamoDB - &lt;a href="https://aws.amazon.com/dynamodb/pricing/" rel="noopener noreferrer"&gt;Amazon DynamoDB Pricing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ราคา Storage ของ S3 - &lt;a href="https://aws.amazon.com/s3/pricing" rel="noopener noreferrer"&gt;Amazon S3 Pricing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ราคา Invocation ของ Lambda - &lt;a href="https://aws.amazon.com/lambda/pricing/" rel="noopener noreferrer"&gt;AWS Lambda Pricing&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;ℹ️  หมายเหตุ: อาจจะมีราคาอีกนิดหน่อยในส่วนของ Network ที่ยังไม่ได้รวม&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ข้อจำกัดของตัวอย่างที่ควรรู้
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;CSV file จะต้องมี header อยู่ที่ row แถวแรกของ file&lt;/li&gt;
&lt;li&gt;การกำหนด partition key ของ DynamoDB จะต้องชื่อตรงกับ column header name ที่อยู่ใน file แบบ case-sensitive (ตัวเล็กตัวใหญ่มีผล)&lt;/li&gt;
&lt;li&gt;Lambda resource และ timeout configuration ควรปรับเปลี่ยนให้เหมาะสมกับขนาดของข้อมูล&lt;/li&gt;
&lt;li&gt;IAM Policy ของ Lambda Execution Role ควรกำหนดให้เหมาะสม เมื่อนำไปใช้งานจริง&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 1: นำข้อมูลตัวอย่างเข้า Amazon S3
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Download ข้อมูลตัวอย่าง &lt;a href="https://ee-assets-prod-us-east-1.s3.amazonaws.com/modules/337d5d05acc64a6fa37bcba6b921071c/v1/SaaS-Sales.csv" rel="noopener noreferrer"&gt;SaaS-Sales.csv&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Upload ข้อมูลตัวอย่างขึ้น S3 (e.g. nutchanon-ddb-importer)
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F06f87qk92l41e15d03jp.png" alt="UploadS3"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 2: สร้าง DynamoDB Table และเตรียม configuration
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;สร้าง DynamoDB Table ชื่อ "quicksight-ddb" โดยมี parition key ชื่อ "Row ID" (ตัวเล็กตัวใหญ่ มีผลต่อข้อมูลตัวอย่าง) และปรับ capacity mode เป็น On-Demand
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgfwbht7tmfn5v56kf6ls.png" alt="DDBCreation"&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzsqcgy8jxoartr5y79gq.png" alt="DDBCapacity"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 3: สร้าง Lambda Function และเตรียม configuration
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;สร้าง Lambda Function ด้วย python 3.9 (e.g. ddb-csv-importer)&lt;/li&gt;
&lt;li&gt;ปรับ Lambda resource และ timeout configuration ให้เป็น 256MB และ timeout 15 นาที 
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgvtsyr2fg3uaah5szzs4.png" alt="LambdaConfig"&gt;
&lt;/li&gt;
&lt;li&gt;จากนั้นเพิ่ม permission ให้ Lambda Execution Role สามารถอ่านข้อมูลจาก S3 และเขียนข้อมูลเข้า DynamoDB ได้ (DDBBatchWrite)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;สำหรับการทดสอบเท่านั้น&lt;/strong&gt; ในการใช้งานต้อง จะต้องมีการระบุ IAM policy ให้ restrict เฉพาะเท่าที่ใช้งานเท่านั้น&lt;/p&gt;
&lt;/blockquote&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgyhem45pvhf6yskoc7k4.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgyhem45pvhf6yskoc7k4.png" alt="LambdaPermission"&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsoq8b40sdj94qtj6mwtu.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsoq8b40sdj94qtj6mwtu.png" alt="S3Policy"&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fas81qqu616bo59wksipu.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fas81qqu616bo59wksipu.png" alt="DDBWritePolicy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 4: Copy python code สำหรับ import ไปยัง Lambda
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Copy Python Lambda code ตามด้านล่าง แล้วอย่าลืมเปลี่ยน configuration "s3_csv_bucket", "s3_csv_data", "ddb_table_src" ให้เป็นของผู้ใช้งานด้วย
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;codecs&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="n"&gt;s3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s3&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ddb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;dynamodb&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;s3_csv_bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nutchanon-ddb-importer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;# Source Amazon S3 bucket
&lt;/span&gt;&lt;span class="n"&gt;s3_csv_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SaaS-Sales.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;# Source Amazon S3 object file
&lt;/span&gt;&lt;span class="n"&gt;ddb_table_src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;quicksight-ddb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;# Target Amazon DynamoDB Table
&lt;/span&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="c1"&gt;# get data
&lt;/span&gt;    &lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Bucket&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s3_csv_bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s3_csv_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# json data
&lt;/span&gt;    &lt;span class="n"&gt;ddb_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DictReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;codecs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getreader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8-sig&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Body&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])):&lt;/span&gt;
        &lt;span class="n"&gt;ddb_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# define dynamodb table
&lt;/span&gt;    &lt;span class="n"&gt;ddb_table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ddb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ddb_table_src&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# batch write data to dynamodb table
&lt;/span&gt;    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;ddb_table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;batch_writer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ddb_data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 5: Execute Lambda Function
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;รัน execute บน Lambda function ด้วย test event ใด ก็ได้ รอจน return success
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpzlfqxb9uma1spy7gmq2.png" alt="LambdaResult"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ขั้นตอนที่ 6: ตรวจสอบข้อมูลที่ import ที่ DynamoDB
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ตรวจสอบข้อมูลใน DynamoDB Table ด้วย "Give live item count"
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpxlrefgvaq9ymak9d503.png" alt="DDBLiveItems"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  วิธีการอื่น ๆ เพิ่มเติม
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ทาง AWS Blog เองก็มีจะวิธีการในการ import ข้อมูลจาก Amazon S3 ไปยัง DynamoDB รวมถึงตัวอย่าง code ที่สามารถใช้งานได้ ดังต่อไปนี้

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/compute/creating-a-scalable-serverless-import-process-for-amazon-dynamodb/" rel="noopener noreferrer"&gt;Creating a scalable serverless import process for Amazon DynamoDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/aws-samples/s3-to-lambda-patterns/tree/master/ddbImporter" rel="noopener noreferrer"&gt;Github: S3-to-DynamoDB importer&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3pp3cc9du87hqg20ugb.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3pp3cc9du87hqg20ugb.jpg" alt="CastleArm"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>awsthai</category>
      <category>tutorial</category>
      <category>dynamodb</category>
    </item>
    <item>
      <title>10 วิธีลด Cost ในการใช้งาน Elasticsearch บน AWS</title>
      <dc:creator>Nutchanon Leelapornudom</dc:creator>
      <pubDate>Wed, 01 Sep 2021 16:24:24 +0000</pubDate>
      <link>https://forem.com/awscommunity-asean/10-cost-elasticsearch-aws-29k</link>
      <guid>https://forem.com/awscommunity-asean/10-cost-elasticsearch-aws-29k</guid>
      <description>&lt;h2&gt;
  
  
  สารบัญ (Table of Contents)
&lt;/h2&gt;

&lt;p&gt;0. บทนำ&lt;br&gt;
1. ลบข้อมูลที่ไม่จำเป็น&lt;br&gt;
2. จำแนกข้อมูลที่ไม่เกี่ยวข้องกัน แบ่งออกเป็นหลาย ๆ Index&lt;br&gt;
3. กำหนด Data Lifecycle Management Policy&lt;br&gt;
4. รวบรวม Elasticsearch หลาย ๆ cluster ในองค์กร ให้เหมาะสม&lt;br&gt;
5. Right Sizing Elasticsearch Servers&lt;br&gt;
6. ไม่ใช้ dedicated master nodes ถ้า cluster ไม่ได้สำคัญ หรือไม่ใหญ่พอ&lt;br&gt;
7. ซื้อ ​Reserved Instance (RI)&lt;br&gt;
8. ย้ายมาใช้ Amazon Elasticsearch Service เพื่อลด maintenance และ Data Transfer Inter-AZ Cost&lt;br&gt;
9. เปลี่ยน Instance Type เป็น Graviton เพื่อ price/performance ที่ดีกว่า&lt;br&gt;
10. ใช้พระเอก/นางเอก UltraWarm และ Cold Storage features บน Amazon Elasticsearch Service&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  บทนำ
&lt;/h2&gt;

&lt;p&gt;Elasticsearch เป็น Search Engine NoSQL Database ที่มีการใช้งานเป็นวงกว้างและหลากหลาย ไม่ว่าจะเป็นการใช้งานการทำ Operational Logging, Log Analytics, การทำ Catalog Search หรือการทำ Index Table Searching ล้วนแล้วแต่เป็นการใช้งานที่จำเป็นต่อองค์กร และมักจะส่งผลให้เกิดค่าใช้จ่าย (cost) บน Elasticsearch cluster/servers ที่หลาย ๆ บริษัทอยากที่จะลดค่าใช้จ่ายในส่วนนี้ลง&lt;/p&gt;

&lt;p&gt;สำหรับวิธีเบื้องต้นในการลดค่าใช้จ่ายที่อยากจะมาแนะนำผู้ใช้งาน Elasticsearch ทั้งในส่วนที่เป็น self-managed (ติดตั้ง Elasticsearch software เอง บน IaaS อย่าง Amazon EC2) หรือจะเป็น AWS managed service อย่าง &lt;a href="https://aws.amazon.com/elasticsearch-service/" rel="noopener noreferrer"&gt;Amazon Elasticsearch Service&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. ลบข้อมูลที่ไม่จำเป็น
&lt;/h3&gt;

&lt;p&gt;สำหรับข้อแรก ที่ดูเหมือนจะทำง่ายแต่จริง ๆ แล้วทำยาก แต่รู้ไหมว่านี่คือวิธีที่ได้ผลที่สุดในการลดค่าใช้จ่าย Elasticsearch เนื่องด้วย mindset ส่วนใหญ่เวลามีการใช้งาน Elasticsearch โดยเฉพาะ Logging use case แล้ว มักจะเกิดเหตุการณ์ &lt;strong&gt;"เก็บ ๆ ไปก่อน ใช้ไม่ใช้ไม่รู้ แต่สักวันอาจจะได้ใช้"&lt;/strong&gt; ส่งผลให้เกิดค่าใช้จ่ายมหาศาลที่องค์กรต้องแบกรับ&lt;/p&gt;

&lt;p&gt;วิธีแก้คือ ถ้าไม่ค่อยได้ใช้ (อาจจะดูจาก Search/Bulk metrics ของแต่ละ Index) ให้ปรับเปลี่ยน mindset ของผู้จัดเก็บ เช่นเอาเฉพาะ ERROR log level มาเท่านั้น หรืออีกวิธีง่าย ๆ คือเปลี่ยนไปเก็บที่ storage engine อื่นที่ถูกกว่า อย่างเช่น Amazon S3 แล้วถ้าจะใช้ ค่อย load กลับไปเมื่อต้องใช้ หรือใช้ Amazon Athena ดึงข้อมูลแทน&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. จำแนกข้อมูลที่ไม่เกี่ยวข้องกัน แบ่งออกเป็นหลาย ๆ Index
&lt;/h3&gt;

&lt;p&gt;การทำการใด ๆ ก็ตามบน Elasticsearch มักจะอยู่ในรูปแบบของ Index (คล้าย ๆ Table ใน Relational Database) เช่นการเพิ่ม replica shard, ปรับ schema, หรือการลบข้อมูล เพราะฉะนั้นหากจำแนกข้อมูลที่ไม่เกี่ยวข้องกันให้อยู่ตามแต่ละ index ได้ จะส่งผลให้จัดการข้อมูล เช่นทำ compress, ย้ายไปยัง tier ต่าง ๆ, หรือลบ ได้อย่างสะดวกและเหมาะสม&lt;/p&gt;

&lt;p&gt;การจำแนกข้อมูลนี้ สามารถทำได้ในระดับ insight ที่รู้เนื้อหา เช่นแยก Logging ในแต่ละ Level -&amp;gt; INFO, ERROR, TRACE, DEBUG ออกจากกัน หรือแบ่งส่วน application, security, server logging แยกจากกัน หรือจะแบ่งตามวันเวลา เช่น daily, monthly เป็นต้น&lt;/p&gt;

&lt;p&gt;แต่ข้อควรระวังคือ ในแต่ละ Elasticsearch Cluster จะมี best practice index/shard sizing recommendation อยู่ ให้พยายาม design ให้อยู่ในกรอบนี้ (เกินได้นิดหน่อย) เพื่อให้ cluster stable[1]&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. กำหนด Data Lifecycle Management Policy
&lt;/h3&gt;

&lt;p&gt;Elasticsearch ใน version ใหม่ ๆ จะมาพร้อมกับ feature Index Management[2] ที่จะช่วยให้ผู้ใช้งานสามารถกำหนด policy ของ index ได้ ว่าจะให้ทำการ merge, ลด replica, ย้าย tier, ปรับ priority, หรือลบข้อมูลได้&lt;/p&gt;

&lt;p&gt;ต่อเนื่องจากข้อ 2 จะทำให้ผู้ใช้งานสามารถกำหนด policy ข้อมูล ตามการใช้งานจริงได้ เช่นข้อมูลที่สำคัญอย่าง security logging ให้ลบหลังจาก 2 ปี แต่ข้อมูลไม่สำคัญเช่น INFO logging อาจจะลบทุก ๆ 3 วัน เป็นต้น&lt;/p&gt;

&lt;p&gt;แต่หากใครที่ใช้ version เก่าหน่อย ก็ลองดูตัว open-source เช่น &lt;a href="https://github.com/elastic/curator" rel="noopener noreferrer"&gt;Curator&lt;/a&gt; ในการสร้าง policy ได้เช่นกัน&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. รวบรวม Elasticsearch หลาย ๆ cluster ในองค์กร ให้เหมาะสม
&lt;/h3&gt;

&lt;p&gt;ในการใช้งาน Elasticsearch จริง ๆ แล้วผู้ใช้งานสามารถแบ่ง tenancy ของการเข้าถึงข้อมูลผ่าน Index และกำหนดสิทธิในการเข้าถึงข้อมูลผ่าน Authorization feature บน Fine-Gain Access Control ซึ่งแทนที่ผู้ใช้งานจะทำการสร้าง Elasticsearch cluster ขึ้นมาหลาย ๆ อัน (บางครั้งสร้างตาม application ด้วยซ้ำ) สามารถใช้งาน cluster เดียว ในรูปแบบของ share resource ได้ ซึ่งก็จะช่วยให้ผู้ใช้งาน utilize server resource ได้อย่างเต็มที่ และลดค่าใช้จ่ายในภาพรวมได้&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Right Sizing Elasticsearch Servers
&lt;/h3&gt;

&lt;p&gt;ในการใช้งาน Elasticsearch resource ก็จะมีความคล้ายกับ database ทั่ว ๆ ไป คือ เมื่อมีขนาดของข้อมูลเยอะขึ้น จำนวน resource (CPU, Memory, Disk) ที่ต้องการก็มากขึ้นตาม ทำให้บางครั้งเกิดการ over-provisioning บน Elasticsearch cluster ขึ้นมาได้ โดยหากผู้ใช้ทำการจัดการข้อมูล (ตามขั้นตอน 1,2,3,4) แล้วอาจจะพบว่า ข้อมูลมีขนาดลดลง ต่อมาก็จะเป็นการเปิดกว้างให้ผู้ใช้งานทำการปรับขนาดของ Elasticsearch server ให้เหมาะสม โดยอาจจะทำการลด size ของ server ให้เท่ากับที่ใช้งานในช่วง peak hour ได้&lt;/p&gt;

&lt;p&gt;ซึ่งวิธีการปรับขนาดของ server ที่นิยมกันคือเพิ่ม (add) node ใหม่ที่มีขนาดเล็กกว่าเข้าไป แล้วค่อยถอด (remove) node ที่มีขนาดใหญ่กว่าออก เพื่อให้มี downtime น้อยที่สุดในการปรับเปลี่ยน server&lt;/p&gt;

&lt;p&gt;ทาง AWS ก็มี guideline ให้กับผู้ใช้งานเบื้องต้นในการ sizing cluster ทั้งในส่วนของ Storage -&amp;gt; &lt;a href="https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/sizing-domains.html#aes-bp-storage" rel="noopener noreferrer"&gt;Calculating storage requirements&lt;/a&gt; และ Instance -&amp;gt; &lt;a href="https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/sizing-domains.html#aes-bp-instances" rel="noopener noreferrer"&gt;Choosing instance types and testing&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  6. ไม่ใช้ dedicated master nodes ถ้า cluster ไม่ได้สำคัญ หรือไม่ใหญ่พอ
&lt;/h3&gt;

&lt;p&gt;การสร้าง Dedicated Master Node ถือเป็น Best Practice ใน production workload หรือ cluster ที่มีจำนวน shard และข้อมูลขนาดใหญ่ เพื่อ stability ของ cluster&lt;/p&gt;

&lt;p&gt;แต่ไม่ใช่ทุก cluster จำเป็นที่จะต้องมี dedicated master node โดยทางผู้ใช้สามารถกำหนด node role ให้เป็นได้ทั้ง master และ data ได้ โดยตัว node นั้นจะทำงานทั้งสองงาน ซึ่งแน่นอนว่าก็จะใช้ resource มากกว่าปกติ และอาจจะไม่ stable เท่า แต่หากคิดถึงการใช้งาน non-production หรือ project ที่ไม่ได้ต้องการ 9'4 uptime ก็จะช่วยลดค่าใช้จ่ายได้อย่างมาก เพราะ dedicated master nodes ก็ต้องใช้อย่างน้อย ๆ 3 nodes ขึ้นไป ถึงจะเกิด stability ของ cluster&lt;/p&gt;

&lt;p&gt;ตัว Amazon Elasticsearch Service ก็เปิดกว้างให้ผู้ใช้งานเลือกไม่มี dedicated master nodes ผ่าน "Custom" บน "Deployment Type" ด้วย&lt;/p&gt;

&lt;p&gt;ในส่วนของการ sizing dedicated master node ทาง AWS ก็มี guideline ให้กับผู้ใช้งาน &lt;a href="https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-managedomains-dedicatedmasternodes.html" rel="noopener noreferrer"&gt;Dedicated master nodes&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  เฉพาะ AWS หรือ Amazon Elasticsearch Service
&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiaclzt1dw85xdtzevgr5.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiaclzt1dw85xdtzevgr5.png" alt="Amazon Elasticsearch Service"&gt;&lt;/a&gt;&lt;br&gt;
วิธีการต่อไปนี้ สามารถทำได้บน AWS หรือ Amazon Elasticsearch Service ได้อย่างง่ายเนื่องจากตัว service มีการดูแลและจัดการให้อัตโนมัติ แต่อย่างไรก็ตาม ผู้ใช้งานสามารถนำ idea ไปปรับใช้กับ self-managed ได้เช่นกัน&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  7. ซื้อ ​Reserved Instance (RI)
&lt;/h3&gt;

&lt;p&gt;วิธีนี้ใช้ได้กับทั้ง EC2 และ Amazon Elasticsearch Service โดยการซื้อ Reserved Instance จะเป็นการ commit จำนวนปีที่ต้องการใช้งาน แลกกับส่วนลดที่ทาง AWS มอบให้กับผู้ใช้งาน ยกตัวอย่างเช่นใน ap-southeast-1 region ใช้ data node r5.xlarge.elasticsearch จะมีค่ายใช้จ่าย on-demand $0.448/hr แต่หากซื้อ RI 1 year no-upfront จะมีค่ายใช้จ่าย $0.309/hr ซึ่งลดลงมาประมาณ 31% เลย โดยไม่ต้องแก้ไขหรือปรับแต่ง Infrastructure ใด ๆ&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  8. ย้ายมาใช้ Amazon Elasticsearch Service เพื่อลด maintenance และ Data Transfer Inter-AZ Cost
&lt;/h3&gt;

&lt;p&gt;การย้ายจาก self-managed มายัง Amazon Elasticsearch Service นอกจากจะลดปัญหาเรื่องการดูแล Elasticsearch ด้วยตัวเองแล้ว ยังช่วยให้ผู้ใช้งานไป focus กับงาน implementation และ automation แทน รวมถึงยังช่วยลดค่า Data Transfer ระหว่าง Availability Zone ที่เกิดขึ้นภายใน Elasticsearch cluster ได้อีกด้วย&lt;/p&gt;

&lt;p&gt;อ่านเพิ่มเติมเรื่องการคิดค่า Data Transfer บน Amazon Elasticsearch Service ได้จาก &lt;a href="https://aws.amazon.com/elasticsearch-service/pricing/?nc=sn&amp;amp;loc=3#Standard_AWS_data_transfer_charges" rel="noopener noreferrer"&gt;Standard AWS data transfer charges&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  9. เปลี่ยน Instance Type เป็น Graviton เพื่อ price/performance ที่ดีกว่า
&lt;/h3&gt;

&lt;p&gt;ตอนนี้ทาง AWS ได้มีการออก Instance Type แบบใหม่ที่นอกเหนือจาก Intel และ AMD ในชื่อ Graviton (m6g, r6g, c6g) ซึ่งจะมีค่าใช้จ่ายที่ถูกกว่าและมี performance ที่ดีขึ้น ในจำนวน CPU และ Memory ที่เท่าเดิม โดยตอนนี้ตัว Graviton ได้รองรับ Amazon Elasticsearch Service เรียบร้อยแล้ว โดยผู้ใช้งานสามารถเปลี่ยนมาใช้งาน Graviton Instance Type โดยไม่ต้องแก้ไข application หรือทำ data migration&lt;/p&gt;

&lt;p&gt;ตัวอย่างเช่น หากเดิมมีการใช้งาน r5.2xlarge.elasticsearch (8 vCPU, 64GiB) ที่มีค่าใช้จ่าย On-Demand อยู่ที่ $0.897/hr แต่หากเปลี่ยนไปใช้งาน r6g.2xlarge.elasticsearch (8 vCPU, 64GiB เท่าเดิม) ที่มีค่าใช้จ่าย On-Demand อยู่ที่ $0.807/hr ซึ่งจะเห็นว่าถูกกว่าราว ๆ 10%&lt;/p&gt;

&lt;p&gt;แต่มีข้อแม้ว่า จะต้องทำการ upgrade Amazon Elasticsearch Service ไปที่อย่างน้อย version 7.9 แล้วเท่านั้น[3]&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  10. ใช้พระเอก/นางเอก UltraWarm และ Cold Storage features บน Amazon Elasticsearch Service
&lt;/h3&gt;

&lt;p&gt;หากพูดถึงการลด cost โดยเฉพาะ Logging หรือ Time-Series use cases การทำ Data Lifecycle Management (ข้อ 3) ถือเป็นจุดสำคัญที่ช่วยลด cost ขององค์กรอย่างมาก แต่หลาย ๆ ครั้งจะพบว่า การลบข้อมูลที่จำเป็นต้องใช้เร็วเกินไป อาจจะไม่ส่งผลดีนัก หรือผู้ใช้ไม่รู้ว่าข้อมูลนี้สามารถลบได้หรือไม่ ก็เกิดขาดความมั่นใจในการลบข้อมูล&lt;/p&gt;

&lt;p&gt;ทาง Amazon Elasticsearch Service ได้มีการเพิ่ม feature Storage Tiering เข้ามาให้กับผู้ใช้งาน ซึ่งจะช่วยให้ผู้ใช้งานยังสามารถเก็บข้อมูล ค้นหาข้อมูล และสร้างกราฟจากข้อมูลบน data node และ storage ที่ถูกลง ผ่าน &lt;a href="https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/ultrawarm.html" rel="noopener noreferrer"&gt;UltraWarm Storage&lt;/a&gt; โดยจะเป็นการย้ายข้อมูลส่วนที่เป็นข้อมูลเก่า, read-only ไปยังกลุ่ม nodes ที่มีราคาถูก โดยที่ยังสามารถ query หรือจัดการข้อมูลแบบเดิม, บน cluster เดิม, ไม่ต้องทำการแยก cluster ออกมาให้วุ่นวาย ซึ่งวิธีนี้จะช่วยให้ลดค่า cost ของ Elasticsearch cluster ได้อย่างมาก (สูงสุดราว ๆ 60-80% ขึ้นอยู่กับชนิดและขนาดของข้อมูล)&lt;/p&gt;

&lt;p&gt;นอกจาก UltraWarm แล้ว ทาง Amazon Elasticsearch Service ยังได้เพิ่ม feature Storage Tiering ที่ถูกแบบพิเศษเข้ามา ในชื่อ &lt;a href="https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/cold-storage.html" rel="noopener noreferrer"&gt;Cold Storage&lt;/a&gt; ซึ่งจะช่วยให้ผู้ใช้งานเสียเงินเฉพาะค่า storage อย่างเดียว (ไม่เสียค่า compute เมื่อไม่ได้ใช้) แต่เมื่อใดก็ตามที่ผู้ใช้งานเรียกข้อมูลจาก Cold Storage ระบบจะค่อยคิดค่าใช้จ่ายตามเวลารันจริงที่เกิดขึ้นเท่านั้น&lt;/p&gt;

&lt;p&gt;โดยทางผู้ใช้งานสามารถกำหนด policy ของการย้ายข้อมูลจาก Hot-&amp;gt;UltraWarm-&amp;gt;Cold ผ่าน &lt;a href="https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/ism.html" rel="noopener noreferrer"&gt;Index State Management&lt;/a&gt; เพื่อให้เกิดการทำแบบ automation ได้ทันที&lt;/p&gt;

&lt;p&gt;แต่มีข้อแม้ว่า จะต้องทำการใช้ Amazon Elasticsearch Service ที่มี version อย่างน้อย 6.8 สำหรับ UltraWarm[4] และ version อย่างน้อย 7.9 สำหรับ Cold[5] โดยต้องมีการใช้ dedicated master nodes ใน cluster ด้วย&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fctwjwej5if4j0jjmgkl3.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fctwjwej5if4j0jjmgkl3.jpg" alt="CastleArm"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  แหล่งอ้างอิง
&lt;/h2&gt;

&lt;p&gt;[1] &lt;a href="https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/sizing-domains.html#aes-bp-sharding" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/sizing-domains.html#aes-bp-sharding&lt;/a&gt;&lt;br&gt;
[2] &lt;a href="https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/ism.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/ism.html&lt;/a&gt;&lt;br&gt;
[3] &lt;a href="https://aws.amazon.com/about-aws/whats-new/2021/05/amazon-elasticsearch-service-offers-aws-graviton2-m6g-c6g-r6g-r6gd-instances/" rel="noopener noreferrer"&gt;https://aws.amazon.com/about-aws/whats-new/2021/05/amazon-elasticsearch-service-offers-aws-graviton2-m6g-c6g-r6g-r6gd-instances/&lt;/a&gt;&lt;br&gt;
[4] &lt;a href="https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/ultrawarm.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/ultrawarm.html&lt;/a&gt;&lt;br&gt;
[5] &lt;a href="https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/cold-storage.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/cold-storage.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>awsthai</category>
      <category>elasticsearch</category>
      <category>opensearch</category>
    </item>
    <item>
      <title>ทำความรู้จัก Apache Cassandra และ Amazon Keyspaces</title>
      <dc:creator>Nutchanon Leelapornudom</dc:creator>
      <pubDate>Tue, 31 Aug 2021 08:23:28 +0000</pubDate>
      <link>https://forem.com/awscommunity-asean/apache-cassandra-amazon-keyspaces-1pb2</link>
      <guid>https://forem.com/awscommunity-asean/apache-cassandra-amazon-keyspaces-1pb2</guid>
      <description>&lt;h2&gt;
  
  
  สารบัญ (Table of Contents)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;บทนำ&lt;/li&gt;
&lt;li&gt;Apache Cassandra คืออะไร&lt;/li&gt;
&lt;li&gt;ข้อดีของ Apache Cassandra&lt;/li&gt;
&lt;li&gt;Amazon Keyspaces (for Apache Cassandra) คืออะไร&lt;/li&gt;
&lt;li&gt;ข้อดีของ Amazon Keyspaces (for Apache Cassandra)&lt;/li&gt;
&lt;li&gt;บทสรุป&lt;/li&gt;
&lt;li&gt;แหล่งอ้างอิง&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  บทนำ &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;สำหรับหลายท่านที่เพิ่งศึกษาการใช้งานระบบฐานข้อมูล (database) มักจะรู้จักระบบฐานข้อมูลแบบตารางเช่น MySQL, PostgreSQL, Oracle, Microsoft SQL Server ซึ่งระบบฐานข้อมูลเหล่านี้ จะถูกจัดอยู่ในหมวดหมู่ Relational Database Management Software (RDBMS) &lt;/p&gt;

&lt;p&gt;แต่ในระยะหลัง ๆ เรื่องการทำงานแบบ Microservices Application ก็มักจะได้ยินระบบฐานข้อมูลประเภท NoSQL (Not-Only-SQL) ซึ่งเป็นระบบฐานข้อมูลที่ช่วยผู้ใช้งานในเรื่องของ ภาษาเข้าถึง (Query Language), การขยาย (Scale), การจัดเก็บ (Storage Engine), และความเร็ว (Performance)&lt;/p&gt;

&lt;p&gt;โดยระบบฐานข้อมูลแบบ NoSQL มีหลายยี่ห้อมากมาย ทั้งที่เป็น Commercial บน open-source อย่างเช่น MongoDB, Redis, Elasticsearch หรือจะเป็น open-source หลัก ๆ อย่าง Apache Cassandra, Prometheus โดยแต่ละยี่ห้อก็จะมีความแตกต่างกันทั้งในแง่ของ ภาษาเข้าถึง, รูปแบบการขยาย, ลักษณะข้อมูลที่จัดเก็บ, และความเร็วในการเข้าถึงที่แตกต่างกัน&lt;/p&gt;

&lt;h2&gt;
  
  
  Apache Cassandra คืออะไร &lt;a&gt;&lt;/a&gt;
&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj8nri7rjkusgnvr65ruu.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj8nri7rjkusgnvr65ruu.png" alt="Cassandra Logo"&gt;&lt;/a&gt;&lt;br&gt;
Apache Cassandra คือระบบฐานข้อมูล open-source NoSQL แบบ distributed ที่มีจุดเด่นในเรื่องของการขยาย (scalability) และความพร้อมใช้ (high availability) อีกทั้งยังมีความเร็วสูง (performance) นอกจากนั้นยังรองรับเรื่องการ Linear-scale ที่สามารถใช้ได้กับ commodity hardware เพื่อช่วยกันทำงานให้เกิดประสิทธิภาพดียิ่งขึ้น [1]&lt;/p&gt;

&lt;p&gt;การจัดเก็บของ Apache Cassandra จะอยู่ในรูปแบบ Column Family (CF) [2] โดยจะเป็นรูปแบบแถว ที่มี key/value ในแต่ละ column (คล้าย ๆ กับ row ใน table) และมีภาษาเข้าถึงชื่อว่า CQL (Cassandra Query Language) ที่มีการเขียนแบบ SQL-Like&lt;/p&gt;

&lt;p&gt;โดยถ้าอ้างอิงจากเว็บไซต์ DB-Engines[3] ตัว Apache Cassandra ถือว่าเป็นระบบฐานข้อมูลที่ได้รับความสนใจ โดยอยู่ในลำดับที่ 11 (เมื่อก่อนเคยอยู่ Top 10 ด้วย) ซึ่งก็ถือว่าเกาะกลุ่มผู้นำ โดยจะช่วยให้ผู้ใช้งาน สามารถหาข้อมูล วิธีการใช้ หรือคำตอบของปัญหาที่เจอแต่ละวันจากเว็บไซต์ต่าง ๆ หรือใน community ได้ง่าย&lt;/p&gt;

&lt;h2&gt;
  
  
  ข้อดีของ Apache Cassandra &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Masterless Architecture&lt;/strong&gt; - Apache Cassandra เป็นระบบฐานข้อมูลที่ทำงานแบบ cluster โดยไม่มี master ซึ่งการสื่อสารกันของข้อมูลภายใน cluster จะทำงานแบบ peer-to-peer โดยใช้ gossip protocol ในการติดต่อกัน
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqo0v6rfo9t3da8n24z27.jpg" alt="Cassandra Distributed Architecture"&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Distributed and Linear Scale-out&lt;/strong&gt; - Apache Cassandra ทำงานแบบ distributed database ผ่าน shard/token โดยแต่ละ node ใน cluster จะทำงานเฉพาะข้อมูลที่ตัวเองเป็นผู้ถือครองเท่านั้น และหากมีการออกแบบที่ถูกต้อง การเพิ่มจำนวน node ใน cluster จะเป็นการเพิ่มการรองรับโหลดแบบ linear scale ได้อีกด้วย (เช่น 10 nodes รับโหลดได้ 10,000 w/s หากขยายเป็น 20 nodes ก็จะรับโหลดได้ 20,000 w/s เป็นต้น)
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F10nnrb7wzn8eysw699w0.jpg" alt="Cassandra Scale"&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Active-Active Multiple Clusters&lt;/strong&gt; - Apache Cassandra รองรับการทำ architecture แบบหลาย cluster ได้ โดยสามารถเลือกที่จะเขียนข้อมูลที่ cluster ไหนก็ได้ อีกทั้งยังสามารถควบคุม data consistency ระหว่าง cluster ได้อีกด้วย ส่งผลให้เกิดการออกแบบ DC/DR ข้าม region ได้
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz0n3mo76sgcp03vjhx4k.jpg" alt="Cassandra MutliDC"&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexible for Data Consistency or Partition Tolerance&lt;/strong&gt; - Apache Cassandra มีการออกแบบให้รองรับเรื่องการทำซ้ำ (replication) ของข้อมูลจากตัวระบบฐานข้อมูลเอง โดยผู้ใช้งานสามารถเลือก 3 copies หรือ N copies (แนะนำเป็นเลขคี่) แล้วแต่ผู้ใช้งานเอง ทำให้แม้ว่าจะเกิด node มีปัญหา ก็ยังสามารถกู้ข้อมูลคืนได้ และผู้ใช้งานยังสามารถกำหนดความถูกต้องของข้อมูลผ่าน Consistency Level ระหว่างอ่าน (read) หรือเขียน (write) ได้ โดยแลกกับความเร็ว (performance)
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvai15g0g0t2sbcpzgvxx.jpg" alt="Cassandra CAP"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;โดย Apache Cassandra มี keywords สำคัญ ๆ ที่ควรจะรู้ดังนี้&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Node&lt;/strong&gt; - เครื่องหรือ process ที่ทำงานระบบฐานข้อมูล โดยจะทำการทั้งการจัดเก็บ การประมวลผล และการพูดคุยเชื่อมต่อกันระหว่าง node ภายใน cluster&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cluster&lt;/strong&gt; - กลุ่มของ node ที่ช่วยกันทำงานบนระบบฐานข้อมูล โดยการเชื่อมต่อจาก application จะเชื่อมต่อเข้ามาทำงานในระดับ cluster&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keyspace&lt;/strong&gt; - Logical Isolation ของข้อมูล โดยเป็นส่วนที่สามารถแบ่งแยกกลุ่มของ table (คล้ายกับ database ใน RDBMS)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Replication Factor&lt;/strong&gt; - ค่าทำซ้ำ (replication) ของข้อมูล โดยสามารถเลือกจำนวน copy ได้ เช่น 3,5,7 เป็นต้น โดยสามารถกำหนดในแต่ละ Keyspace ของแต่ละ "DC" ได้&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Table&lt;/strong&gt; - Schema ที่ใช้ในการจัดเก็บข้อมูล โดยมีการระบุ column name, data type รวมถึง Keys ต่าง ๆ เพื่อใช้ในการเข้าถึงข้อมูล (คล้ายกับ table ใน RDBMS)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Partition Key(s)&lt;/strong&gt; - Column(s) ที่ระบุให้ทำการ shard ไปในแต่ละ node ของ cluster โดย partition key(s) เป็นสิ่งที่ require ในการทำ equal filtering เวลาเข้าถึงข้อมูล&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clustering Key(s)&lt;/strong&gt; - Column(s) ที่ระบุให้ทำการเรียง (sort) ของข้อมูล ซึ่งจะสามารถเข้าถึงข้อมูลแบบ range filtering ได้&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Primary Key&lt;/strong&gt; - ส่วนประกอบของ Partition Key(s) กับ Clustering Key(s) ที่แสดงถึงความเป็น Unique ของ record ใด ๆ โดยหากมีการเขียนซ้ำที่ record ที่มี Primary Key เดียวกัน จะเป็นการ Upsert โดยอัตโนมัติ ซึ่งรูปแบบการจัดการ conflict จะเป็นลักษณะ Last-Write-Win&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency Level&lt;/strong&gt; - กำหนดความถูกต้องของข้อมูล โดยสามารถกำหนดแยกกันระหว่างการเขียน (write) กับการอ่าน (read) ได้ โดยจะส่งผลทั้งเรื่องของ performance, availability ด้วย เช่น ONE, QUORUM, ALL, LOCAL_ONE, LOCAL_QUORUM เป็นต้น&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ต่อมาเมื่อผู้ใช้งาน Apache Cassandra ใช้งานไปสักระยะนึงแล้ว มีการขยายจำนวน node ใหญ่ประมาณนึง ผู้ใช้งานมักจะพบปัญหาเรื่องการจัดการ การดูแล รวมถึงความรู้ความใจเชิงลึกของตัว software&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;การปรับ cassandra.yaml[4] - จำนวนของ configuration ที่สามารถปรับเปลี่ยนได้มีเยอะมาก ๆ และต้องใช้ expert ที่เข้าใจระบบค่อนข้างสูง ซึ่งจะส่งผลทั้งเรื่อง performance และ stability&lt;/li&gt;
&lt;li&gt;การจัดการผ่าน Nodetool - ตัว software ของ Apache Cassandra จะมี tool ที่ใช้ในการจัดการ node ผ่าน Nodetool แต่การทำงานผ่าน Nodetool ส่วนใหญ่จะมีผลกับ node ที่ระบุเท่านั้น โดยหากต้องจัดการระดับ 20-100+ nodes จะต้องเสียเวลาทำ automation เพิ่มเติมด้วย&lt;/li&gt;
&lt;li&gt;การดูแล compaction tasks - compaction เป็นเรื่องสำคัญที่ต้องดูแลเพราะจะส่งผลทั้งในแง่ของ performance และการ stream ของข้อมูลในการเพิ่ม/ลด node&lt;/li&gt;
&lt;li&gt;การ replace dead node - day-to-day maintenance ที่ต้องทำเพื่อการแก้ไข node ที่มีปัญหา และต้องคอยดูแลไม่ให้เกิดการ stream ข้อมูลผิดพลาด&lt;/li&gt;
&lt;li&gt;การ repair inconsistent data - ตัว Apache Cassandra เมื่อมีการทำงานไปสักพักจะเกิด data inconsistent ใน cluster โดยจะมี practice ที่ต้องทำการ full repair data ก่อนเกิด garbage collection ของข้อมูล (default 10 days)&lt;/li&gt;
&lt;li&gt;การ monitor low-level - แม้ว่าส่วนใหญ่ตัว Apache Cassandra จะให้ metrics ผ่าน MBean หรือ Nodetool มา แต่การที่จะดูแลและเข้าใจ ต้องใช้ผู้เชี่ยวชาญที่เข้าใจ architecture และ configuration ค่อนข้างสูง&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Amazon Keyspaces (for Apache Cassandra) คืออะไร &lt;a&gt;&lt;/a&gt;
&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frpzv73e1akjzaec9zekv.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frpzv73e1akjzaec9zekv.png" alt="Amazon Keyspaces Logo"&gt;&lt;/a&gt;&lt;br&gt;
Amazon Keyspaces คือ Serverless Apache Cassandra–compatible platform ที่ให้ผู้ใช้งานสามารถใช้งาน service ได้ทันที โดยยังคงความสามารถต่าง ๆ ที่ตัว Apache Cassandra ทำได้ ทั้งในเรื่องของ Scalability, High Availability รวมถึงตัว Driver, Code และภาษาเข้าถึงอย่าง CQL&lt;/p&gt;

&lt;p&gt;โดยคำว่า Serverless หมายความว่าทางผู้ใช้งานไม่ต้องทำการ provision ไม่ต้อง patch ไม่ต้องดูแล server, ไม่ต้องติดตั้ง (install), ดูแล (maintain), หรือจัดการ (operate) software อีกต่อไป&lt;/p&gt;

&lt;p&gt;นอกจากนั้นยังเพิ่มเติมความสามารถอย่าง Data Encryption การทำ Backup และ Point-in-time Recovery[5]&lt;/p&gt;

&lt;h2&gt;
  
  
  ข้อดีของ Amazon Keyspaces (for Apache Cassandra) &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Serverless on Apache Cassandra architecture&lt;/strong&gt; - โดยหลัก ๆ แล้วข้อดีเรื่อง architecture ก็จะยังอยู่ครบทั้งเรื่องของ scalability, high availability, partition tolerance และผู้ใช้งานยังสามารถเลือก Consistency Level ได้เหมือนเดิม และมีส่วนเพิ่มเติมคือเรื่องของ Serverless Architecture ที่ช่วยให้ผู้ใช้งานไม่ต้องดูแล server ไม่ต้องติดตั้ง software ไม่ต้องจัดการ software รวมถึงรองรับ Mutliple Availability Zone ที่ช่วยเพิ่ม SLA ของ service ให้กับผู้ใช้งานอีกด้วย&lt;br&gt;
&lt;br&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;คงความเป็น Apache Cassandra Compatibility&lt;/strong&gt; - หากตัว application มีการติดตั้ง driver/client ที่ใช้กับ version 3.11.2 ได้ ก็จะยังสามารถใช้ตัวเดิม เชื่อมต่อ Amazon Keyspaces ได้เลย โดยไม่ต้องมีการติดตั้งใหม่[6] และยังรองรับภาษา CQL ในการอ่านและเขียนข้อมูลได้อีกด้วย ซึ่งหมายถึงผู้ใช้งานสามารถเลือกใช้ Apache Cassandra หรือ Amazon Keyspaces โดยไม่ต้องแก้ไข application เหมาะกับการโยกย้ายไปมาได้สะดวก แต่แน่นอน ว่านี่เป็น compatibility service แนะนำให้อ่านความแตกต่างในรายละเอียดได้บน &lt;a href="https://docs.aws.amazon.com/keyspaces/latest/devguide/keyspaces-vs-cassandra.html" rel="noopener noreferrer"&gt;Compare Amazon Keyspaces with Cassandra&lt;/a&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;เพิ่มเติมในส่วนของ Security และ Data Protection&lt;/strong&gt; - ตัว Amazon Keyspaces มี default เป็น Data Encryption At-Rest และ security มุมอื่น ๆ อีกมากมาย ที่จะช่วยให้ผู้ใช้ตอบโจทย์เรื่อง Security and Compliance รวมถึงการจัดการ Backup/Restore ที่รองรับรูปแบบ Point-in-Time Recovery อีกด้วย&lt;br&gt;
&lt;br&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;รองรับการใช้งานผ่าน Capacity แบบ Provisioned และ On-demand และการคิดเงินแบบ pay-as-you-go model&lt;/strong&gt; - โดย Provisioned จะเป็นรูปแบบกำหนด throughput ที่ผู้ใช้งานจะสามารถ ทั้งในส่วนของการอ่านและเขียน (คล้ายซื้อค่า internet) หรือ on-demand ที่ให้ผู้ใช้งาน ใช้เท่าไหร่จ่ายเท่านั้น โดยทั้งสองแบบนั้นยังรองรับการทำ Auto-Scaling เพื่อให้มั่นใจได้ว่า ตัว service สามารถรองรับก็ load ที่เกิดขึ้นได้&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  บทสรุป &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Apache Cassandra&lt;/strong&gt; คือระบบฐานข้อมูลแบบ Distributed NoSQL ที่มีจุดเด่นในเรื่องของการทำ Scale-out Architecture, High Availability, และ Performance ที่สูง โดยผู้ใช้งานสามารถเลือกปรับ Data Consistency ให้เหมาะสมกับ Use Case ที่เลือกใช้ได้ และยังรองรับภาษา CQL (SQL-Like) ซึ่งจะช่วยให้ผู้ใช้งานไม่ต้องปรับตัวมากนัก&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amazon Keyspaces (for Apache Cassandra)&lt;/strong&gt; คือ 1 ใน Database Services ที่ทาง AWS ให้บริการในรูปแบบ Serverless Apache Cassandra Compatibility Service ที่ช่วยให้ผู้ใช้งานสามารถใช้ driver/client เดิม รวมถึงภาษา CQL เดิมที่เคยใช้อยู่แล้ว นำมาใช้กับ Amazon Keyspaces ได้ทันที โดยทาง AWS ช่วยเรื่องของการจัดการ infrastructure, software, scaling ต่าง ๆ ให้ รวมถึงมีการเพิ่ม features บางส่วนเช่น security backup/restore และให้บริการในรูปแบบ pay-as-you-go model&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgdhrwaj8zolrm46mhs3k.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgdhrwaj8zolrm46mhs3k.jpg" alt="CastleArm"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  แหล่งอ้างอิง &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;[1] &lt;a href="https://cassandra.apache.org/" rel="noopener noreferrer"&gt;https://cassandra.apache.org/&lt;/a&gt;&lt;br&gt;
[2] &lt;a href="https://en.wikipedia.org/wiki/Column_family" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Column_family&lt;/a&gt;&lt;br&gt;
[3] &lt;a href="https://db-engines.com/en/ranking" rel="noopener noreferrer"&gt;https://db-engines.com/en/ranking&lt;/a&gt;&lt;br&gt;
[4] &lt;a href="https://github.com/apache/cassandra" rel="noopener noreferrer"&gt;https://github.com/apache/cassandra&lt;/a&gt;&lt;br&gt;
[5] &lt;a href="https://aws.amazon.com/keyspaces/" rel="noopener noreferrer"&gt;https://aws.amazon.com/keyspaces/&lt;/a&gt;&lt;br&gt;
[6] &lt;a href="https://docs.aws.amazon.com/keyspaces/latest/devguide/programmatic.drivers.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/keyspaces/latest/devguide/programmatic.drivers.html&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  แหล่งอ้างอิงรูปภาพ
&lt;/h3&gt;

&lt;p&gt;[a] &lt;a href="https://cassandra.apache.org/_/cassandra-basics.html" rel="noopener noreferrer"&gt;https://cassandra.apache.org/_/cassandra-basics.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>awsthai</category>
      <category>cassandra</category>
      <category>keyspaces</category>
    </item>
  </channel>
</rss>
