まくろぐ

読書メモ『HEALTH HACKS!』川田浩志

更新:
作成:

健康は何よりも重要!

本書には、健康に効果があって(エビデンスがあって)、かつ続けられる方法がいろいろと示されています。 著者は、「年収が上がると健康度が上がる」のではなくて、「健康度が上がると年収が上がる」と考えています。 だから、健康への自己投資は若いときから続けるのがよいと。 ごもっとも。

以下、参考になったことをメモメモ。

メモ

考え方

  • 健康度は主観的なものだが、自分の健康度が高いと思っているほど寿命が長いという結果がある。
  • 健康度を挙げるには、正しい知識を付けて、自信をもって健康に良いことをする 必要がある。
  • ジムや健康食品、健康法などの問題は、続けられないこと(▽RIZAPとかはこのあたりに目を付けてますね^^)。だから、効果があって続けられそうなこと から少しずつ自分の生活に取り込んでいくのがよい。
  • 周りの人たちの健康も考えてあげることで、Win-Win で健康になっていく。
  • 明るい、楽天的、活動的 → 長寿

運動

  • 『家庭用トレッドミル』 はおすすめ。テレビを見ながらでもできるので時間の節約になるし、雨の日でも、真夏で外に出られなくても、毎日続けられる。外出用に着替える必要もない。折り畳み式のものであれば、場所もとらない。音楽を聴きながら、目をつぶって歩くととても気持ちがよい。
  • 運動にはがん予防の効果がある(大腸がん、乳がん)。
  • 筋トレは何歳で始めても必ず効果が出る。

食事

  • 白パン、マーガリン、ハム、ソーセージみたいない朝食を続けるくらいなら、朝食は抜いたほうがまし。
  • 現在では、カロリーの接種を控えめにすることが一番 健康保持と長寿に有力。お腹いっぱい食べるのではなく、腹七分ないし八分目を意識すべし。
  • 寿命を延ばすには、インスリンの濃度を低く保つ こと。GI 値が高い商品(炭水化物)は、血糖値を上げるのでインスリンが出て細胞の寿命がどんどん縮む。野菜から食べ始める のがやはり効果的。
  • リスベラトロール を摂ると、インスリンの分泌を低く保つことができる。
    • 皮ごと食べられるブドウ赤ワイングレープジュース
    • カリフォルニア・レーズン
    • アーモンドの皮
  • 年を取ると、のどの渇きを感じにくくなるので、水は決めた量を飲むようにする。これは血液の流れをよくするため。男性2ℓ、女性1.5ℓ くらい(食事に含まれる水分を含む)。
  • 水の取りすぎで「むくむ」ことはなく、むくみの原因は塩分の取りすぎにある(血液の浸透圧が高くなるから)。
  • 飲酒は少量であっても様々ながんの発症リスク を高めてしまう。乳がん、食道がん、大腸がん、肝臓がんなどのリスクが上がる。顔が赤くなる人は特に注意。飲酒がメリットになる日本人は少ない。
  • ミネラルウォーターの含有ヒ素濃度は、水道水の 5 倍まで認可されている。▽日本の水道水は安全度が高いということ。
  • 善玉コレステロールを増やすには、よい油を摂る。グレープシードオイルエゴマ油 をドレッシングにするとよい。

サプリメント

  • サプリメントでおすすめなのは、ビタミン A の代わりに ベータカロテン を使っている マルチビタミン・ミネラル サプリメント。ベータカロテンは体内で必要なだけビタミン A に変換してくれる。
  • マルチビタミン・ミネラルのサプリメントは毎日飲み続ける必要はなく、食生活が不規則だなと感じたときに数日間飲むといい。ただし、肉やワインをよく接種する人は鉄の取りすぎになるので、鉄抜きのものを選ぶとよい。

見た目

  • 歯が白いだけで印象はだいぶよくなる。リンゴ酸入りの歯磨き粉 などを使うとよい。見た目を先に改善 することで、健康を維持しようというモチベーションが上がる。
  • 人と会う前には目薬をしておくとよい。
  • 顔を若く保つには UV ケアが何より大切。現在では、シワの原因のほとんどは日光からの紫外線 であることが分かっている。昔は日光に当たることがよいなどと言われていたことがあったが、日光に直接当たるのは百害あって一利なし。木陰に 10 分いるだけでビタミン D の活性化にも十分。
  • 普段の日焼け止めの SPF は 10 程度 で十分。SPF が高くなると皮膚に有害 だが、日本ではほとんど規制されておらず、高いものが出回っている。

