Software engineering notes

AWS

(最後更新: 2016-04-27)

介紹

AWS (Amazon Web Services) 是針對主機或 App 提供整套 solution 的雲端服務

Install/Upgrade AWS CLI

安裝

sudo pip install --upgrade awscli

如果安裝出問題, 強制重新安裝可以解決

sudo pip install awscli --force-reinstall --upgrade

Stop the agent

sudo service awslogs stop   // Works on Ubuntu
sudo service awslogsd stop  // Amazon Linux 2

stop|restart|start

Region & AZ

IAM

[操作] 增加一個登入帳號給團隊的成員

Users -> Create Users -> 輸入 user name -> copy Access Key ID 及 Secret Access Key (目前還不會用到) -> 回到 Users 列表就會看到剛剛新加的 user

但加完帳號其實還沒有密碼 : Has Password: No, 所以在那 User 下面選擇 Manage Password 可以手動指定一組密碼給它

接著他只要到 IAM users sign-in link 輸入他的 user name 及 password, 就可以登入了

如何用同一個瀏覽器切換不同的 AWS account

假設有 QA & Prod 的 AWS account

  1. 在 QA 建立一個 IAM Role 選擇 Another AWS Account 填入 Prod account ID, 然候權限給予 AdministratorAccess
  2. 在 Prod Account 右上角選擇 Switch Role, 填入 QA Account ID 及上一步建立的 Role name

Route 53

DNS 服務, 使用上很直覺簡單. 一個 domain 可以對應多個 ip (可以填 TW 及 US IP)

[操作]

Create Hosted Zone

輸入 Domain Name 後, 會新增一筆 Zone (EX: qq.test.com), 然候進入 Zone 裡面

AWS 預設裡面會有兩筆 Record

自己再新增每一筆 Sub domain record :

s1.qq.test.com   A   55.123.122.33

如果上例設定的 Zone 也是主站的 sub domain, 必須在去主要的 domain 設定

首先先去 qq.test.com 這個 Zone copy NS 那筆 Record 的 Value, 再到 test.com 新增一筆 Record

qq.test.com    NS    (將剛 copy 的 ns value 貼到這的 value field)

一個 domain 對全球,讓 route 53 自動幫我們把 user 的 region 導到對應的 region 的 elb

  1. 先設定 domain 對應到 ELB 的 endpoint

  2. domain 右邊設定 Routing Policy 選擇 lantency, Set ID 隨便打,它們就對應好關係了

  3. user 連上來會根據 latency 指派到最近 region 的 elb

Internal domain

如果建立 mysql 要使用 interntal domain e.g. mysql.xxx.local 指到那台 endpoint 要記得將它的 VPC 的 hostnames 打開,否則不會通

不知道有沒有打開可以到 VPC 那個網段可以下面是否顯示 DNS hostnames: yes

VPC

[備註]

[操作步驟]

1) Your VPCs : 建立一個 VPC, CIDR block 為 10.0.0.0/16

2) Subnets : 實務上可以依這樣分類去切, 這樣對之後設定 security group 比較方便

10.0.1.0/24     : base
10.0.11.0/24    : api-zone-a
10.0.12.0/24    : api-zone-b
10.0.21.0/24    : db-zone-a
10.0.22.0/24    : db-zone-b

能不能對外可以再以 security group 去個別設定某個網段(i.e. 10.0.11.0/24)要不要對外

3) Internet Gateways : 建立一個可以讓外部連進來的 Gateway, 再 attach 到 vpc

4) Route Tables : 建立兩個 Route Table

建立好的 VPC 的 Routes (在畫面下面) 新增 0.0.0.0/0 指向步驟 3 建立的 internet gateway.

Subnet Associations 指向步驟2建立的 subnet

注意! 要連到外面 Routes 一定要將 0.0.0.0/0 指向 internet gateway, 並且 Security Groups 的 SSH Source 也要記得設定成 0.0.0.0/0

5) Security Groups

Inbound :

TYPE            Port    Source
==================================
ALL Traffic     ALL     10.0.0.0/16
SSH             22      0.0.0.0/0
HTTP            80      0.0.0.0/0
HTTPS           443     0.0.0.0/0
ALL ICMP        ALL     0.0.0.0/0           # ping

6) EC2

Security Group 選擇步驟5建立的 Private Group

Public :

Network : 選擇剛建立的 VPC
Subnet : 選擇 Public subnet
Auto-assign Public IP : Enabled

Private :

Network : 選擇建立的 VPC
Subnet : 選擇 Private subnet
Auto-assign Public IP : Use subnet setting (Disable)   => 就算 Enabled 也沒有用, 因為外部無法 Access 到裡面

總結

