Below you will find pages that utilize the taxonomy term “AWS”
Posts
Deploy s3 bucket by cloudformation
預先準備 需要先把 aws cli 給裝起來
利用CLI可以把預先寫好的基礎建設結構佈署到AWS上,下面是簡單部署一個S3的bucket範例。
aws cloudformation deploy --stack-name paulteststack --template-file ./s3-create-template.json --stack-name: 想要deploy到哪一個cloudformation stack裡 --template-file: template 檔案的所在位置 還有很多參數可以設定,詳情可以參考 create-stack
{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "Create S3 bucket on AWS", "Resources": { "S3Test": { "Type": "AWS::S3::Bucket", "Properties": { "BucketName": "paul-test-1495611707" } } } } template 可以依照情境進行更進階的調整,例如調整bucket的CROS讓外部的前端程式可以進行存取。 { "AWSTemplateFormatVersion": "2010-09-09", "Description": "Create S3 bucket on AWS", "Resources": { "S3Test": { "Type": "AWS::S3::Bucket", "Properties": { "BucketName": "paul-test-1495611707", "AccessControl": "PublicReadWrite", "CorsConfiguration": { "CorsRules": [ { "AllowedHeaders": [ "*" ], "AllowedMethods": [ "GET" ], "AllowedOrigins": [ "*" ], "ExposedHeaders": [ "Date" ], "Id": "myCORSRuleId1", "MaxAge": "3600" }, { "AllowedHeaders": [ "x-amz-*" ], "AllowedMethods": [ "DELETE" ], "AllowedOrigins": [ "http://www.
Posts
收集 AWS IoT data到 AWS kinesis 處理資料流
使用AWS IoT服務來開發大量的資料傳輸系統,主要是想彙整資料或是做數據分析,AWS同樣提供資料串流的分析服務 kinesis. kinesis服務裡面有三個類別,Data Streams, Data Firehose, Data Analytics. Data Streams: streams 這個服務其實就有點類似 Kafka. 在IoT mqtt的protocol下,publish/subscribe之間系統是不會保存任何傳遞的資料。所以一但需要做資料流分析時,需要將收到的資料存在Message Queue裡,kinesis streams就擔任這個初階的角色,stream可以搭配firhorsec,analytics,lambda…一起使用。
Data Firehose: firehose可以將stream的資料倒至其他AWS的服務,例如: S3, Redshift…,firehose服務裡提供transformation功能將資料整理成需要的格式。
Data Analytics: 利用收到的data stream,只要提供需要sql程式,設定好Source(data stream)與Destination,AWS就會提供即時分析服務。
IoT trigger Kinese stream
只要在IoT的Service上建立rule,只要推送資料到設定的topi就會將資料導入Kinese stream。 選定 Send messages to an Kinesis Stream 就可以在符合Rule時將資料導入data stream 選定預先創立好的stream,設定Partition key,還有執行角色就完成 Partition key說明
利用Partition key,IoT的資料可以藉由group的方式去將資料分配的儲存在stream的shards裡面,最容易的方式是用網頁上提供的function: newuuid(),去隨機產出亂數平均的儲存資料,或是利用IoT的資料裡面的Key直做group。 [{'key':'a1', 'value':1}, {'key':'a2', 'value':2}, {'key':'a1', 'value':3}] 如果Partition key填入${key},那麼第1,3比資料會被送到stream裡的同一個shard,2則被送到另一個shard。
trigger lambda處理收集好的batch資料
shard只由一個lambda服務 pull 多shard由多個lambda執行task, semphore問題
Posts
AWS IoT | 進階資訊分享
AWS IoT - 進階 IoT reserved topic 在 AWS IoT的資源上,有部份的 topic name是被保留。 $aws/events/presence/connected/# : 如果有任何的使用者連上 IoT 就會推播訊息到這個 Topic $aws/events/presence/disconnected/#: 如果有任何的使用者斷線,就會推播訊息
這個是當使用者 connected/disconnected 推播到 topic 裡的訊息範例 { "clientId": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6", "timestamp": 1460065214626, "eventType": "connected", "sessionIdentifier": "00000000-0000-0000-0000-000000000000", "principalIdentifier": "000000000000/ABCDEFGHIJKLMNOPQRSTU:some-user/ABCDEFGHIJKLMNOPQRSTU:some-user" } $aws/events/subscriptions/subscribed/#: 如果有任何的使用者訂閱了任何的 topic就會推播訊息到這個topic $aws/events/subscriptions/unsubscribed/#: 如果有任何的使用者解訂閱了任何的 topic就會推播訊息
這個是 subscribed/unsubscribed 推播的訊息範例 { "clientId": "186b5", "timestamp": 1460065214626, "eventType": "subscribed" | "unsubscribed", "sessionIdentifier": "00000000-0000-0000-0000-000000000000", "principalIdentifier": "000000000000/ABCDEFGHIJKLMNOPQRSTU:some-user/ABCDEFGHIJKLMNOPQRSTU:some-user" "topics" : ["foo/bar","device/data","dog/cat"] } :::info
同時要聆聽相同 Topic 底下不同的子 Topic 可用 + 號串聯,例如: $aws/events/subscriptions/+/#: 可以同時聆聽到 connected, disconnected, subscribed, unsubscribed …的訊息 company/+/member: + 號可以是任意的字串,只要符合這個 Topic 的 name 的規則,都可以收到資訊 :::
Posts
AWS IoT with websocket
在大多數的瀏覽器都有支援websocket的protocol前提下,實作網頁即時接收訊息的功能上,我們希望每個網頁都可以當作是一個mqtt的裝置,如此一來就可以即時推播給各個網頁,也可以即時的接收到來自client端的訊息。 AWS在IoT的服務上也有做到MQTT Over the WebSocket Protocol,透過AWS SigV4的身份認證, 利用Port 443,我們可以透過網頁連線上AWS IoT的服務。 server side
以下是server端需要產出帶有authentication的query url,使用上,前端只需要將url用get的方式呼叫就可以連接上IoT。 function SigV4Utils() {} SigV4Utils.getSignatureKey = function (key, date, region, service) { var kDate = AWS.util.crypto.hmac('AWS4' + key, date, 'buffer'); var kRegion = AWS.util.crypto.hmac(kDate, region, 'buffer'); var kService = AWS.util.crypto.hmac(kRegion, service, 'buffer'); var kCredentials = AWS.util.crypto.hmac(kService, 'aws4_request', 'buffer'); return kCredentials; }; SigV4Utils.getSignedUrl = function(host, region, ) { var datetime = AWS.util.date.iso8601(new Date()).replace(/[:\-]|\.\d{3}/g, ''); var date = datetime.
Posts
AWS IoT介紹
AWS IoT 說明
certificate:裝置可以透過 certificates 去做驗證,保證使用 IoT 的溝通上 security 是沒有任何問題的。除了certificates之外,也可以透過IAM權限,Congnito 的權限控管去操作 IoT 的 resources (如上圖)。 利用 AWS IoT 提供的 sdk 可以在 AWS resource 內產出一組 certificate, 裏面包含的資訊會有certificate pem keyPair(a pair of public & private key) certificateId & ARN
取得憑證後,需要在憑證上套用policy,policy就好像規定這拿著這隻憑證鑰匙可以進哪個門,不能進哪個門,以達到 AWS IoT 的 resource 控管。
Policy設定 以下的這個 Policy設定代表使用者只要有合理的 certificates,就可以針對IoT上所有的resources 做連線,推播,接收的動做,沒做任何的限制管控,如果要限制使用者能力有下面另外一個範例 { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": [ "iot:Publish", "iot:Subscribe", "iot:Connect", "iot:Receive" ], "Resource": ["*"] }] } 如果想讓使用者只能針對自己 CertificateId 的 topic 操作,policy 就要修改成以下的方式,利用 ${iot:CertificateId} 的變數,AWS IoT 會去檢查裝置端連線時所使用的憑證,達到每個憑證只能操作對應憑證 ID 的 Topic,降低資訊被竊取的風險。 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iot:Subscribe", "Resource": "arn:aws:iot:ap-northeast-1:1234:topicfilter/${iot:CertificateId}" }, { "Effect": "Allow", "Action": "iot:Connect", "Resource": "arn:aws:iot:ap-northeast-1:1234:client/${iot:CertificateId}" }, { "Effect": "Allow", "Action": [ "iot:Publish", "iot:Receive" ], "Resource": "arn:aws:iot:ap-northeast-1:1234:topic/${iot:CertificateId}" } ] } connect 的 policy 要跟操作 IoT resources 要分開寫,因為 connect 是針對 client resource 操作,但是其他的動作是針對 IoT 上的 topic resource 做操作,如果都在一條 statement 會導致錯誤。
Posts
Serverless offline 開發設定 - 基礎篇
說明
為了加速開發的效率,開發過程中不會想要每次都佈署到AWS做測試或開發。Serverless offline套件可以解決這件事情。透過模擬 AWS λ and API Gateway ,開發者在本機端就可以run一個的server去模擬再AWS服務的情況。
前置作業
需要事先安裝過 serverless package sudo npm install serverless -g 安裝serverless offline套件 npm install serverless-offline --save-dev
使用方法
在原本專案的serverless.yml上添加程式碼
plugins plugins: - serverless-offline server conf 將server在 3000 PORT 開啟; 開放所有的 IP 都可以存取
custom: serverless-offline: host: "0.0.0.0" port: 3000 在Terminal上啟動 serverless offline server serverless offline start 接著就可以用各種工具去發出request做開發測試
:::danger
執行API request出現錯誤 { "statusCode": 400, "error": "Bad Request", "message": "Invalid cookie value" } 經過測試,如果將IP綁在127.0.0.1或是沒有設定(系統預設為localhost)的話會出現access error,這個問題只要將 IP 綁在 0.
Posts
在Local machine開發AWS serverless project
AWS dev project 說明:這個 Project 主要是拿來研究 AWS serverless 的開發規劃和未來建構 Project 的基礎參考。主要會用到 AWS Resource 有 API-gateway, Lambda, RDS, Congnito Services。 Install 安裝 serverless package npm install -g serverless 安裝開發所需其他的套件 npm install Dev run Project 開發時,可在本機上做 Debug,確定Lambda的function沒有邏輯錯誤再佈署上去AWS就可以。Dev server開啟時會建立在 port 3000 上,請用自己主機 ip 連,不要用 127.0.0.1 或 localhost 連線,否則會出現錯誤。 npm run dev Deploy to AWS 將自己的程式碼透過serverless package上傳到 CloudFormation後佈署所需資源。 npm run deploy 為 API-gateway建立一個 Usage Plan aws apigateway create-usage-plan --name dev-file-sharing-plan --api-stages apiId={{API_ID}},stage=dev --region ap-northeast-1 為 Usage Plan 綁定一組 API-key aws apigateway create-usage-plan-key --usage-plan-id {{PLAN_ID}} --key-id {{KEY_ID}} --key-type "API_KEY" Migrations 建立一個 Migration 檔案 (若變更 Schema 則需要新增一個 Migration 檔案) db-migrate create <migrate_file> --config .
Posts
Dev issue: Lambda reuse
當系統透過 APIGateway 呼叫 Lambda 執行時,我以為Lambda會全部重新執行打包好的程式。所以開發時,我們將 database connection 物件當成 Global 物件使用,認為每次重新呼叫 Lambda 都會全部重新生成物件。因為這個觀念而導致系統錯誤,當 Project 的物件被 require 後或變成 global 參數,再次執行 Lambda container 會出現 reuse 特性,將不會再被重新執行而生成新物件,以下是一個範例。 DB 的 client 為 global 物件
const pg = require('pg'); const client = new pg.Client('postgres://myrds:5432/dbname'); client.connect(); exports.handler = (event, context, cb) => { const {test_print} = require('./example_module'); test_print(); client.query('SELECT * FROM users WHERE ', (err, users) => { // Do stuff with users cb(null); // Finish the function cleanly }); }; 上面的範例,因為 client 為 global物件,所以如果在程式裡面有 disconnect client 的狀況下,再次執行 Lambda 就會出現錯誤,因為 client 物件沒被重新 connect。 Global 程式不會每次都被執行