関連記事

AWS CDK 入門 (3) CDK サンプルコード

更新:
作成:

AWS CDK を使った TypeScript サンプルコードいろいろです。

リソースにタグを付ける

import * as cdk from '@aws-cdk/core'
import { MyappStack } from '../lib/myapp-stack'

const app = new cdk.App()
new MyappStack(app, 'MyappStack', {
  tags: {
    Owner: 'TeamA',
    Purpose: 'Project1',
  },
})

AWS リソース用のコンストラクトの props パラメーターで、tags プロパティを指定することで、そのリソースにタグを設定できます。

タグの設定方法は、どの AWS リソース用のコンストラクトでも同様です。 上記のように Stack コンストラクトに対してタグを設定すると、その中に配置した AWS リソースにもそのタグが設定されます。

S3 バケットや DynamoDB テーブルをスタック削除時に自動削除する

バケットが空のときだけ自動削除する

import * as cdk from '@aws-cdk/core'
import * as s3 from '@aws-cdk/aws-s3'

new s3.Bucket(this, 'MyBucket', {
  removalPolicy: cdk.RemovalPolicy.DESTROY,
})

CDK で作成した S3 バケットや DynamoDB テーブルは、デフォルトでは、(内容が空であっても)スタック削除時にそのまま残るようになっています。 つまり、スタックから独立したリソースとして S3 バケットだけが残ります。 これは、CloudFormation の DeletionPolicy のデフォルトの挙動とは逆なので注意してください。 スタックの削除 (cdk destroy) と同時に S3 バケットや DynamoDB テーブルを削除したいときは、上記のように removalPolicy を設定します。

バケットが空じゃなくても自動削除する

import * as cdk from '@aws-cdk/core'
import * as s3 from '@aws-cdk/aws-s3'

new s3.Bucket(this, 'MyBucket', {
  removalPolicy: cdk.RemovalPolicy.DESTROY,
  autoDeleteObjects: true,
})

removalPolicyRemovalPolicy.DESTROY に設定しても、S3 バケットにオブジェクト含まれているときは、スタック削除時に連動して自動削除してくれません。 スタック削除時に、バケット内のオブジェクトを自動削除してバケットの削除までやってしまいたいときは、removalPolicy に加えて、autoDeleteObjects プロパティを設定します。 この設定を行うと、たとえ S3 バケットのバージョニングが有効 (versioned: true) になっていても、問答無用で削除されるので注意してください。 autoDeleteObjects の機能を実現するために、内部的に Lambda 関数が自動生成されるので、CDK のブートストラッピング (cdk bootstrap) をあらかじめ実行しておく必要があります。

S3 バケットの物理名 (Physical ID) を指定する

import * as s3 from '@aws-cdk/aws-s3'

const bucket = new s3.Bucket(this, 'MyBucket', {
  bucketName: 'bucket-123456789012-user-data',
})

L2 コンストラクトの s3.Bucket は、物理バケット名(物理 ID)を自動生成してくれますが、何らかの理由で固定の物理名を指定したいときは、上記のように bucketName プロパティで明示的に指定することができます。 逆に、L1 コンストラクトの CfnBucket を使ってバケットを作成するときは、必ず bucketName の指定が必要です。

S3 バケットを作成して Lambda 関数から参照できるようにする

import * as lambda from '@aws-cdk/aws-lambda'
import * as s3 from '@aws-cdk/aws-s3'

const bucket = new s3.Bucket(this, 'my-bucket')
new lambda.Function(this, 'my-lambda', {
  // ...
  environment: {
    BUCKET_NAME: bucket.bucketName
  }
})

// バケットポリシーで Lambda 関数から読み書きできるようにする
bucket.grantReadWrite(lambda)

Function コンストラクトをインスタンス化するときに、上記のように environment props を指定することで、Lambda 関数の実装の中で、環境変数 BUCKET_NAME としてバケット名を参照できるようになります。 実際に Lambda 関数から S3 バケットにアクセスできるようにするには、Bucket コンストラクト側の grantRead / grantWrite / grantReadWrite 関数を呼び出して、Lambda 関数にアクセス権限を付けておく必要があります(バケットポリシーが生成されます)。 これを忘れると、Lambda 関数の実行時に Access Denied エラーになります。

既存の S3 バケットを参照する

import * as s3 from '@aws-cdk/aws-s3'