EC2 主要是看 Security Group, 但 EC2 是掛在 VPC 的 Subnet 裡面, 每個 Subnet 又有他自己的 Route, 所以如果要對外的話

Route 要先設定成對外(加上 internet gateway), 而 EC2 的 Security Group 設定允許外面連進來的的防火牆 rule 才有意義

[VPC connect another vpc in the same region]

VPC 下的 Peering Connections

[VPC cross region, 需透過 VPN 達成]

EC2

申請固定IP

Elastic IPs -> Allocate New Address

[備註]

IPv4 and IPv6

IPv6 was supported on “EC2 Classic” but not on EC2 VPC. And EC2 Classic is no longer available for new AWS accounts. Also, EC2 Classic is deprecated and should not be used, all new accounts use VPC.

Update (Sept 2016): IPv6 is now supported for Elastic Load Balancer end points. Internally in the VPC, IPv4 is still used, but it’s now possible to provide an IPv6 endpoint for public web sites (important for Apple devices!)

流量價錢

t2 CPU Credit

CPU Credit 保持的越高, query 處理的效率會越好, 反之如果 credit 用完了, 它的處理效率就差

如果 cpu 保持低於基礎線以下的話, credit 是會加回來的, 直到加到上限

可以參考官方的連結

CPU Credit usage 如果是 1 的話代表要升級機器了

以 t2.small 為例, credit 基礎線為 CPU utilization 20%, 以上的話會扣 credit, 以下的話會加回來

新開的 ec2 e.g. t2.small 開啟動它的 CPU CreditBalance 是從 0 開始, 而不是 288 (updated on 2018-06-28)

另外建議在 production 不要用 t 系列, 除非是成本考量

因為 CPU Credit Balance 很容易被漏看, 且也需要了解它的規則

對 CPU Credit Balance 做監控比對 CPU Utilization 設重要多了, 因為當 Credit Balance 用完之後, CPU 才會開始衝高, 而且 EC2 CPU 裡面充到 100% 但外面的 CPU Utilization 卻只會顯示只有 20~30%,

而且 EC2 CPU 裡面充到 100% 但外面的 CPU Utilization 卻只會顯示只有 20~30%, 因為主要的 CPU 使用被外面掐住了

用 CLI 取得 EC2 private IP

以下會找出 EC2 tag Name: jenkins Value: my-services 的主機, 並把 private IP 取出來

/usr/bin/aws ec2 describe-instances --filter Name=tag:jenkins,Values=my-services --query 'Reservations[*].Instances[*].[PrivateIpAddress]' --region ap-southeast-1 | /usr/bin/jq -c '.[] | .[] | .[]'

ELB / ALB

ELB (HTTP, HTTPS, and TCP)

Load balance 服務, 可以將多台主機放在 Load balance 下, 做隨機或權重分配, 減輕單一 server 負擔

可以設定接 HTTPS 內部再導向 HTTP, 內部都是走 VPC 的網段

設定完大概15分鐘 ELB 的 DNS 才會通

將 ELB 的 domain 貼在 route53 record 新增的 CNAME item 裡

ELB 有內建 graceful shutdown,當把它移除掉,它會先停接新的 request,等到目前的 request 結束才移除

ALB (HTTP/HTTPS)

需要先設 Target Groups 主要是 port -> EC2 instance

再到 ELB 選擇 application type (一般的 ELB 是 classic) 然候再選擇 url path 對應到哪個 target group

注意:

NLB (TCP)

注意:

SSL

如果在 godaddy 買 domain,用 CNAME 連到這個 ELB 的 dns CNAME,然候再把 godaddy 的憑證上傳到 ELB,然候就 OK 了,

Auto Scaling

[操作]

  1. 一開始要先建立 Launch Configurations (要吃哪個 AMI ID 等等) 才能設定 Auto Scaling Groups (自動調整 size 的 Policy)
  2. 一旦建立好的 Launch Configuration 就不能改 AMI ID 了, 所以主機更新後除了重新打一個新的 Image, 再點原本的 Launch Configuration 複製建立新的並且選擇新的 AMI ID, 再到 Auto Scaling 的 config 選擇新的 Launch Configuration.
  3. 如果要一次對兩個 AZ 輪流新增 instance 的話在選擇 Subnet 時就要選擇兩個 AZ 所屬的 Subnet
  4. IP Address Type 要選擇 Assign a public IP address to every instance. 否則預設不會配 public ip, 但 ELB 走 LAN 還是可以讓此 API 對外開放, 只是如果要更新系統或抓新 code 就會受限無法 access internet
  5. 新啟動的 instance 大約在 1 分鐘內可以上線服務, (讓 CPU% 上升到 100% 的測試指令 : while true; do echo; done)

