ソリューションライブラリにリリースされた Tag Tamer のセットアップ方法とつまづきポイントをまとめてみた

2021.07.02

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

いわさです。

AWSのソリューションライブラリに "Tag Tamer" というソリューションがリリースされました。
機能や使い勝手はどのような感じかまとめて近日記事にしようと考えています。

セットアップで少し躓きました。
テンプレート実行で終わり、とはいかず事前準備や事後設定が必要です。

ドキュメントのセットアップ手順を参考に進めることは出来るはずですが、わかりにくい部分は調べて解決していったので、今回記事に残すことにしました。

Tag Tamerとは

AWSリソースのタグ適用やタグ管理をTag Tamer専用Web画面で行うことが出来ます。
標準のタグエディターとの違いなどは別途紹介したいと思います。

AWSソリューションライブラリから CloudFormationテンプレートをダウンロードし、デプロイを行う形となります。

テンプレートは2種類用意されており、インターネットへ Tag Tamer ポータルサイトを公開するパブリックテンプレートと、プライベートネットワーク上でのみ利用するプライベートテンプレートと2種類用意されています。
DirectConnectやVPN経由でのアクセスのみにしたい、などの場合はプラベートテンプレートを使うことになります。

本記事ではパブリックテンプレートを使ってデプロイを行います。
なお、パブリックテンプレートでもIPアドレスによるアクセス元の制限は可能です。

注意点として、デプロイ可能リージョンの制限があります。

ソリューション内では様々なサービスや機能が使われていますが、そのひとつでCognitoとSESの統合機能を使っています。
Cognito自体は様々なリージョンで使えるのですが、CognitoのSES統合機能は現時点では eu-west-1, us-east-1, us-west-2 でのみ使うことが可能です。

その関係で Tag Tamer も上記3つのリージョンのいずれかで展開する必要があります。

テンプレート実行前の準備

テンプレートのパラメータに必要な以下の2つを事前に準備する必要があります。

ACMを準備する

ACM証明書を用意します。
以下に従い今回は自己証明書を用意しACMへインポートしました。

検証済みかつ Cognito からの利用を許可した Amazon SES Eメールアドレスを用意する

Amazon SES で Eメールを登録し、検証を行います。

CognitoのSES統合は対応リージョンがまだ少なく、東京リージョンでCloudFormationを実行しようとすると以下のエラーが発生します。

Invalid EmailConfiguration.SourceArn. Provided SourceArn must be in one of the following SES regions: eu-west-1, us-east-1, us-west-2. (Service: AWSCognitoIdentityProviderService; Status Code: 400; Error Code: InvalidParameterException; Request ID: 11007006-b4a9-4163-b5e0-d6e8f7783b0e; Proxy: null)

Cognito+AmazonSESの対応リージョンについては以下に記載があります。

ただし、対応リージョンだとしてもCognitoからの呼び出しの許可を行っていないと、CloudFormationスタック作成時に以下のエラーが発生します。

Cognito is not allowed to use your email identity (Service: AWSCognitoIdentityProviderService; Status Code: 400; Error Code: InvalidEmailRoleAccessPolicyException; Request ID: 76c5cf52-b085-4ed4-b3dd-bf9421ce5c9b; Proxy: null)

その場合、以下の手順でポリシーを作成し割当を行います。
検証済みIdentityを選択し、Cognitoへのメール送信の承認許可ポリシーを設定します。

テンプレート実行

事前準備した2つの情報をパラメータにCloudFormationを実行します。
この時にアクセス元IPアドレスの制限設定も可能です。

テンプレート実行後

CloudFormationスタックの作成に成功してもすぐに利用は出来ません。
Tag Tamerポータル画面では Cognito を使ったユーザー管理を行っています。

IDプールへの認証ロールの割当と、ユーザープールでグループの作成が必要です。

Cognito IDプール 認証ロール設定を変更

CloudFormationによって Cognito IDプールが作成されていると思います。   作成されたIDプールを選択し、"IDプールの編集"を選択します。