// (A) Construct a resource (bucket) just by its name (must be same account)
const myBucket = s3.Bucket.fromBucketName(
  this, 'MyBucket', 'bucket-123456789012-user-data'
)

// (B) Construct a resource (bucket) by its full ARN (can be cross account)
const myBucket = s3.Bucket.fromBucketArn(
  this, 'MyBucket', 'arn:aws:s3:::bucket-123456789012-user-data'
)

// あとは Lambda 関数などに読み書き権限を与える
myBucket.grantReadWrite(lambdaFunc)

すでに別の CloudFormation スタック内に作成済みの S3 バケットなどを参照する必要がある場合は、上記のようにバケット名や ARN をもとに s3.Bucket インスタンスを生成できます。

既存の DynamoDB テーブルを参照する

import * as dynamodb from '@aws-cdk/aws-dynamodb'

// (A) 既存の DynamoDB テーブルをテーブル名で参照する(同一アカウント内)
const configTable = dynamodb.Table.fromTableName(
  this, 'ConfigTable', 'myapp-dev-config'
)

// (B) 既存の DynamoDB テーブルを ARN で参照する(クロスアカウント)
const configTable = dynamodb.Table.fromTableArn(
  this,
  'ConfigTable',
  'arn:aws:dynamodb:<Region>:<Account>:table/myapp-dev-config'
)

// あとは Lambda 関数などに読み書き権限を与える
configTable.grantReadWriteData(lambdaFunc)

S3 バケットにオブジェクトを追加したときに SNS トピック通知を発行する

import * as s3 from '@aws-cdk/aws-s3'
import * as s3notify from '@aws-cdk/aws-s3-notifications'
import * as sns from '@aws-cdk/aws-sns'

const bucket = new s3.Bucket(this, 'bucket')
const topic = new sns.Topic(this, 'topic')
bucket.addObjectCreatedNotification(new s3notify.SnsDestination(topic))

上記のように S3 バケットと SNS トピックを生成して、addObjectCreatedNotification で関連付けると、S3 バケットへのオブジェクト追加(および更新)時に SNS トピックからの通知を発行できるようになります。 CloudFormation を直書きすると、S3 との連携用にポリシー設定 (AWS::SNS::TopicPolicy) まで記述しないといけなくて非常に面倒ですが、CDK であれば、上記のように記述だけで済みます(トピックポリシーは内部で自動生成してくれます)。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "0",
      "Effect": "Allow",
      "Principal": {
        "Service": "s3.amazonaws.com"
      },
      "Action": "sns:Publish",
      "Resource": "arn:aws:sns:<リージョン>:<アカウント>:<トピック名>",
      "Condition": {
        "ArnLike": {
          "aws:SourceArn": "arn:aws:s3:::<バケット名>"
        }
      }
    }
  ]
}

応用として、NotifyingBucket をインスタンス化するときの props 引数で、prefix: '/images' と指定すれば、監視対象となるオブジェクトをフィルタすることができます。 次の独自コンストラクト (NotifyingBucket) の実装例では、オプションで prefix を指定できるようにしています。

import * as cdk from '@aws-cdk/core'
import * as s3 from '@aws-cdk/aws-s3'
import * as s3notify from '@aws-cdk/aws-s3-notifications'
import * as sns from '@aws-cdk/aws-sns'

export interface NotifyingBucketProps {
  prefix?: string
}

export class NotifyingBucket extends cdk.Construct {
  constructor(scope: cdk.Construct, id: string, props: NotifyingBucketProps = {}) {
    super(scope, id)
    const bucket = new s3.Bucket(this, 'bucket')
    const topic = new sns.Topic(this, 'topic')
    bucket.addObjectCreatedNotification(new s3notify.SnsDestination(topic), {
      prefix: props.prefix
    })
  }
}

S3 バケットにオブジェクトが追加されたときに Lambda 関数を呼び出す

import * as lambda from '@aws-cdk/aws-lambda'
import * as s3 from '@aws-cdk/aws-s3'
import * as s3notify from '@aws-cdk/aws-s3-notifications'

const handler = new lambda.Function(this, 'Handler', {/* ... */})
const bucket = new s3.Bucket(this, 'Bucket')
bucket.addObjectCreatedNotification(new s3notify.LambdaDestination(handler))

S3 バケットにオブジェクトが追加されたときに Lambda 関数を呼び出すには、Bucket#addObjectCreatedNotification()LambdaDestination オブジェクトを渡します。 呼び出す関数は SNS トピック通知を発行する場合と同様ですが、引数で渡すオブジェクトが異なります。