註: 如果要在機器啟動時執行一些 shell 指令, 可以在 Launch Configuration 的 User data 的 type 選擇 file, 內容 :

#!/bin/sh
echo "qq white into dd" > /tmp/dd

那麼機器啟動時就會執行這份檔案的指令了

[Autoscaling with custom metrics]

  1. Put metric data

可以直接在程式引用別人寫好的套件, 直接透過程式做或使用 command line

  1. 到 cloudWatch 確認 metric 是否上傳成功 (Metrics 搜尋 JobCount 看是否存在)

成功後寫一個會定時回報 metric 的 script 或程式, 讓 Auto-Scaling 把 AMI 啟動成 EC2 可以自動執行

  1. Create Alarm (Action 是當超過設定值要做什麼事, 例如寄信等等的, 可以不用), 目的是為了讓 Auto-Scaling 的判斷機制可以選擇這個 metric

建兩個 Alarm 一個是 JobCount>=100 另一個是 JobCount <=10

  1. 將 EC2 打成 Image

  2. 建立 Auto Scaling configuration 及 group, 並持續 put-metric-data 測試是否 scale 成功

CloudWatch

監控 EC2 的狀態 (CPU usage, Network I/O ,etc..)

[備註]

預設默認一些 cpu 使用, io 等資訊

但不包括 ram 使用, 因為 AWS 是與 Hight provider 拿取使用狀況, 如果要拿到 ram 使用率勢必要放 agent 在 ec2, 而 aws 沒有做這件事

如果 launch 一個 instance 沒有打開 monitor, 預設的 CloudWatch 會紀錄

打開後會多紀錄

Install AWS CloudWatch Log Agent

curl https://s3.amazonaws.com/aws-cloudwatch/downloads/latest/awslogs-agent-setup.py -O
sudo python ./awslogs-agent-setup.py --region us-east-1

ref: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/QuickStartEC2Instance.html

重新設定要監聽的log, 再下一次

sudo python ./awslogs-agent-setup.py --region

log agent 的位置

/var/log/awslogs.log

[Put custom metric (command line)]

  1. 安裝 AWS CLI tool

  2. EC2 要有權限, 打開 put metric data 給 cloudWatch 的權限有兩種方法

Note: 不需要在 AWS Console 建立一個新的 metric,當你報上來的時候如果是新的 metric name,CloudWatch 會自動新增

第一種是建立 User 並給予對應權限, 再到 EC2 上設定 Access 及 Secret

  1. 到 AWS Console 的 IAM : 新增或選擇舊有的 User, 新增 Policy : AWS Service Roles -> Amazon EC2 (Select) -> cloudWatch 全部權限
  2. 再到主機裡設定 AWS config
    aws configure
    AWS Access Key ID [None]: A******************Q
    AWS Secret Access Key [None]: 9**************************************O
    Default region name [None]: us-west-2   (Oregon 是 us-west-2)
    Default output format [None]:text

第二種是建立 Role 然候在起 EC2 的時候指定 Role

(?) 先不要用 role 來做 put-metric-data, 不知道為什麼, 就是會一直噴錯誤

一開始以為到 AWS Console 的 IAM : Create Role -> Role Type 選擇 Amazon EC2 -> CloudWatch Full Access -> Create Role

然候再選擇這個 role 建立 EC2 權限是可以的, 但卻會噴出 A client error (InvalidClientTokenId) occurred when calling the PutMetricData operation: The security token included in the request is invalid. 這樣的錯誤

註 : 目前這個 Role 只能給你目前帳號使用, 假如你跟別人共同開發, IAM 建立多個 User 並且每個人使用不同的 User 登入 AWS Console, 那麼其他人建 EC2 是看不到這個 Role 的, 解決辦法是在其他人的 User 或 Group 增加 Policy 打開 AWS Data Pipeline Full Access, 這樣其他人在建立 EC2 就可以看到 IAM Role 了

再到主機裡設定 AWS config

$ aws configure
AWS Access Key ID [None]: (留空 直接 enter)
AWS Secret Access Key [None]: (留空 直接 enter)
Default region name [None]: us-west-2
Default output format [None]:text
  1. 測試 put metric data

    aws cloudwatch put-metric-data –namespace “Job worker metrics” –metric-name JobCount –unit “Count” –dimensions “AutoScalingGroupName=myAutoScalingGroup” –value 23

如果沒有其他的訊息代表上傳成功

Custom Metrics 計價方式

以下是官方的範例

If your application runs on 10 Amazon EC2 instances 24x7 for a 30-day month, and you published 5 custom metrics every 5 minutes via the PutMetricData API, your charges would be as follows:

Total number of metrics = 5 metrics per instance * 10 instances = 50 metrics
Monthly CloudWatch Metrics Charges @$0.30 per custom metric = 50 * $0.30 = $15

Total number of minutes in the month = 60 * 24 * 30 = 42,300 minutes
Total Number of API requests = 10 instances * (42,300 minutes/5 minutes) = 84,600 requests
First 1,000,000 API requests = $0

Monthly CloudWatch charges = $15 + $0 = $15 per month

常收到 State is OK 的通知 OK: "API CPU >= 70%", 但狀態都沒有變成 alarm

這是因為 cloudwatch 沒有收到足夠的資料所以 Alarm updated from OK to INSUFFICIENT_DATA

這時只要修改這個設定將 Treat missing data as: ignore (maintain the alarm state) 就行了,

它就不會在服務正常的時候還報 OK, 只有在 Alarm -> OK 才會收到

測試 alarm 的方式

先在 sns 建立一個自已的 topic 設定 email 寄給自已做通知

alarm 再指向這個 sns topic, 如果測試完成後再刪除這個 sns topic

EBS

IS 是跟 EC2 同一台機器上; EBS 是在雲上的硬碟.

如果 EC2 stop 再 start, 而 EC2 會換一台機器上, 所以 IS 就無法使用了, 但 EBS 則不受限制

IS 不收錢, 提供比 EBS 更高的 io/ps 因為沒有網路

一開始選擇 OS 時會標示他預設是使用 IS 還是 EBS, 但幾乎都是 EBS, 除非是在 AMI markets 就會看到有些是 IS 的

Glacier

存的資料不常使用, 能接受 3~5 小時的取回時間, 成本只有 s3 的 1/10, EX: 常用來封存 log 等等之類的久放但沒事不會拿出來的資料

RDS

[操作]

1) 建立好 VPC

  1. RDS 預設不是 public, 如果要對外, 在建立 instance 時 Publicly Accessible 要選擇 yes
  2. 也可以使用自定義的 VPC, 先分好網段, 一個對內一個對外

如果勾選 Publicly Accessible 則 VPC 要將 DNS resolution 及 hostnames 打開

2) 先建立 Subnet GRoups

  1. 點擊 Create DB Subnet Group,
  2. 然候選擇 VPC ID 及 VPC 的 public 的 subnet,
  3. Subnet Group 規定 Subnet 要設定可以通兩個 AZ, 所以 VPC 的 Subnet 要有兩組不同的網段對應到不同的 AZ

3) 建立 Security Group, 讓 RDS 可以對外

4) 建立 RDS MySQL, 並且選擇 Public 的 Subnet, 及 Secruity Group

[主 DB 在美西, 其他 region 要 update DB 問題 (全球 DB 佈署問題)]

因為需要考慮到 Auto Scaling 的問題, 新的主機會不知道 IP, 所以無法先設定在 Security Group

有四種方法解決 :

  1. singapore 用 mysql 內建的 SSL 連到美西的 DB master, 然候再 call 美西那邊的 security group API 新增讓此 IP 通過的 rule

比較麻煩, 不是個很好的方法

  1. 用 VPN IPSec 將兩個 region 的 VPC Subnet 連在一起, 其通道本身就加密了, 所以可以直接通過 LAN 的方式更新

維護主機的成本提高

  1. 在美西架一個 API server, 所有主機要更新 DB master 都透過此 API server, 並且用 https, 本身也是很安全的

幾乎不用花時間設定, 但需要花時間寫 API 接口

  1. MySQL MMM 架構

需要擔心 DB 互相 sync 時引發的錯誤

結論 : 建議使用第 3 種方法, 可能 Update 速度稍慢, 但出錯的成本最少

RDS - MySQL

max_connection 不同 size 支援的 max_connections 量不同 :

t2.micro    66
t2.small    150
m3.medium   296
t2.medium   312
M3.large    609
t2.large    648
M4.large    648
M3.xlarge   1237
R3.large    1258
M4.xlarge   1320
M2.xlarge   1412
M3.2xlarge  2492
R3.xlarge   2540

從 snapshow 復原 DB

  1. DB Instance Identifier 是 AWS RDS 辨認的 ID, 只要不要重覆就好
  2. 記得取選 Security group
  3. 修改 Master password (也就是 DB admin 的 password)

如果要恢復整個 DB => 將程式 RDS endpoint 直接指向新的, 舊的再砍掉

如果要恢復每個 TABLE => 要先用 mysqldump 指令把那個 TABLE 匯出, 再到要復原的 DB TRUNCATE 那個 TABLE 後再匯入

Slow query

在 instance 下的 Parameter group, 點進去輸入 slow, 看 slow_query_log 有沒有打開

