1. 程式人生 > 實用技巧 >AWS中國區的那些“坑”

AWS中國區的那些“坑”

前言

最近做的一個專案是要把公司在國外已經上線的一個物聯網的專案移植到AWS中國區來。
由於AWS屬於國外雲產商,在中國運營,必須符合國家的相關規定:

  • 必須是合資公司 (AWS北京區由北京光環新網運營,寧夏區由西雲資料運營)
  • 拿到ICP認證
  • 伺服器和資料必須在物理上中國境內
  • 其他

AWS在Global區已有的服務,也是一點點在中國上線的,例如2020年上線了很多重要的服務,Route53、Certificate Manager等等, 可以在這裡檢視最新上線的服務
我曾經問過AWS中國的support人員,其他未上線的服務是否有時間表?support人員,一般標準回答都是:"沒有準確的時間表。"
AWS的中國區和AWS在Global的其他區之間是"不相通的

";賬號是獨立分開的,中國區的賬號下,目前只有北京和寧夏兩個region

從這段時間的工作經驗,總結出要把國外的AWS雲專案移植到中國需要注意的一些"坑", 其中很多問題,在中文社群很難找到相關文章,所以決定分享出來,避免大家再走彎路!

坑一:arn問題

問題描述

AWS的各個資源,都有一個arn,作為全域性唯一的標識, 例如:arn:partition:service:region:account-id:resource-id
我們一般會在程式碼中會直接這樣寫:arn:aws:apigateway:region:lambda, 這樣寫,在AWS Global基本上沒有問題,但是在中國區,AWS採取了不同的arn
上面的那個例子在中國區就變成了: arn:aws-cn

:aipgateway:region:lambda

大部分公司都希望一套程式碼在全球使用,不希望單獨為中國區準備一個版本。那怎麼樣做到相容呢?

解決方案

在cloudFormation內建指令碼中有一個引數Partition, 有了這個引數,上面的arn的寫法就變成了: arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda

為了做到批量修改,我們可以使用一些輔助工具replace,它還支援正則表示式
以下是一段參考指令碼,適用於在CloudFormation中存在arn hardcode的情況, 可以根據具體情況進行修改替代規則

npm install -g replace
replace '!Sub "arn:aws:' '!Sub "arn:${AWS::Partition}:' *.template.yaml
replace '"arn:aws:iot:",{ "Fn::Sub": "${AWS::Region}" }' '{ "Fn::Sub": "arn:${AWS::Partition}:iot:${AWS::Region}" }' *.template.yaml

坑二:網址域名字尾

問題描述

在Global區,在生成的APIGateway和S3地址都是:https://.amazonaws.com, 在中國區變成了https://.amazonaws.com.cn

解決方案

目前我採取的方案,有些ugly:

  • 把所有hardcode的amazonaws.com用佔位符替換掉
  • 部署的時候,根據目標環境替換成對應的值
    虛擬碼
# preparation
replace '.\$\{AWS::Region\}.amazonaws.com' '.${AWS::Region}.#AMAZONAWS#' *.template.yaml

# deployment stage
if "target is China"
      replace '#AMAZONAWS#' 'amazonaws.com.cn' *.template.yaml
else
      replace '#AMAZONAWS#' 'amazonaws.com' *.template.yaml

坑三:可用區問題

問題描述

在Global區,大部分的region都有3個及以上可用區,所以在自動化建立VPC腳本里面,會預設使用3個可用區,however,在北京區(cn-north-1)目前只有兩個可用區

解決方案

為了相容性,方案類似於坑二,就是在部署指令碼中需要判斷目標區域的可用區數量,然後決定是用2個或3個可用區的指令碼,建議VPC的部署指令碼分成兩份,一份支援兩個可用區,另外一個支援三個可用區

坑四:APIGateway埠 80\443預設關閉問題

問題描述

曾經被這個問題耽誤了很長時間,明明一個很簡單的APIGateway+lambda應用,從本地postman怎麼也發不通!後來發現每個賬號,預設80和443埠是不通的!

解決方案

需要從AWS Console錄一個support的case來開通。另外你的組織可能已經開始使用AWS Organization來管理多級賬號了,每個子賬號都需要用這種方式來開通埠
case參考模板:

坑四:計費單位

問題描述

有時候需要設定一些Alarm,當費用超預算時,自動郵件通知,設定計費單位的時候,需要注意,中國區目前只支援CNY

解決方案

不要hardcode,而是把計費單位作為引數傳進去

Parameters:
      MoneyUnit:
            Type: String
            Default: USD
Resources:
      DynamoDBBudget:
            Type: "AWS::Budgets::Budget"
            Properties:
                  Budget:
                        BudgetLimit:
                              Amount: !Ref DynamoDBBillingTreshold
                              Unit: !Ref MoneyUnit
                        TimeUnit: MONTHLY

不可用服務替代方案

之前提過,很多服務在中國區未上線,不可用,但很多全球專案又深度依賴這些服務。這個時候,就需要尋找替代方案。順便說一下,在做整體架構設計的時候,可能需要考慮我的現有程式碼要從一個雲產商移植到另外一個雲產商需要付出的代價,這裡就不展開講了。

AWS Cognito User Pool -> Keycloak

問題描述

我們的專案深度依賴Cognito user pool, Cognito user pool和APIGateway整合, 做使用者身份驗證和授權,遺憾的是這個服務在中國區不可用。

解決方案

我們找到一個非常強大的做使用者管理和身份驗證的開源專案:Keycloak
經過實踐,完美解決:用lambda寫一個customize authorizer和APIGateway進行整合

其他

一位一起工作的國外同事,在國外,經常碰到一些網路連線的問題,開AWS China Console間歇性斷網,非常影響工作效率。
後來的臨時解決方案是先走公司內網,連到一臺中國的伺服器(jump server),再從這臺伺服器上連線AWS Console。
總覺得不是一個非常好的方案,建議能在國內有一名開發人員配合工作,提高效率!

寫在最後

說是“坑”,其實是調侃,畢竟世界發展太快,之前的開發人員可能也沒預料到科技受到各種ZZ因素的影響,導致無法理想化的大一統!
程式設計師就是這麼一個職業,不斷的給別人挖坑,填別人的坑!哈哈
好了,分享使我快樂,有什麼問題,請留言。