SNS トピックの通知で Lambda 関数を呼び出す

import * as sns from '@aws-cdk/aws-sns'
import * as snsSub from '@aws-cdk/aws-sns-subscriptions'

// 既存の SNS Topic からの通知で Lambda 関数を起動する
const myTopic = sns.Topic.fromTopicArn(
  this,
  'MyTopic',
  'arn:aws:sns:<Region>:<Account>:myapp-dev-xxx-topic'
)
myTopic.addSubscription(new snsSub.LambdaSubscription(handler))

S3 バケットを Read 可能な IAM グループを作成する

import * as s3 from '@aws-cdk/aws-s3'
import * as iam from '@aws-cdk/aws-iam'

const rawData = new s3.Bucket(this, 'raw-data')
const dataScience = new iam.Group(this, 'data-science')
rawData.grantRead(dataScience)

S3 バケットへの CORS アクセスを許可する

import * as s3 from '@aws-cdk/aws-s3'

const myBucket = new s3.Bucket(this, 'MyBucket', {
  cors: [
    {
      allowedHeaders: ['*'],
      allowedMethods: [s3.HttpMethods.GET, s3.HttpMethods.POST],
      allowedOrigins: [
        'http://localhost:*',
        'https://example.com/',
        'https://*.example.com/',
      ],
    },
  ],
})

Web サイトのクライアントサイド JavaScript から、S3 バケット内のファイルを取得する場合は、S3 バケットの CORS 設定でクロスオリジンのアクセスを許可しておく必要があります。 Web ブラウザのコンソール出力で、次のようなエラーが出たら、この CORS 設定ができていない証拠です。

Access to fetch at ‘…’ from origin ‘http://localhost:3000’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

allowedOrigins の指定方法ですが、http://localhost:3000 からアクセスするのであれば、http://localhost:3000http://localhost:* と記述する必要があり、スキーマを省略したり (localhost:3000)、ポート番号を省略したり (http://localhost) するのは NG です。 ワイルドカードのアスタリスクは、アドレスの一か所でのみ使用可能です。

SQS キューと Lambda 関数を結びつける

import * as lambda from '@aws-cdk/aws-lambda'
import * as sqs from '@aws-cdk/aws-sqs'

const jobsQueue = new sqs.Queue(this, 'jobs')
const createJobLambda = new lambda.Function(this, 'create-job', {
  runtime: lambda.Runtime.NODEJS_14_X,
  handler: 'index.handler',
  code: lambda.Code.fromAsset('./create-job-lambda-code'),
  environment: {
    QUEUE_URL: jobsQueue.queueUrl
  }
})

このように、lambda.Function の props で environment を設定しておくと、Lambda 関数の実装の中から、QUEUE_URL 環境変数の形で SQS キューの URL を参照できるようになります。

ECS クラスターを作って EC2 サービスから参照する

import * as ecs from '@aws-cdk/aws-ecs'

const cluster = new ecs.Cluster(this, 'Cluster', {/* ... */})
const service = new ecs.Ec2Service(this, 'Service', { cluster: cluster })

別のスタック内の S3 バケットを参照する

const prod = { account: '123456789012', region: 'ap-northeast-1' }
const stack1 = new Stack1(app, 'Stack1', { env: prod })
const stack2 = new Stack2(app, 'Stack2', { env: prod, bucket: stack1.bucket })

Stack2 のコンストラクタの bucket props として、Stack1 オブジェクトの公開プロパティ bukcket を渡しています。 同じアカウント&リージョンのスタックであることが条件です。

EventBridge で定期的に Lambda 関数を実行する

import * as cdk from '@aws-cdk/core'
import * as events from '@aws-cdk/aws-events'
import * as eventsTargets from '@aws-cdk/aws-events-targets'
import * as lambdaNodejs from '@aws-cdk/aws-lambda-nodejs'

// Lambda 関数を作成する
const myLambda = new lambdaNodejs.NodejsFunction(this, 'MyLambda', {
  entry: 'lambda/index.ts',
})

// EventBridge ルールで 10 分おきに Lambda 関数呼び出し
new events.Rule(this, 'MyRule', {
  schedule: events.Schedule.rate(cdk.Duration.minutes(10)), // 10分おき
  // schedule: events.Schedule.cron({ ... }), // cron 形式で指定する場合
  targets: [
    new eventsTargets.LambdaFunction(myLambda, { retryAttempts: 3 }),
  ],
})

