Deploy IAM Policy
Attach this policy to the OIDC deploy role (prefer over AdministratorAccess). Replace ACCOUNT_ID and REGION everywhere. Assumes the account is already bootstrapped (CDKToolkit + cdk-hnb659fds-assets-*).
See GitHub OIDC for trust policy setup and secrets.
{ "Version": "2012-10-17", "Statement": [ { "Sid": "CdkBootstrapLookup", "Effect": "Allow", "Action": [ "ssm:GetParameter", "cloudformation:DescribeStacks", "cloudformation:ListStacks", "sts:GetCallerIdentity", "ec2:DescribeAvailabilityZones" ], "Resource": "*" }, { "Sid": "CdkAssetsBucket", "Effect": "Allow", "Action": [ "s3:CreateBucket", "s3:GetBucketLocation", "s3:GetBucketPolicy", "s3:PutBucketPolicy", "s3:ListBucket", "s3:GetObject", "s3:PutObject", "s3:DeleteObject", "s3:AbortMultipartUpload", "s3:ListBucketMultipartUploads", "s3:GetEncryptionConfiguration", "s3:PutEncryptionConfiguration", "s3:GetBucketVersioning", "s3:PutBucketVersioning", "s3:GetBucketPublicAccessBlock" ], "Resource": [ "arn:aws:s3:::cdk-hnb659fds-assets-ACCOUNT_ID-REGION", "arn:aws:s3:::cdk-hnb659fds-assets-ACCOUNT_ID-REGION/*" ] }, { "Sid": "CloudFormationAppStack", "Effect": "Allow", "Action": [ "cloudformation:CreateStack", "cloudformation:UpdateStack", "cloudformation:DeleteStack", "cloudformation:DescribeStacks", "cloudformation:DescribeStackEvents", "cloudformation:DescribeStackResource", "cloudformation:DescribeStackResources", "cloudformation:GetTemplate", "cloudformation:GetTemplateSummary", "cloudformation:ListStackResources", "cloudformation:CreateChangeSet", "cloudformation:DescribeChangeSet", "cloudformation:ExecuteChangeSet", "cloudformation:DeleteChangeSet", "cloudformation:ListChangeSets" ], "Resource": [ "arn:aws:cloudformation:REGION:ACCOUNT_ID:stack/PrReadinessCoachStack/*", "arn:aws:cloudformation:REGION:ACCOUNT_ID:stack/CDKToolkit/*" ] }, { "Sid": "IamForLambdaExecutionRole", "Effect": "Allow", "Action": [ "iam:CreateRole", "iam:GetRole", "iam:DeleteRole", "iam:TagRole", "iam:UntagRole", "iam:PassRole", "iam:AttachRolePolicy", "iam:DetachRolePolicy", "iam:PutRolePolicy", "iam:DeleteRolePolicy", "iam:GetRolePolicy", "iam:ListRolePolicies", "iam:ListAttachedRolePolicies", "iam:UpdateAssumeRolePolicy" ], "Resource": "arn:aws:iam::ACCOUNT_ID:role/PrReadinessCoachStack-*" }, { "Sid": "PassRoleToLambdaService", "Effect": "Allow", "Action": "iam:PassRole", "Resource": "arn:aws:iam::ACCOUNT_ID:role/PrReadinessCoachStack-*", "Condition": { "StringEquals": { "iam:PassedToService": "lambda.amazonaws.com" } } }, { "Sid": "PassRoleCdkCfnExec", "Effect": "Allow", "Action": "iam:PassRole", "Resource": "arn:aws:iam::ACCOUNT_ID:role/cdk-hnb659fds-cfn-exec-role-ACCOUNT_ID-REGION", "Condition": { "StringEquals": { "iam:PassedToService": "cloudformation.amazonaws.com" } } }, { "Sid": "AssumeCdkBootstrapRoles", "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": [ "arn:aws:iam::ACCOUNT_ID:role/cdk-hnb659fds-deploy-role-ACCOUNT_ID-REGION", "arn:aws:iam::ACCOUNT_ID:role/cdk-hnb659fds-file-publishing-role-ACCOUNT_ID-REGION", "arn:aws:iam::ACCOUNT_ID:role/cdk-hnb659fds-image-publishing-role-ACCOUNT_ID-REGION", "arn:aws:iam::ACCOUNT_ID:role/cdk-hnb659fds-lookup-role-ACCOUNT_ID-REGION" ] }, { "Sid": "LambdaFunction", "Effect": "Allow", "Action": [ "lambda:CreateFunction", "lambda:DeleteFunction", "lambda:GetFunction", "lambda:GetFunctionConfiguration", "lambda:UpdateFunctionCode", "lambda:UpdateFunctionConfiguration", "lambda:TagResource", "lambda:UntagResource", "lambda:ListTags", "lambda:AddPermission", "lambda:RemovePermission", "lambda:InvokeFunction", "lambda:GetPolicy", "lambda:ListVersionsByFunction", "lambda:PublishVersion" ], "Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:PrReadinessCoachStack-*" }, { "Sid": "ApiGateway", "Effect": "Allow", "Action": [ "apigateway:GET", "apigateway:POST", "apigateway:PUT", "apigateway:PATCH", "apigateway:DELETE", "apigateway:TagResource", "apigateway:UntagResource" ], "Resource": [ "arn:aws:apigateway:REGION::/restapis", "arn:aws:apigateway:REGION::/restapis/*", "arn:aws:apigateway:REGION::/apikeys", "arn:aws:apigateway:REGION::/apikeys/*", "arn:aws:apigateway:REGION::/usageplans", "arn:aws:apigateway:REGION::/usageplans/*", "arn:aws:apigateway:REGION::/tags/*" ] }, { "Sid": "DynamoDbOptionalRunHistory", "Effect": "Allow", "Action": [ "dynamodb:CreateTable", "dynamodb:UpdateTable", "dynamodb:DeleteTable", "dynamodb:DescribeTable", "dynamodb:DescribeTimeToLive", "dynamodb:UpdateTimeToLive", "dynamodb:ListTagsOfResource", "dynamodb:TagResource", "dynamodb:UntagResource", "dynamodb:DescribeContinuousBackups", "dynamodb:UpdateContinuousBackups" ], "Resource": [ "arn:aws:dynamodb:REGION:ACCOUNT_ID:table/PrReadinessCoachStack-*", "arn:aws:dynamodb:REGION:ACCOUNT_ID:table/PrReadinessCoachStack-*/index/*" ] }, { "Sid": "CognitoOwnerUi", "Effect": "Allow", "Action": [ "cognito-idp:CreateUserPool", "cognito-idp:DeleteUserPool", "cognito-idp:DescribeUserPool", "cognito-idp:UpdateUserPool", "cognito-idp:CreateUserPoolClient", "cognito-idp:DeleteUserPoolClient", "cognito-idp:DescribeUserPoolClient", "cognito-idp:UpdateUserPoolClient", "cognito-idp:AdminCreateUser", "cognito-idp:AdminDeleteUser", "cognito-idp:AdminGetUser", "cognito-idp:ListUsers", "cognito-idp:TagResource", "cognito-idp:UntagResource", "cognito-idp:ListTagsForResource" ], "Resource": "arn:aws:cognito-idp:REGION:ACCOUNT_ID:userpool/*" }, { "Sid": "AmplifyHostingZipDeploy", "Effect": "Allow", "Action": [ "amplify:CreateApp", "amplify:DeleteApp", "amplify:UpdateApp", "amplify:GetApp", "amplify:ListApps", "amplify:CreateBranch", "amplify:DeleteBranch", "amplify:UpdateBranch", "amplify:GetBranch", "amplify:ListBranches", "amplify:CreateDeployment", "amplify:StartDeployment", "amplify:GetJob", "amplify:ListJobs", "amplify:StopJob", "amplify:TagResource", "amplify:UntagResource", "amplify:ListTagsForResource" ], "Resource": "arn:aws:amplify:REGION:ACCOUNT_ID:apps/*" }, { "Sid": "CloudWatchLogsForLambda", "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:DeleteLogGroup", "logs:PutRetentionPolicy", "logs:DescribeLogGroups", "logs:TagResource", "logs:UntagResource", "logs:ListTagsForResource" ], "Resource": "arn:aws:logs:REGION:ACCOUNT_ID:log-group:/aws/lambda/PrReadinessCoachStack-*" } ]}- This role deploys infra; it does not need
bedrock:*. Bedrock invoke stays on the Lambda execution role. PassRoleCdkCfnExecis required so CloudFormation can use the bootstrap cfn-exec role.AssumeCdkBootstrapRolesavoids “could not be used to assume … Proceeding anyway” warnings.- First-time
cdk bootstrapis a separate, wider one-time admin action (not this CI role). - If CloudFormation reports a missing action, add only that action — resource names use the
PrReadinessCoachStack-*prefix.