認証プロバイダーセクションでCognitoタブを選択し、認証されたロールの選択で「トークンからロールを選択する」を選択し、ロールの解決に「拒否」を設定します。

Cognitoユーザーグループとロール、ポリシーの作成とアタッチ

CloudFormationによってCognitoユーザープールも作成されていると思います。
ユーザープールからグループの作成を選択します。

ロールとポリシーを作成します。
設定内容はドキュメントに従えば問題ありません。

ロールの信頼設定に利用しているロール名を指定する必要があるのでそこだけ適宜変更をしてください。

TagTamerAllAdminPermissionsPolicy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "TagTamerDynamoDBTables",
            "Effect": "Allow",
            "Action": [
                "dynamodb:PutItem",
                "dynamodb:GetItem",
                "dynamodb:Scan",
                "dynamodb:UpdateItem"
            ],
            "Resource": [
                "arn:aws:dynamodb:*:*:table/tag_tamer_roles",
                "arn:aws:dynamodb:*:*:table/tag_tamer_tag_groups"
            ]
        },
        {
            "Sid": "TagTamerAllAdminPermissions",
            "Effect": "Allow",
            "Action": [
                "codecommit:GetRepository",
                "codecommit:ListRepositories",
                "codecommit:ListTagsForResource",
                "codecommit:TagResource",
                "codepipeline:ListPipelines",
                "codepipeline:GetPipeline",
                "codepipeline:TagResource",
                "codepipeline:ListTagsForResource",
                "config:DescribeConfigRules",
                "config:ListTagsForResource",
                "config:PutConfigRule",
                "config:TagResource",
                "config:UntagResource",
                "dynamodb:DescribeTable",
                "dynamodb:ListTables",
                "dynamodb:ListTagsOfResource",
                "dynamodb:TagResource",
                "dynamodb:UntagResource",
                "ec2:CreateTags",
                "ec2:DeleteTags",
                "ec2:DescribeInstances",
                "ec2:DescribeTags",
                "ec2:DescribeVolumes",
                "ecr:DescribeRepositories",
                "ecr:ListTagsForResource",
                "ecr:TagResource",
                "ecr:UntagResource",
                "ecs:DescribeClusters",
                "ecs:DescribeTasks",
                "ecs:DescribeTaskDefinition",
                "ecs:ListTagsForResource",
                "ecs:TagResource",
                "ecs:UntagResource",
                "eks:DescribeCluster",
                "eks:DescribeNodegroup",
                "eks:ListClusters",
                "eks:ListNodegroups",
                "eks:ListTagsForResource",
                "eks:TagResource",
                "eks:UntagResource",
                "iam:GetRole",
                "iam:ListPolicies",
                "iam:ListRoles",
                "iam:ListRolePolicies",
                "iam:ListRoleTags",
                "iam:TagRole",
                "iam:TagUser",
                "lambda:GetFunction",
                "lambda:ListFunctions",
                "lambda:ListTags",
                "lambda:TagResource",
                "rds:AddTagsToResource",
                "rds:DescribeDBClusters",
                "rds:DescribeDBClusterEndpoints",
                "rds:DescribeDBInstances",
                "rds:DescribeGlobalClusters",
                "rds:DescribeOptionGroups",
                "rds:ListTagsForResource",
                "rds:RemoveTagsFromResource",
                "redshift:CreateTags",
                "redshift:DeleteTags",
                "redshift:DescribeClusters",
                "s3:PutObjectTagging",
                "s3:DeleteObjectTagging",
                "s3:GetBucketTagging",
                "s3:GetObject",
                "s3:GetObjectTagging",
                "s3:ListAllMyBuckets",
                "s3:ListBucket",
                "s3:PutBucketTagging",
                "s3:ReplicateTags",
                "servicecatalog:AssociateTagOptionWithResource",
                "servicecatalog:CreateTagOption",
                "servicecatalog:DescribeProduct",
                "servicecatalog:DescribeProductAsAdmin",
                "servicecatalog:DeleteTagOption",
                "servicecatalog:DescribeTagOption",
                "servicecatalog:DisassociateTagOptionFromResource",
                "servicecatalog:ListTagsForResource",
                "servicecatalog:ListTagOptions",
                "servicecatalog:SearchProducts",
                "servicecatalog:SearchProductsAsAdmin",
                "servicecatalog:TagResource",
                "servicecatalog:UntagResource",
                "servicecatalog:UpdateTagOption",
                "sts:AssumeRole"
            ],
            "Resource": "*"
        }
    ]
}