上記の例では、10 分ごとに Lambda 関数を呼び出すように EventBridge のスケジュール設定(ルール設定)を行っています。

CDK コードの中で SSM パラメーターストアのパラメーター値を取得する

import * as ssm from '@aws-cdk/aws-ssm'

const bucketName = ssm.StringParameter.valueForStringParameter(this,
  '/myapp/dev/ImageBucketName'
)

上記の例では、SSM パラメーターストアの /myapp/dev/ImageBucketName というパラメーターに格納された値を取得しています。 他のアプリが生成した S3 バケットの名前をこのパラメーターストアに格納してくれていれば、その値を介して連携させることができます。 パラメーターの種類が SecureString の場合は、次のように別の関数を使います(バージョン情報の指定が必要です)。

const gitHubToken = ssm.StringParameter.valueForSecureStringParameter(this,
  '/myapp/dev/GitHubToken', 1
)

Lambda 関数から SSM パラメーターストアにアクセスできるようにする

import * as lambdaNodejs from '@aws-cdk/aws-lambda-nodejs'
import * as ssm from '@aws-cdk/aws-ssm'

// Lambda 関数を作成する
const myLambda = new lambdaNodejs.NodejsFunction(this, 'MyLambda', {
  runtime: lambda.Runtime.NODEJS_14_X,
  entry: 'lambda/index.ts',
  environment: {
    GITHUB_TOKEN_SSM_PARAM: '/myapp/dev/GitHubToken',
  },
})

// 既存の SSM パラメーターの読み取り権限を Lambda 関数に与える
const mySsmParam = ssm.StringParameter.fromStringParameterName(
  this, 'MySsmParam', '/myapp/dev/GitHubToken'
)
mySsmParam.grantRead(myLambda)

// エラーが出るときは、下記でやってみる
// const mySsmParam = ssm.StringParameter.fromSecureStringParameterAttributes(
//   this, 'MySsmParam', {
//     parameterName: '/myapp/dev/GitHubToken',
//     version: 1,
//   }
// )

ここでは、パラメーターストア上のパラメーター (/myapp/dev/GitHubToken) として GitHub のアクセストークンを格納して、Lambda 関数内からその値を取得することを想定しています。 既存のパラメーターのコンストラクト参照を取得するには、上記のように ssm.StringParameter.fromStringParameterName 関数を使用します。 あとは、grantRead で Lambda 関数からの読み込みを許可してやると、次のようなアクションがまとめて許可されます。

  • ssm:DescribeParameters
  • ssm:GetParameter
  • ssm:GetParameterHistory
  • ssm:GetParameters

StringParametergrantRead 関数を使わずに、次のように Lambda 関数に Policy ステートメントを直接追加してしまう方法もありますが、パラメーターの ARN 指定などが面倒ですね。 grantRead を使った方がシンプルでよいと思います。

myLambda.addToRolePolicy(new iam.PolicyStatement({
  effect: iam.Effect.ALLOW,
  actions: ['ssm:GetParameter*'],
  resources: ['arn:aws:ssm:<Region>:<Account>:parameter/myapp/dev/GitHubToken'],
}))

ちなみに、Lambda 関数 (AWS SDK) の方では、次のような感じでパラメーターの値を取得できます。

Lambda 関数内で SSM パラメーター値を取得
import * as AWS from 'aws-sdk'
const ssm = new AWS.SSM({ region: 'ap-northeast-1' })

export async function getGitHubToken(): Promise<string | undefined> {
  const result = await ssm.getParameter({
    Name: process.env.GITHUB_TOKEN_SSM_PARAM as string,
    WithDecryption: true,
  }).promise()
  return result.Parameter?.Value
}

ApiGateway + Lambda 関数で REST API を作成する

lib/myapi-stack.ts
import * as cdk from '@aws-cdk/core'
import * as apigateway from '@aws-cdk/aws-apigateway'
import * as lambdaNodejs from '@aws-cdk/aws-lambda-nodejs'

export class MyapiStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props)

    // Lambda 関数(GET books/ のハンドル用)
    const getBooksHandler = new lambdaNodejs.NodejsFunction(
      this, 'getBooksHandler', {
        entry: 'lambda/index.ts',
        handler: 'getBooksHandler',
      })

    // Lambda 関数(GET books/{id} のハンドル用)
    const getSingleBookHandler = new lambdaNodejs.NodejsFunction(
      this, 'getSingleBookHandler', {
        entry: 'lambda/index.ts',
        handler: 'getSingleBookHandler',
      })

    // ApiGateway (RestApi) の作成
    const api = new apigateway.RestApi(this, 'api')

    // Lambda 関数を結びつける (GET books/)
    const books = api.root.addResource('books')
    books.addMethod('GET',
      new apigateway.LambdaIntegration(getBooksHandler))

    // Lambda 関数を結びつける (GET books/{id})
    const singleBook = books.addResource('{id}')
    singleBook.addMethod('GET',
      new apigateway.LambdaIntegration(getSingleBookHandler))
  }
}

