diff --git a/Makefile b/Makefile index d9f73c0c..c51fee26 100644 --- a/Makefile +++ b/Makefile @@ -172,6 +172,15 @@ endif "GitHubOidcProviderArn=$(GITHUB_OIDC_PROVIDER_ARN)" \ "VercelOidcProviderArn=$(VERCEL_OIDC_PROVIDER_ARN)" +# Usage: make sam-status ENV=staging +.PHONY: sam-status +sam-status: +ifndef ENV + $(error ENV is required, e.g. make sam-status ENV=staging) +endif + aws cloudformation describe-stacks --stack-name data-hub-$(ENV) \ + --region us-west-1 --query 'Stacks[0].StackStatus' --output text + # Usage: make sam-teardown ENV=staging .PHONY: sam-teardown sam-teardown: diff --git a/developer-docs/ci-and-deployment.md b/developer-docs/ci-and-deployment.md index d0ff2bd3..0cb330fd 100644 --- a/developer-docs/ci-and-deployment.md +++ b/developer-docs/ci-and-deployment.md @@ -194,7 +194,9 @@ On pushes to `staging` or `production`, the **Deploy Lambda** workflow: Secrets (`DATA_HUB_API_KEY`, etc.) are stored in GitHub environment secrets scoped to each environment. -> **Note:** The CI deploy role has intentionally narrow permissions — enough to push a new container image, update the existing CloudFormation stack, and modify the data buckets' S3 event notifications (so new instrument triggers roll out via CI), but _not_ enough to create the stack from scratch or to add/remove S3 buckets or Lambda functions. Initial stack creation and structural infrastructure changes must be performed by an admin with broader AWS permissions. Once the stack exists, routine image-update deploys and new-trigger rollouts through CI work without issue. +> **Note:** The CI deploy role has intentionally narrow permissions — enough to push a new container image, update the existing CloudFormation stack, modify the data buckets' S3 event notifications (so new instrument triggers roll out via CI), and update the data buckets' CORS configuration, but _not_ enough to create the stack from scratch or to add/remove S3 buckets or Lambda functions. Initial stack creation and structural infrastructure changes must be performed by an admin with broader AWS permissions. Once the stack exists, routine image-update deploys and new-trigger rollouts through CI work without issue. +> +> The deploy that first grants `s3:PutBucketCORS` must be run by an admin via `make sam-deploy` (CI can't grant itself a permission and use it in the same changeset). CORS edits after that roll out through CI. > > The bucket policies that deny object writes from unapproved principals (`RawDataBucketPolicy`, `ProcessedDataBucketPolicy`, `ArchivesBucketPolicy`) are managed the same way: adding or changing them requires `s3:PutBucketPolicy`, which the CI role does **not** hold (by design — a routine CI role that could rewrite these policies could also disable the write protection). Apply changes to the deny lists via an admin `make sam-deploy`, not CI. diff --git a/infra/template.yaml b/infra/template.yaml index fc644ead..19bd08bb 100644 --- a/infra/template.yaml +++ b/infra/template.yaml @@ -494,6 +494,16 @@ Resources: - !Sub "arn:aws:s3:::arcadia-data-hub-raw-${Environment}" - !Sub "arn:aws:s3:::arcadia-data-hub-processed-${Environment}" - !Sub "arn:aws:s3:::arcadia-data-hub-archives-${Environment}" + # Same rationale as notifications above — lets CI roll out CORS + # changes on the data buckets without an admin deploy. + - Effect: Allow + Action: + - s3:GetBucketCORS + - s3:PutBucketCORS + Resource: + - !Sub "arn:aws:s3:::arcadia-data-hub-raw-${Environment}" + - !Sub "arn:aws:s3:::arcadia-data-hub-processed-${Environment}" + - !Sub "arn:aws:s3:::arcadia-data-hub-archives-${Environment}" - Effect: Allow Action: - iam:GetRole