進入 mysql console 去 query mysql.slow_log, 參考 Slow query

Dynamo DB

細節特性

Elastic Cache

[操作]

先新增 Cache Subnet Groups, 把 VPC 的 Subnet 選進去

Security Group 要開 6379 port

CloudFront

cloudfront + s3 (with custom domain over SSL)

  1. 建立
  1. 送出後, 設定 route53 把 sub domain 指到這個 cloudfront 的 Domain Name

  2. Edit Distribution -> General

  1. Edit Distribution -> Origin
  1. 測試

pre-signed url + custom domain

  1. 將基本的 cloudfront custom domain 設定好
  2. 建立 cloudfront 專用的 key pair
    • 一定要用主帳號新增 (IAM users can’t create CloudFront key pair. You must log in using root credentials to create key pair.)
    • 右上角帳號選單 -> My Security Credentials -> CloudFront key pairs -> Create New Key Pair -> Download Private Key File (Pulblic Key File 可以先載但用不到) -> Copy Access Key ID (實際上只會用到 Private Key, 它只能載一次)
  3. 設定 Distribution 的 Origin
    • Restrict Bucket Access : Yes.
    • Your Identities : Use an Existing Identity (沒有的話就選 Create a New Identity)
    • Grant Read Permissions on Bucket : Yes, Update Bucket Policy (註1)
  4. 新增 S3 bucket + 放一個 test.jpg 測試是否可以通, (Permissions -> Public access -> Read object 打勾) e.g. https://example.com/test.jpg
  5. 禁止外部直接取得 s3 資源 CloudFront 的 Behavior 設定
    • Viewer Protocol Policy : HTTPS Only or Redirect HTTP to HTTPS
    • Restrict Viewer Access (Use Signed URLs or Signed Cookies) : Yes (允許可以用 signed URL or signed cookie access 檔案)
    • Trusted Signers : Self
  6. 已經禁止外部直接 e.g. https://example.com/test.jpg 就看不到東西了
  7. 將 private_key 上傳到主機並以各語言實作

註1 : 如果本身 bucket 有其他 policy 當你選擇 Yes, Update Bucket Policy 送出後,它會變回 No, I Will Update Permissions,實際上它已經更新 s3 bucket 的 policy 了

{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E3D7VZ7WMEZSYS"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::test-bucket/*"
        }
    ]
}

ref :

清除 cache

目的: 如果 cloudfront 上的檔案還沒 expire, 你的靜態檔如果更新了, 但拉到也可能還會是舊的, 可以選擇手動將 cache 清掉

CloudFront Distributions -> (選 ID,點進去) -> Invalidations -> Create Invalidation -> 輸入要清除的 uri(也可以用 * 清掉全部) -> Invalidate

S3

權限

要先了解 S3 有三種權限控制它

  1. Bucket policies : Attached to bucket
  2. ACLs : Grant access to specific AWS account or anonymous,可以各別定義 Grantee (一種身份) 可以對這個 bucket 做什麼事,預設是 root account 都可以
  3. IAM : Attached to user, json based ,讓你能不能進入 S3 的 WebUI,但實際上跟你有沒有權限用 API 的方式操作這個 Bucket 沒有關係

IAM 需要去 IAM 服務才能給予權限,而 Bucket policies 及 ACLs 可以在 S3 webUI 就可以選擇了

ACLs 只有一些 Group 讓你選 :

Bucket policies :

AWS-SDK / AWS-CLI 上傳及下載 (必要設定)

如果發生沒有設定,在上傳時會發生 Access Denied

upload failed: ./test.txt to s3://buname_name/test.txt A client error (AccessDenied) occurred when calling the PutObject operation: Access Denied

剛建立的 Bucket 你一定要額外給予它被上傳的權限,否則無法透過 API 的方式上傳 (與 IAM Policy AmazonS3FullAccess 無關)

本以為新增 permission (Add more permissions) 就可以做到,但發現是不行的,所以要使用以下的方法去新增它的權限