TagTamerAllAdminPermissionsRole

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/xxxxx"
      },
      "Action": "sts:AssumeRole",
      "Condition": {}
    },
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Federated": "cognito-identity.amazonaws.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity"
    }
  ]
}

ロールとポリシーが作成されたら、Cognitoユーザープールの先程作成したユーザーグループにロールを割り当てします。

ただし、マネジメントコンソール上だとロールが表示されない場合があります。

この現象はドキュメントでも言及されており、CLIでコマンドを使うよう指示がされています。

[cloudshell-user@ip-10-0-167-119 ~]$ aws cognito-idp list-user-pools --max-results 10
{
    "UserPools": [
        {
            "Id": "us-east-1_uzIkdAoBS",
            "Name": "tag_tamer_user_pool",
            "LambdaConfig": {},
            "LastModifiedDate": "2021-07-02T08:00:50.901000+00:00",
            "CreationDate": "2021-07-02T08:00:50.901000+00:00"
        }
    ]
}
[cloudshell-user@ip-10-0-167-119 ~]$ aws cognito-idp list-groups --user-pool-id us-east-1_uzIkdAoBS
{
    "Groups": [
        {
            "GroupName": "test-group-all-access",
            "UserPoolId": "us-east-1_uzIkdAoBS",
            "Description": "These users have access to all Tag Tamer features",
            "Precedence": 1,
            "LastModifiedDate": "2021-07-02T08:31:53.714000+00:00",
            "CreationDate": "2021-07-02T08:31:53.714000+00:00"
        }
    ]
}
[cloudshell-user@ip-10-0-167-119 ~]$ aws cognito-idp update-group --group-name test-group-all-access --user-pool-id us-east-1_uzIkdAoBS --role-arn arn:aws:iam::123456789012:role/TagTamerAllAdminPermissionsRole
{
    "Group": {
        "GroupName": "test-group-all-access",
        "UserPoolId": "us-east-1_uzIkdAoBS",
        "Description": "These users have access to all Tag Tamer features",
        "RoleArn": "arn:aws:iam::123456789012:role/TagTamerAllAdminPermissionsRole",
        "Precedence": 1,
        "LastModifiedDate": "2021-07-02T08:37:58.623000+00:00",
        "CreationDate": "2021-07-02T08:31:53.714000+00:00"
    }
}
[cloudshell-user@ip-10-0-167-119 ~]$

ロールの設定に成功しました。

サインアップとユーザー登録

Tag Tamerにアクセスします。
CloudFormationのスタック出力からURLが確認出来るのでそのURLを使います。

サインアップ機能が用意されいますので、新規ユーザーの作成を行います。

ユーザー作成時、確認メールが届きます。
ここでCognito+AmazonSESの統合機能が使われています。

検証を行うとCognitoユーザーが作成されます。

しかし、これだけだとサインインはまだ出来ません。
先程作ったCognitoユーザーグループに作成したユーザーを追加する必要があります。

ユーザーグループに追加が出来たら、改めてサインインしてみてください。
サインイン出来るようになったはずです。

まとめ

エラー対処法や事前準備などはドキュメント上に案内はありますが、詳細手順についてはそれぞれのサービスのドキュメントなどから探す必要があります。
今回情報をまとめておきましたので参考になれば幸いです。

構築まで出来ましたので、次回以降使い勝手の確認や機能の紹介をしていきたいと思います。