[アップデート] Amazon Managed Service for Prometheus がリソースポリシーをサポートしました
アップデート概要
Amazon Managed Service for Prometheus (AMP) がリソースベースポリシーに対応しました。
これまで、別アカウントに存在する AMP ワークスペースに Prometheus メトリクスを集約しようとした際、集約先アカウントに IAM ロールを作成して、スイッチロールさせるような設定が必要でした。
AWS Blog の Setting up cross-account ingestion into Amazon Managed Service for Prometheus で詳しく説明されているので詳細は省きますが、集約先アカウントに IAM ロールを作成してその IAM ロールを Prometheus エージェントから指定する形になります。
serviceAccounts:
server:
name: "amp-iamproxy-ingest-service-account"
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::$WORKLOAD_ACCOUNT_ID:role/EKS-AMP-ServiceAccount-Role
server:
remoteWrite:
- url: https://aps-workspaces.eu-west-1.amazonaws.com/workspaces/$WORKSPACE_ID/api/v1/remote_write
queue_config:
max_samples_per_send: 1000
max_shards: 200
capacity: 2500
sigv4:
region: eu-west-1
role_arn: arn:aws:iam::$CENTRAL_ACCOUNT_ID:role/EKS-AMP-Central-Role
statefulSet:
enabled: "true"
上記方法を取ればこれまでも問題なくメトリクスの集約ができたのですが、S3 バケットポリシーのようにリソース側でポリシーを設定することで簡単にクロスアカウントで AMP を操作できるようになったというのが今回のアップデートです。
試してみる
インフラ構築
まず、Terraform でリソースを作成します。
VPC を作成します。
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 6.0.1"
name = "eks-vpc"
cidr = "10.0.0.0/16"
azs = ["ap-northeast-1a", "ap-northeast-1c", "ap-northeast-1d"]
public_subnets = ["10.0.0.0/24", "10.0.1.0/24", "10.0.2.0/24"]
private_subnets = ["10.0.100.0/24", "10.0.101.0/24", "10.0.102.0/24"]
enable_nat_gateway = true
single_nat_gateway = true
public_subnet_tags = {
"kubernetes.io/role/elb" = 1
}
private_subnet_tags = {
"kubernetes.io/role/internal-elb" = 1
}
}
EKS を作成します。
合わせて AMP への書き込み権限を付与した Prometheus 用の IAM ロールも作成しています。
locals {
cluster_name = "test-cluster"
k8s_service_account_namespace = "prometheus"
k8s_prometheus_service_account_name = "amp-iamproxy-ingest-sa"
}
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 21.0.4"
name = local.cluster_name
kubernetes_version = "1.33"
addons = {
coredns = {}
kube-proxy = {}
vpc-cni = {
before_compute = true
}
}
endpoint_public_access = true
enable_irsa = true
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
enable_cluster_creator_admin_permissions = true
eks_managed_node_groups = {
default = {
name = "default"
ami_type = "AL2023_x86_64_STANDARD"
instance_types = ["t3.medium"]
min_size = 1
max_size = 3
desired_size = 1
metadata_options = {
http_tokens = "required"
http_put_response_hop_limit = 2
}
}
}
}
data "aws_iam_policy_document" "prometheus_ingest_policy" {
statement {
effect = "Allow"
actions = [
"aps:RemoteWrite",
"aps:GetSeries",
"aps:GetLabels",
"aps:GetMetricMetadata"
]
resources = ["*"]
}
}
resource "aws_iam_policy" "prometheus_ingest_policy" {
name = "AMPIngestPolicy"
policy = data.aws_iam_policy_document.prometheus_ingest_policy.json
}
module "prometheus_irsa_role" {
source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts"
version = "6.2.1"
name = "amp-ingest-role"
policies = {
policy = aws_iam_policy.prometheus_ingest_policy.arn
}
oidc_providers = {
this = {
provider_arn = module.eks.oidc_provider_arn
namespace_service_accounts = ["${local.k8s_service_account_namespace}:${local.k8s_prometheus_service_account_name}"]
}
}
}
AMP ワークスペースの設定
まずは AMP ワークスペースを作成します。
今回は下記ポリシーを設定します。
アクションは絞りつつ、Principal はアカウント全体を許可しました。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CrossAccountWrite",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<EKSが存在するアカウント>:root"
},
"Action": [
"aps:RemoteWrite",
"aps:GetSeries",
"aps:GetLabels",
"aps:GetMetricMetadata"
],
"Resource": "arn:aws:aps:ap-northeast-1:<集約先アカウントID>:workspace/ws-5d9339d0-b854-4d3f-bea0-cfc38426eab3"
}
]
}
作成した段階では特にリソースベースポリシーが設定されていない状態となります。
% aws amp describe-resource-policy --workspace-id ws-dfdd118f-1bdf-40e2-b70c-6a3e6cef0dd4
An error occurred (ResourceNotFoundException) when calling the DescribeResourcePolicy operation: Workspace resource policy not found.
amp put-resource-policy
コマンドを実行して、リソースベースポリシーを設定します。
% aws amp put-resource-policy --workspace-id ws-dfdd118f-1bdf-40e2-b70c-6a3e6cef0dd4 --policy-document file://policy.json
{
"policyStatus": "CREATING",
"revisionId": "1756628389448"
}
上手く設定が入りました。
% aws amp describe-resource-policy --workspace-id ws-dfdd118f-1bdf-40e2-b70c-6a3e6cef0dd4
{
"policyDocument": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"CrossAccountWrite\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::xxxxxxxxxxxx:root\"},\"Action\":[\"aps:RemoteWrite\",\"aps:GetSeries\",\"aps:GetLabels\",\"aps:GetMetricMetadata\"],\"Resource\":\"arn:aws:aps:ap-northeast-1:xxxxxxxxxxxx:workspace/ws-dfdd118f-1bdf-40e2-b70c-6a3e6cef0dd4\"}]}",
"policyStatus": "CREATING",
"revisionId": "1756628389448"
}
Prometheus インストール
下記手順に沿って EKS に Prometheus エージェントをインストールします。
Helm チャートリポジトリを追加します。
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo add kube-state-metrics https://kubernetes.github.io/kube-state-metrics
helm repo update
Prometheus 用の名前空間を作成します。
kubectl create ns prometheus
Helm の設定ファイルを用意します。
eks.amazonaws.com/role-arn
は環境ごとに IAM ロールの ARN を指定して下さい。
今回は先ほど EKS と一緒に Terraform で作成した IAM ロールの ARN を指定しました。
serviceAccounts:
server:
name: "amp-iamproxy-ingest-sa"
annotations:
eks.amazonaws.com/role-arn: "arn:aws:iam::xxxxxxxxxxxx:role/amp-ingest-role-20250831062837565500000002"
server:
remoteWrite:
- url: https://aps-workspaces.ap-northeast-1.amazonaws.com/workspaces/ws-5d9339d0-b854-4d3f-bea0-cfc38426eab3/api/v1/remote_write
sigv4:
region: ap-northeast-1
queue_config:
max_samples_per_send: 1000
max_shards: 200
capacity: 2500
persistentVolume:
enabled: false
alertmanager:
enabled: false
インストールします。
helm install prometheus prometheus-community/prometheus -n prometheus -f prometheus.yaml
AMP に正しくデータが送信されているかをチェック
今回は簡単に awscurl でデータを確認します。
まず、awscurl をインストールします。
pip install awscurl
AMP のリモート書き込み URL を設定します。
% export AMP_QUERY_ENDPOINT=https://aps-workspaces.ap-northeast-1.amazonaws.com/workspaces/ws-5d9339d0-b854-4d3f-bea0-cfc38426eab3/api/v1/query
AMP ワークスペースが存在するアカウントの権限をセットした状態でリクエストを送ると、上手くクロスアカウントでメトリクスを送信できていました!
% awscurl -X POST --service aps --region ap-northeast-1 "$AMP_QUERY_ENDPOINT?query=up"
{"status":"success","data":{"resultType":"vector","result":[{"metric":{"__name__":"up","instance":"localhost:9090","job":"prometheus"},"value":[1756628674,"1"]},{"metric":{"__name__":"up","instance":"10.0.102.73:443","job":"kubernetes-apiservers"},"value":[1756628674,"1"]},{"metric":{"__name__":"up","instance":"prometheus-prometheus-pushgateway.prometheus.svc:9091","job":"prometheus-pushgateway"},"value":[1756628674,"1"]},{"metric":{"__name__":"up","beta_kubernetes_io_arch":"amd64","beta_kubernetes_io_instance_type":"t3.medium","beta_kubernetes_io_os":"linux","eks_amazonaws_com_capacityType":"ON_DEMAND","eks_amazonaws_com_nodegroup":"default-20250831053151174600000009","eks_amazonaws_com_nodegroup_image":"ami-05aac55ac640fc3ad","eks_amazonaws_com_sourceLaunchTemplateId":"lt-09806e18d8a7d3096","eks_amazonaws_com_sourceLaunchTemplateVersion":"1","failure_domain_beta_kubernetes_io_region":"ap-northeast-1","failure_domain_beta_kubernetes_io_zone":"ap-northeast-1a","instance":"ip-10-0-100-155.ap-northeast-1.compute.internal","job":"kubernetes-nodes-cadvisor","k8s_io_cloud_provider_aws":"9650fdbb8a8b5bfe4fd8cf1ea1de26c9","kubernetes_io_arch":"amd64","kubernetes_io_hostname":"ip-10-0-100-155.ap-northeast-1.compute.internal","kubernetes_io_os":"linux","node_kubernetes_io_instance_type":"t3.medium","topology_ebs_csi_aws_com_zone":"ap-northeast-1a","topology_k8s_aws_zone_id":"apne1-az4","topology_kubernetes_io_region":"ap-northeast-1","topology_kubernetes_io_zone":"ap-northeast-1a"},"value":[1756628674,"1"]},{"metric":{"__name__":"up","app_kubernetes_io_component":"metrics","app_kubernetes_io_instance":"prometheus","app_kubernetes_io_managed_by":"Helm","app_kubernetes_io_name":"prometheus-node-exporter","app_kubernetes_io_part_of":"prometheus-node-exporter","app_kubernetes_io_version":"1.9.1","helm_sh_chart":"prometheus-node-exporter-4.47.3","instance":"10.0.100.155:9100","job":"kubernetes-service-endpoints","namespace":"prometheus","node":"ip-10-0-100-155.ap-northeast-1.compute.internal","service":"prometheus-prometheus-node-exporter"},"value":[1756628674,"1"]}]}}