Properties -> Permission -> Edit bucket policy -> 點選下面的 AWS Policy Generator 它可以幫你產生 Policy,但我們需要把表填一填

  1. Select Type of Policy : S3 Bucket Policy
  2. Effect : Allow (維持預設)
  3. Principal : arn:aws:iam::6**********4:user/app_server (其實就是 IAM 的某位 User 的 User ARN)
  4. AWS Service : Amazon S3 (維持預設)
  5. Actions : 選三個就好 DeleteObject GetObject PutObject
  6. Amazon Resource Name (ARN) : arn:aws:s3:::my-bucket/*

Generate Policy 後複製下來,再貼到 Edit bucket policy 那裡

{
    "Version": "2012-10-17",
    "Id": "Policy1461726945589",
    "Statement": [
        {
            "Sid": "Stmt1461726943472",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::624758352504:user/app_server"
            },
            "Action": [
                "s3:DeleteObject",
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::my-bucket/*"
        },

        # 這邊是另外加上的, 讓外部可以直接 Access 檔案
        {
            "Sid": "Stmt1461734747651",
            "Action": [
                "s3:GetObject"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::my-bucket/*",
            "Principal": "*"
        }
    ]
}

然候應該就可以上傳,也可以下載了。

下載也是要使用上述的設定才可以設定公開,我試過在 Bucket 最頂層 Add more permission 設定 Grantee : Everyone, Action 只允許 List,但結果是沒有用的

ref : 關於 S3 權限

對這個 bucket 設定任何人都可以下載檔案

click {bucket_name} -> Properties -> Edit bucket policy

{
    "Version": "2008-10-17",
    "Id": "Policy1416798504862",
    "Statement": [
        {
            "Sid": "Stmt1416798496088",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::{this_bucket_name}/*"
        }
    ]
}

AWS-CLI command 上傳到 s3

安裝 aws cli

sudo apt-get install awscli

上傳

$ aws configure
AWS Access Key ID :
AWS Secret Access Key :
region name : us-west-2                     # 可以在 S3 該 Bucket 的 URL 找到 i.e. ?region=ap-northeast-1#&bucket=
output format : none
$ echo "test" > test.txt
$ aws s3 cp test.txt s3://bucket_name/      # 將 bucket_name 替換為你的 bucket name
$ curl http://bucket_endpoint/test.txt
test

其他相關 cli 指令

aws s3 cp s3://another-bucket/file.txt s3://my-bucket/          # 從其他 bucket copy
aws s3 cp test.txt s3://my-bucket/                              # copy local file to my-bucket
aws s3 ls s3://my-bucket/                                       # my-bucket 下的檔案列表
aws s3 ls                                                       # bucket list

Delete folder

There is no such thing as folders in S3; There are simply files with slashes in the filenames.

Many S3 tools will visualize these slashes as folders, but they’re not real.

You can delete all files with the same prefix, but first you need to look them up with list_objects(), then you can batch delete them.

ref : https://forums.aws.amazon.com/message.jspa?messageID=249514

刪除所有檔案, 目錄也會自動消失

SQS

AWS SQS 是一套 Queue 的系統,儲存要處理的工作,通常都是一個 message 用 json encode 存進去,再來就是自已實作 worker 那一段再串 SQS。

SES

修改 mailed-by

The mailed-by header is the usually used to persist the content of the envelope from or MAIL FROM through forwarding.

Amazon do not allow the MAIL FROM to be customised. The following quote is from an Amazon employee in a comment on an blog post about SPF & DKIM

The headers you mentioned [mailed-by] seem to be something appended by an ISP after the message left Amazon SES, rather than standard message headers.
We unfortunately do not have control over receiver add-ons.
Nevertheless, assuming that the “mailed-by” value is based on the MAIL-FROM, the answer would be that right now all emails sent through Amazon SES have amazonses.com (or a subdomain of that) as the MAIL-FROM domain.
We don't currently support its customization

Posted by Adrian@AWS on November 4, 2014 8:31:29 AM PST

ref : https://serverfault.com/questions/641262/remove-or-replace-mailed-by-field-with-dkim-spf-enabled

gmail 顯示的 from & singed-by

signed-by 顯示的 domain 是通過 domain Auth 的 SES ARN

寄信的時候你可以只指定 from, ses 會判斷 from 的 domain 並且使用對應的 SES ARN

也可以指定 SES ARN 寄信,但其實沒那麼必要,因為 fromdomain 的 SES ARN 的 domain 必須要是一樣的,否則信會寄不出去

當一封信收到後,fromsigned-by 一定會是一樣的

CloudFormation

將 region 下所有的主機資訊輸出成 JSON, 如果下次要重 build 一個環境可以直接執行, 但記得要改參數

[操作]

  1. 進去會看到兩個按鈕, 上面是 Create New Stack, 如果已有建立好的 Template 就選擇它, 下面是 Launch CloudFormer, 如果還沒有建立 Template 就選擇它, 將你目前的 AWS 的服務轉成 Json
  2. 所以先選 Launch CloudFormer, 注意! 必須要有 AWS 本身 region 的 default VPC, 否則會一直出現 error 啟不起來,
  3. 成功後會自動在 EC2 建立一個 instance, 接著連到這個 instance 的 public IP, 就可以開始設定了 (建立的那個帳號要有 IAM Full Access 權限才可以將 instance 跑起來)
  4. 設定完後會產生一份 JSON 格式的 template, 把它存起來
  5. 需要改的地方, 以 singapore 與 frankfurt 舉例, 簡稱 sin 跟 fr, 將 sin 的 AZ 名稱取代成 fr 的 AZ 名稱

無法解決

Security Group 的 outbound 0.0.0.0/0 一直出現 AWS::EC2::SecurityGroupEgress Encountered unsupported property CidrIP, 找不出解決方法, 最後就放棄使用 CloudFormation 了

ECS

  1. Create Cluster
    • If it failed, you need to go to CloudFormation to delete that stack becuase it uses CloudFormation under the hood
  2. Create a Task Definition

Opsworks

Elastic Beanstalk

可以起一個 web server 並且放在 auto scaling 下, 或者是選擇一個 docker file

並且選擇要如何更新 server, 有兩種方法,

  1. 一種是百分比的, 如果是 30%, 那麼 AWS 就會以一次 shutdown 30% 的主機, 進行更新
  2. 另種是一次幾台, 如果是一次一台的話, 那麼就會一台一台更新

Cognito

不需要煩惱及建置後端架構, 透過此服務即可達到 mobile 互相交換訊息

Mobile Analytics

Mobile 的 GA

CloudTrail

AWS console log

Lambda

建立 Function,使用 IAM Role 讓它可以 call DynamoDB

  1. 在 IAM Role 建立一個 role,policy 這個 AmazonDynamoDBFullAccess 就好

  2. 到 Lambda 建立 function : Configure function

  1. 先選擇 code inline 否則如果一開始沒有檔案會無法建立

讓lambda 的 log 可以紀錄在 cloudwatch Log Groups /aws/lambda/{lambda_name}

先去看該 lambda function 的 Existing role 叫什麼, 然候再到 IAM Role 那將 Policy CloudWatchLogsFullAccess 加到這個 role, 就可以在 cloudwatch 看到執行這個 function 時的 log 了

Index

SMS

寄 簡訊

SNS

Registger SNS

宣要注意的是

Push Notification

Create Notification ARN by Platform

發送 GCM notification 格式 (不管 production 還是 dev 都用這個)

{ "GCM": "{ \"notification\": { \"body\": \"test body\",\"title\": \"test title\",\"icon\": \"test icon\" },\"data\": { \"custom_field\": \"custom_value\" } }" }

Andriod 的聲音是 app 自已決定的

發送 APNS notification 格式 (production)

 { "APNS":"{\"aps\":{\"alert\":\"Hello World!!\",\"sound\":\"default\"},\"custom_field\": \"custom_value\"}" }

自行決定是否要帶聲音的參數

APNS_SANDBOX 格式 (dev)

 { "APNS_SANDBOX":"{\"aps\":{\"alert\":\"Hello World!!\"},\"custom_field\": \"custom_value\"}" }

Apple notification 的 title 不像 GCM 可以自訂, 它是不能動的, title 固定都顯示 app name.

Error: PlatformApplicationDisabled: Platform application is disabled

IOS credentials 在 AWS SNS 上過期了, 需要請 IOS developer 重新產生 credentials, 產生完選擇要 renew 的 ARN, 再選 Update credentials 重新上傳就可以了

註: IOS credentials 一年就會過期, 需要每年更新

android 不會有這個問題

Kinesis

主要是用來做 log 收集及分析, 跟 Apache Kafka 做的事情很類似

Kinesis vs Kafka

將 cloudwatch log 傳送到 kinesis firehose 處理, 並將結果存到 s3

步驟可參考官方文件, 但裡面都是用指令去建立, 而我是用 Web Console 來設定

1~4 可以用 Web Console 達成, 5 之後就要下指令才能達成

[1] 先建立一個 s3 專門給 cloudwatch 或 kinesis 使用

[2] 建立新的 IAM Role 給 Kinesis, Create role -> AWS Service -> Kinesis (這邊很重要, 一定要選, 否則第 3 步驟要選 IAM Role 會看不到這個), 建立完 Role 選擇 Attach policies 旁邊的 Add inline policy, 為的是讓它有權限寫入到步驟 1 的 S3

{
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:AbortMultipartUpload",
                "s3:GetBucketLocation",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::qa-test-cloudwatch-logs",        // 要改成步驟1 建立的 bucket
                "arn:aws:s3:::qa-test-cloudwatch-logs/*"       // 要改成步驟1 建立的 bucket
            ]
        }
    ]
}

[3] 建立 Kinesis firehose

[4] 測試 Kinesis firehose

點選 Start sending demo data, 邊觀察下面的 Monitoring 及 S3 是否有資料

cloudwatch logs 會出現這個 group e.g. /aws/kinesisfirehose/, 不過都不會有 log, 可能是 kinesis 有 error 才會在這

Kinesis 的測試資料

{"ticker_symbol":"HJK","sector":"TECHNOLOGY","change":0,"price":4.78}
{"ticker_symbol":"XTC","sector":"HEALTHCARE","change":-4.34,"price":108.7}

(optional) 當 kinesis horse 建立完成後, 建立 Data Analytics 分析結果

Data Analytics 只有幾個 rigion 支援

[1] Create

[2] Kinesis firehose 點選 Start sending demo data, 讓資料一直進來, 因為要一直有資料進來才好完成接下來的步驟

[3] SQL Query

  1. SQL (這裡做的是把 price > 80 的資料儲存下來)

    CREATE OR REPLACE STREAM “DESTINATION_SQL_STREAM” (ticker_symbol VARCHAR(4), sector VARCHAR(12), change DOUBLE, price DOUBLE);

    CREATE OR REPLACE PUMP “STREAM_PUMP” AS INSERT INTO “DESTINATION_SQL_STREAM” SELECT STREAM “ticker_symbol”, “sector”, “change”, “price” FROM “SOURCE_SQL_STREAM_001” WHERE “price” > 80

欄位要用 " 包起來, 否則它內部會幫你自動轉大寫, 送出後會跟你說找不到這個欄位的錯誤

  1. Save and run SQL (如果要改可以隨時改, 再點擊這個讓它生效)

[4] Connect to a destination

SQL 的結果總要有地方來儲存吧? 它這裡無法直接寫入 S3, 必須要靠 firehose 寫入

  1. 建立 Kinesis Firehose delivery stream 給這個 Data Analytics 儲存結果, 建立過程跟之前一樣, 只是產生在 S3 的 Prefix 改成用 Data-Analytics_ 以便分類
  2. Destination -> Kinesis Firehose delivery stream -> 選擇剛建立的 firehose
  3. Connect in-application stream -> DESTINATION_SQL_STREAM (SQL Query 建立的 stream name)

[5] 看測試結果

看 s3 bucket 下有沒有 folder data-analytics_2018, 並且看裡面的檔案, 看看 price 是否 > 80

(optional) 當 kinesis horse 建立完成後, 將 CloudWatch Log 傳到 Kinesis

接下來就要下指令了, 無法用 Web Console 達成

/tmp/TrustPolicyForCWL.json

{
  "Statement": {
    "Effect": "Allow",
    "Principal": { "Service": "logs.ap-northeast-1.amazonaws.com" },     // region 要改
    "Action": "sts:AssumeRole"
  }
}

建立 IAM Role

aws iam create-role --role-name CWLtoKinesisFirehoseRole --assume-role-policy-document file:///tmp/TrustPolicyForCWL.json

file://{file path}

/tmp/PermissionsForCWL.json

{
    "Statement":[
      {
        "Effect":"Allow",
        "Action":["firehose:*"],
        "Resource":["arn:aws:firehose:region:123456789012:*"]
      },
      {
        "Effect":"Allow",
        "Action":["iam:PassRole"],
        "Resource":["arn:aws:iam::123456789012:role/CWLtoKinesisFirehoseRole"]
      }
    ]
}

裝 policy 跟 IAM Role 關聯

aws iam put-role-policy --role-name CWLtoKinesisFirehoseRole --policy-name Permissions-Policy-For-CWL --policy-document file:///tmp/PermissionsForCWL.json

將要傳送 CloudWatch Log 的 group 連接到 Kinesis

aws logs put-subscription-filter --log-group-name "dev-worker-logs" --filter-name "FirehoseDestination" --filter-pattern ""  --destination-arn "arn:aws:firehose:ap-northeast-1:3**********2:deliverystream/qa-kinesis-test" --role-arn "arn:aws:iam::3**********2:role/CWLtoKinesisFirehoseRole"

[6] 確認是否 log 都有被送到 Kinesis Firehose

看 monitoring 就能知道

如果不要將 cloudwatch logs 傳到 kinesis (取消訂閱), 在 cloudwatch logs 的該 group 上選擇 Remove Subscription Filter

ref:

Other

安裝 AWS CLI tool

$ curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip"
$ unzip awscli-bundle.zip
$ sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws

[建立可以看 billing 的帳號]

除了建立一個 IAM User 並給予權限 (AWSAccountActivityAccess), 但光是這樣還是看不到花費狀況, 還要去主帳號的 Dashboard -> 帳號 -> IAM 用戶對賬單信息的訪問權限 -> 激活IAM 訪問權限, 這樣就可以了

現在登入 IAM User 帳號, 應該就能看到帳單資料了

[其他服務]