この記事は DENSOアドベントカレンダー2020 の4日目の記事です。
今年は仕事でAWS上で構築したものをAWS Chinaでも動作するようにする機会があったのですが、まあそれ自体情報が少ないのと、AWS ChinaとAWSの違いで苦労したので、今後挑戦する方のためにまとめておきます。
はじめに
AWS Chinaとは?
中国版のAWS
https://www.amazonaws.cn/en/about-aws/china/
なんですがAWSと似ているようでちょっと違います。
AWS ChinaとAWSの違いについて
少なくとも以下の違いはありました
- グローバルで展開されているサービスがAWS Chinaで提供されていないことがある
- ARNの書きかたが違う
- コスト管理系のサービスのリージョンが違う
グローバルで展開されているサービスがAWS Chinaで提供されていないことがある
https://pages.awscloud.com/rs/112-TZM-766/images/H1-07.pdf
にもまとまっていますがAWS Chinaで使用できないサービスがある場合もあります
自分たちがすでに使用していたがAWS Chinaで使えなかったとサービスたち
他にもいろいろ違いがありますが
- AWS GuardDuty
- AWS Config のマネージドルールがない(guardduty-enabled-centralized,acm_certificate_expiration_check_enabled)
ちなみにAWS Chinaで提供されているサービスはAWS Chinaのページから確認できます
ARNの書きかたが違う
ARNs for AWS services in Chinaに記載があるように
に
グローバル:aws
AWS China:aws-cn
となる
ARNの書き方が違うせいでTerraform ではこんなエラーが出た
Terraformを使用して構築を自動化していたのですがこのARNの違いによってAWS Chinaでは構築エラーになりました。
以下具体的に遭遇したエラーです。
ロググループの定義でエラー
Error: Error putting IAM role policy lambda_cost-explorer: MalformedPolicyDocument: Partition "aws" is not valid for resource "arn:aws:logs:cn-north-1:*:log-group:/aws/lambda/cost_explorer_slack_notification:*".
status code: 400, request id: 0413d587-ef1b-43e9-b1dd-1c98ada10e2d
on modules/cost_explorer/iam.tf line 31, in resource "aws_iam_role_policy" "lambda_for_cost_explorer":
31: resource "aws_iam_role_policy" "lambda_for_cost_explorer" {
もともとのコード
例えばTerraformのコードが以下のようになっていた部分があったのですがこれらが全部AWS Chinaではエラーになりました。
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": ["arn:aws:logs:${var.region}:*:log-group:${aws_cloudwatch_log_group.cost_explorer_slack_notification.name}:*"],=>ここにawsと書いていた
"Effect": "Allow"
}
]
}
修正例
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": ["arn:*:logs:${var.region}:*:log-group:${aws_cloudwatch_log_group.cost_explorer_slack_notification.name}:*"], =>*にしちゃう
"Effect": "Allow"
}
]
}
大半のサービスは上記置き換えで動作するようになったのですが、S3の定義についてはこのような置き換えではエラーになったりします。
バケットポリシーでエラー
これはちょっとやっかいロググループみたいに*で置き換えたらエラーになる
Error: Error putting S3 policy: MalformedPolicy: Policy has invalid resource
status code: 400, request id: 6774E20500A4AB30, host id: /6snJ2Mq7154TaCvqhOf5FAnOEFF6V92mgZKtRRRaS+PJo/59Aw3PMLhg7emCya6fHoWzk+6jtI=
on modules/aws_config/main.tf line 15, in resource "aws_s3_bucket" "aws_config":
15: resource "aws_s3_bucket" "aws_config" {
修正前(もともとのコード)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AWSConfigBucketPermissionsCheck",
"Effect": "Allow",
"Principal": {
"Service": "config.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": ["arn:aws:s3:::${local.config_bucket}"]
},
{
"Sid": "AWSConfigBucketDelivery",
"Effect": "Allow",
"Principal": {
"Service": "config.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": ["arn:aws:s3:::${local.config_bucket}/AWSLogs/${var.account_id}/Config/*"],
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
}
]
}
こうしないと中国では動かない(ただこれでは中国でしか動かなくなる)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AWSConfigBucketPermissionsCheck",
"Effect": "Allow",
"Principal": {
"Service": "config.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": ["arn:aws-cn:s3:::${local.config_bucket}"]
},
{
"Sid": "AWSConfigBucketDelivery",
"Effect": "Allow",
"Principal": {
"Service": "config.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": ["arn:aws-cn:s3:::${local.config_bucket}/AWSLogs/${var.account_id}/Config/*"],
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
}
]
}
修正例
バケットポリシーを後付にして作成したバケットからarnを取得するようにする。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AWSConfigBucketPermissionsCheck",
"Effect": "Allow",
"Principal": {
"Service": "config.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": ["${aws_s3_bucket.aws_config.arn}"]
},
{
"Sid": "AWSConfigBucketDelivery",
"Effect": "Allow",
"Principal": {
"Service": "config.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": ["${aws_s3_bucket.aws_config.arn}/AWSLogs/${var.account_id}/Config/*"],
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
}
]
}
コスト管理系のサービスのリージョンが違う
コスト管理系のサービス(AWS Cost Explorerとか)はAWSだとバージニア北部(us-east-1)ですがAWS ChinaだとNingxia(cn-northwest-1)になります。
詳細は
https://docs.aws.amazon.com/general/latest/gr/billing.html
に記載されている通り
コスト通知の仕組みを実装していてる場合はリージョンが変わるので注意
まとめ
AWS Chinaを使用する場合に困ったこと、注意すべきことをまとめました。
AWS Chinaを使用することになったときに参考になれば幸いです。