下記はバックエンドとして動く Lambda 関数の適当な実装です。 実際には、DynamoDB などから情報を取得して JSON データとして返すように実装します。

lambda/index.ts
import { Handler } from 'aws-lambda'

const BOOKS = [
  { id: '1', title: 'Title 1' },
  { id: '2', title: 'Title 2' },
  { id: '3', title: 'Title 3' },
]

/** 全ての本情報を取得する。 */
export const getBooksHandler: Handler = async () => {
  return {
    statusCode: 200,
    body: JSON.stringify(BOOKS),
  }
}

/** 指定された ID の本情報を取得する。 */
export const getSingleBookHandler: Handler = async (event: any = {}) => {
  const id = event.pathParameters.id
  return {
    statusCode: 200,
    body: JSON.stringify(BOOKS.find((b) => b.id === id)),
  }
}

関連記事

AWS SSM のポリシーステートメント例

更新:
作成:

パラメーターの説明情報の取得

すべてのパラメーターの説明情報を取得できるようにする
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:DescribeParameters"
            ],
            "Resource": "*"
        }
    ]
}

ssm:DescribeParameters は、SSM パラメーターストアに格納されたパラメーターの説明情報を取得する権限です。 この権限だけでは、パラメーターの「値」自体は取得できないことに注意してください。

パラメーターの値の取得

prod- で始まるパラメーターの値を取得できるようにする
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:GetParameter*"
            ],
            "Resource": "arn:aws:ssm:<Region>:<Account>:parameter/prod-*"
        }
    ]
}

パラメーターの Get 系アクションには、GetParameter/GetParameters/GetParameterHistory/GetParametersByPath など いろいろある ため、上記のように ssm:GetParameter* とワイルドカード指定しておくと確実に取得できるようになります。 GetParameter だけだと、パラメーターの一覧取得などが許可されません。

パラメーターの追加・削除

prod- で始まるパラメーターの追加と削除を許可する
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:PutParameter",
                "ssm:DeleteParameter",
                "ssm:DeleteParameters"
            ],
            "Resource": "arn:aws:ssm:<Region>:<Account>:parameter/prod-*"
        }
    ]
}

暗号化されたパラメーター (SecureString) の取得

暗号化された prod- で始まるパラメーターを読み込む
{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Action": [
            "ssm:GetParameter*"
         ],
         "Resource": [
            "arn:aws:ssm:<Region>:<Account>:parameter/prod-*"
         ]
      },
      {
         "Effect": "Allow",
         "Action": [
            "kms:Decrypt"
         ],
         "Resource": [
            "arn:aws:kms:<Region>:<Account>:key/<KmsKey>"
         ]
      }
   ]
}

SSM パラメーターストアに SecureString タイプとして格納されたパラメーターは、KMS キーによって暗号化されています。 このパラメーターの値を取得するには、ssm:GetParameter* によるパラメーター読み取り権限と、kms:Decrypt による複合化の権限が必要です。

暗号化されたパラメーター (SecureString) の作成

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:PutParameter"
            ],
            "Resource": [
                "arn:aws:ssm:<Region>:<Account>:parameter/prod-*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
               "kms:Encrypt",
               "kms:GenerateDataKey" // 暗号化された詳細パラメータの作成に必要
            ],
            "Resource": [
                "arn:aws:kms:<Region>:<Account>:key/<KmsKey>"
            ]
        }
    ]
}

Principal で特定のユーザーに権限を絞る

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Allow SSM parameter access for maku",
            "Effect": "Allow",
            "Principal": {"AWS": "arn:aws:iam::111122223333:user/maku"},
            "Action": [
                "ssm:PutParameter",
                "ssm:DeleteParameter",
                "ssm:DeleteParameters"
            ],
            "Resource": [
                "arn:aws:ssm:<Region>:<Account>:parameter/prod-*"
            ]
        }
    ]
}

関連記事

メニュー

まくろぐ
サイトマップまくへのメッセージ