aws-amplify / aws-amplify/amplify-cli

Override S3 Auth Public Policy on `init`

Open
#13,619 4 comments 0 reactions 0 assignees View on GitHub
feature-request platform-init
Dominant language
TypeScript
Stars
2.9k
Forks
825
Avg merge
11d 23h
Merged PRs (30d)
2

Description

### How did you install the Amplify CLI?

npm

### If applicable, what version of Node.js are you using?

20.11.1

### Amplify CLI Version

12.10.1

### What operating system are you using?

Ubuntu & Windows

### Did you make any manual changes to the cloud resources managed by Amplify? Please describe the changes made.

No manual changes made.

### Describe the bug

When using `amplify init` to create a new project, the process fails because of `ControlTower::Guard::Hook` failure. This failure is caused by Control Tower enforcing pre-provisioning rules on the creation of S3 buckets. The result is that Cloudformation is unable to create the S3 deployment bucket needed, which results in the entire Stack breaking.

As a result, the `amplify init` process fails before it creates a local backend folder. Since it never creates a local back-end folder, I am unable to manually make changes to the backend configuration as recommended in #8894.

Below is the Hook Status Message that causes the failure:
```
Hook failed with message: ValidationError [CT.S3.PR.1]: Require an Amazon S3 bucket to have block public access settings configured [FIX]: The parameters 'BlockPublicAcls', 'BlockPublicPolicy', 'IgnorePublicAcls', 'RestrictPublicBuckets' must be set to true under the bucket-level 'PublicAccessBlockConfiguration'. , ValidationError [CT.S3.PR.6]: Require an Amazon S3 bucket to have lifecycle policies configured [FIX]: Configure at least one active lifecycle rule in 'LifecycleConfiguration.Rules' by setting 'Status' on a rule to 'Enabled'.
```

### Expected behavior

Generate the configuration for `amplify init` locally to allow for customization of the settings. Alternatively, provide a mechanism by which I can override the default S3 configuration to deal with the error. For reasons outside of my control, I am unable to change the ControlTower settings.

### Reproduction steps

1. Run `amplify init`

### Project Identifier

Cannot run `amplify diagnose` because there was no backend created.

### Log output

```
# Put your logs below this line

2024-02-26T16:48:52.632Z|info : amplify init core {"permissions-boundary":"arn:aws:iam::###########","yes":false}
2024-02-26T16:48:52.647Z|info : @aws-amplify/amplify-cli-core.banner-message/index.ts.fetch banner messages from https://aws-amplify.github.io/amplify-cli/banner-message.json({}
2024-02-26T16:48:57.077Z|info : amplify-provider-awscloudformation.system-config-manager.getProfileConfig(["####"])
2024-02-26T16:48:57.077Z|info : amplify-provider-awscloudformation.system-config-manager.getProfiledAwsConfig.profileConfig([{"sso_start_url":"####","sso_region":"us-east-1","sso_registration_scopes":"sso:account:access","sso_account_id":"####","sso_role_name":"####","region":"us-east-1","output":"json","credential_process":"SOME BLOODY CUSTOM 3RD PARTY COMMAND BECAUSE YOUR OWN SDK IS INCOMPATABLE WITH YOUR OWN INTERNAL CONVENTIONS(https://github.com/aws-amplify/amplify-cli/issues/4488)"}])
2024-02-26T16:49:03.828Z|info : amplify-provider-awscloudformation.amplify-service-permission-check.checkAmplifyServiceIAMPermission.amplifyClient.listApps([])
2024-02-26T16:49:04.207Z|info : amplify-provider-awscloudformation.amplify-service-manager.init.amplifyClient.createApp([{"name":"####","environmentVariables":{"_LIVE_PACKAGE_UPDATES":"[{\"pkg\":\"@aws-amplify/cli\",\"type\":\"npm\",\"version\":\"latest\"}]"}}])
2024-02-26T16:49:04.716Z|info : amplify-provider-awscloudformation.amplify-service-manager.init.amplifyClient.getBackendEnvironment([{"appId":"####","environmentName":"[***]ev"}])
2024-02-26T16:49:05.030Z|error : amplify-provider-awscloudformation.amplify-service-manager.init.amplifyClient.getBackendEnvironment([{"appId":"####","environmentName":"[***]ev"}])
NotFoundException: BackendEnvironment dev does not exist.
2024-02-26T16:49:05.031Z|info : amplify-provider-awscloudformation.amplify-service-manager.init.amplifyClient.getBackendEnvironment([{"appId":"####","environmentName":"[***]ev","stackName":"####","deploymentArtifacts":"amplify-####-dev-####-deployment"}])
2024-02-26T16:49:05.189Z|info : amplify-provider-awscloudformation.aws-cfn.cfnModel.createStack([{"StackName":"####","Capabilities":["CAPABILITY_NAMED_IAM","CAPABILITY_AUTO_EXPAND"],"TemplateBody":"{\n \"AWSTemplateFormatVersion\": \"2010-09-09\",\n \"Description\": \"{\\\"createdOn\\\":\\\"Linux\\\",\\\"createdBy\\\":\\\"Amplify\\\",\\\"createdWith\\\":\\\"12.10.1\\\",\\\"stackType\\\":\\\"root\\\",\\\"metadata\\\":{}}\",\n \"Parameters\": {\n \"[***]cketName\": {\n \"Description\": \"Name of the common deployment bucket provided by the parent stack\",\n \"Type\": \"String\",\n \"Default\": \"DeploymentBucket\"\n },\n \"[***]eName\": {\n \"Type\": \"String\",\n \"Default\": \"AuthRoleName\"\n },\n \"[***]leName\": {\n \"Type\": \"String\",\n \"Default\": \"UnauthRoleName\"\n }\n },\n \"Resources\": {\n \"DeploymentBucket\": {\n \"Type\": \"AWS::S3::Bucket\",\n \"DeletionPolicy\": \"Retain\",\n \"Properties\": {\n \"BucketName\": {\n \"Ref\": \"DeploymentBucketName\"\n },\n \"BucketEncryption\": {\n \"ServerSideEncryptionConfiguration\": [\n {\n \"ServerSideEncryptionByDefault\": {\n \"SSEAlgorithm\": \"AES256\"\n }\n }\n ]\n }\n }\n },\n \"AuthRole\": {\n \"Type\": \"AWS::IAM::Role\",\n \"Properties\": {\n \"RoleName\": {\n \"Ref\": \"AuthRoleName\"\n },\n \"AssumeRolePolicyDocument\": {\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"\",\n \"Effect\": \"Deny\",\n \"Principal\": {\n \"Federated\": \"cognito-identity.amazonaws.com\"\n },\n \"Action\": \"sts:AssumeRoleWithWebIdentity\"\n }\n ]\n },\n \"PermissionsBoundary\": \"####"\n }\n },\n \"UnauthRole\": {\n \"Type\": \"AWS::IAM::Role\",\n \"Properties\": {\n \"RoleName\": {\n \"Ref\": \"UnauthRoleName\"\n },\n \"AssumeRolePolicyDocument\": {\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"\",\n \"Effect\": \"Deny\",\n \"Principal\": {\n \"Federated\": \"cognito-identity.amazonaws.com\"\n },\n \"Action\": \"sts:AssumeRoleWithWebIdentity\"\n }\n ]\n },\n \"PermissionsBoundary\": \"####"\n }\n }\n },\n \"Outputs\": {\n \"Region\": {\n \"Description\": \"CloudFormation provider root stack Region\",\n \"Value\": {\n \"Ref\": \"AWS::Region\"\n },\n \"Export\": {\n \"Name\": {\n \"Fn::Sub\": \"${AWS::StackName}-Region\"\n }\n }\n },\n \"StackName\": {\n \"Description\": \"CloudFormation provider root stack ID\",\n \"Value\": {\n \"Ref\": \"AWS::StackName\"\n },\n \"Export\": {\n \"Name\": {\n \"Fn::Sub\": \"${AWS::StackName}-StackName\"\n }\n }\n },\n \"StackId\": {\n \"Description\": \"CloudFormation provider root stack name\",\n \"Value\": {\n \"Ref\": \"AWS::StackId\"\n },\n \"Export\": {\n \"Name\": {\n \"Fn::Sub\": \"${AWS::StackName}-StackId\"\n }\n }\n },\n \"DeploymentBucketName\": {\n \"Description\": \"CloudFormation provider root stack deployment bucket name\",\n \"Value\": {\n \"Ref\": \"DeploymentBucketName\"\n },\n \"Export\": {\n \"Name\": {\n \"Fn::Sub\": \"${AWS::StackName}-DeploymentBucketName\"\n }\n }\n },\n \"AuthRoleArn\": {\n \"Value\": {\n \"Fn::GetAtt\": [\n \"AuthRole\",\n \"Arn\"\n ]\n }\n },\n \"UnauthRoleArn\": {\n \"Value\": {\n \"Fn::GetAtt\": [\n \"UnauthRole\",\n \"Arn\"\n ]\n }\n },\n \"AuthRoleName\": {\n \"Value\": {\n \"Ref\": \"AuthRole\"\n }\n },\n \"UnauthRoleName\": {\n \"Value\": {\n \"Ref\": \"UnauthRole\"\n }\n }\n }\n}","Parameters":[{"ParameterKey":"DeploymentBucketName","ParameterValue":"amplify-####-dev-####-deployment"},{"ParameterKey":"AuthRoleName","ParameterValue":"amplify-####-dev-####-authRole"},{"ParameterKey":"UnauthRoleName","ParameterValue":"amplify-####-dev-####-unauthRole"}],"Tags":[{"Key":"[***]tack","Value":"dev"},{"Key":"[***]ication","Value":"####"}]}])
2024-02-26T16:49:05.742Z|info : amplify-provider-awscloudformation.aws-cfn.cfnModel.createStack([{"StackName":"[####","Capabilities":["CAPABILITY_NAMED_IAM","CAPABILITY_AUTO_EXPAND"],"TemplateBody":"{\n \"AWSTemplateFormatVersion\": \"2010-09-09\",\n \"Description\": \"{\\\"createdOn\\\":\\\"Linux\\\",\\\"createdBy\\\":\\\"Amplify\\\",\\\"createdWith\\\":\\\"12.10.1\\\",\\\"stackType\\\":\\\"root\\\",\\\"metadata\\\":{}}\",\n \"Parameters\": {\n \"[***]cketName\": {\n \"Description\": \"Name of the common deployment bucket provided by the parent stack\",\n \"Type\": \"String\",\n \"Default\": \"DeploymentBucket\"\n },\n \"[***]eName\": {\n \"Type\": \"String\",\n \"Default\": \"AuthRoleName\"\n },\n \"[***]leName\": {\n \"Type\": \"String\",\n \"Default\": \"UnauthRoleName\"\n }\n },\n \"Resources\": {\n \"DeploymentBucket\": {\n \"Type\": \"AWS::S3::Bucket\",\n \"DeletionPolicy\": \"Retain\",\n \"Properties\": {\n \"BucketName\": {\n \"Ref\": \"DeploymentBucketName\"\n },\n \"BucketEncryption\": {\n \"ServerSideEncryptionConfiguration\": [\n {\n \"ServerSideEncryptionByDefault\": {\n \"SSEAlgorithm\": \"AES256\"\n }\n }\n ]\n }\n }\n },\n \"AuthRole\": {\n \"Type\": \"AWS::IAM::Role\",\n \"Properties\": {\n \"RoleName\": {\n \"Ref\": \"AuthRoleName\"\n },\n \"AssumeRolePolicyDocument\": {\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"\",\n \"Effect\": \"Deny\",\n \"Principal\": {\n \"Federated\": \"cognito-identity.amazonaws.com\"\n },\n \"Action\": \"sts:AssumeRoleWithWebIdentity\"\n }\n ]\n },\n \"PermissionsBoundary\": \"####"\n }\n },\n \"UnauthRole\": {\n \"Type\": \"AWS::IAM::Role\",\n \"Properties\": {\n \"RoleName\": {\n \"Ref\": \"UnauthRoleName\"\n },\n \"AssumeRolePolicyDocument\": {\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"\",\n \"Effect\": \"Deny\",\n \"Principal\": {\n \"Federated\": \"cognito-identity.amazonaws.com\"\n },\n \"Action\": \"sts:AssumeRoleWithWebIdentity\"\n }\n ]\n },\n \"PermissionsBoundary\": \"####"\n }\n }\n },\n \"Outputs\": {\n \"Region\": {\n \"Description\": \"CloudFormation provider root stack Region\",\n \"Value\": {\n \"Ref\": \"AWS::Region\"\n },\n \"Export\": {\n \"Name\": {\n \"Fn::Sub\": \"${AWS::StackName}-Region\"\n }\n }\n },\n \"StackName\": {\n \"Description\": \"CloudFormation provider root stack ID\",\n \"Value\": {\n \"Ref\": \"AWS::StackName\"\n },\n \"Export\": {\n \"Name\": {\n \"Fn::Sub\": \"${AWS::StackName}-StackName\"\n }\n }\n },\n \"StackId\": {\n \"Description\": \"CloudFormation provider root stack name\",\n \"Value\": {\n \"Ref\": \"AWS::StackId\"\n },\n \"Export\": {\n \"Name\": {\n \"Fn::Sub\": \"${AWS::StackName}-StackId\"\n }\n }\n },\n \"DeploymentBucketName\": {\n \"Description\": \"CloudFormation provider root stack deployment bucket name\",\n \"Value\": {\n \"Ref\": \"DeploymentBucketName\"\n },\n \"Export\": {\n \"Name\": {\n \"Fn::Sub\": \"${AWS::StackName}-DeploymentBucketName\"\n }\n }\n },\n \"AuthRoleArn\": {\n \"Value\": {\n \"Fn::GetAtt\": [\n \"AuthRole\",\n \"Arn\"\n ]\n }\n },\n \"UnauthRoleArn\": {\n \"Value\": {\n \"Fn::GetAtt\": [\n \"UnauthRole\",\n \"Arn\"\n ]\n }\n },\n \"AuthRoleName\": {\n \"Value\": {\n \"Ref\": \"AuthRole\"\n }\n },\n \"UnauthRoleName\": {\n \"Value\": {\n \"Ref\": \"UnauthRole\"\n }\n }\n }\n}","Parameters":[{"ParameterKey":"DeploymentBucketName","ParameterValue":"amplify-####-dev-####-deployment"},{"ParameterKey":"AuthRoleName","ParameterValue":"amplify-####-dev-####-authRole"},{"ParameterKey":"UnauthRoleName","ParameterValue":"amplify-####-dev-####-unauthRole"}],"Tags":[{"Key":"[***]tack","Value":"dev"},{"Key":"[***]ication","Value":"####"}]}])
2024-02-26T16:49:10.746Z|info : amplify-provider-awscloudformation.aws-cfn.getStackEvents.cfnModel.describeStackEvents([{"StackName":"####"}])
2024-02-26T16:49:11.077Z|info : amplify-provider-awscloudformation.aws-cfn.getStackEvents.cfnModel.describeStackEvents([{"StackName":"[***]rmation:us-[***]st-[***]58:stack/[####"}])
2024-02-26T16:49:15.747Z|info : amplify-provider-awscloudformation.aws-cfn.getStackEvents.cfnModel.describeStackEvents([{"StackName":"[####}])
2024-02-26T16:49:16.059Z|info : amplify-provider-awscloudformation.aws-cfn.getStackEvents.cfnModel.describeStackEvents([{"StackName":"[***]rmation:us-[***]st-[***]58:stack/####}])
2024-02-26T16:49:25.748Z|info : amplify-provider-awscloudformation.aws-cfn.getStackEvents.cfnModel.describeStackEvents([{"StackName":"####"}])
2024-02-26T16:49:26.062Z|info : amplify-provider-awscloudformation.aws-cfn.getStackEvents.cfnModel.describeStackEvents([{"StackName":"[***]rmation:us-[***]st-[***]58:stack/####}])
2024-02-26T16:49:45.748Z|info : amplify-provider-awscloudformation.aws-cfn.getStackEvents.cfnModel.describeStackEvents([{"StackName":"####"}])
2024-02-26T16:49:46.102Z|info : amplify-provider-awscloudformation.aws-cfn.getStackEvents.cfnModel.describeStackEvents([{"StackName":"[***]rmation:us-[***]st-[***]58:stack/####"}])
2024-02-26T16:50:11.538Z|error : amplify-provider-awscloudformation.aws-cfn.cfnModel.createStack([{"StackName":"####","Capabilities":["CAPABILITY_NAMED_IAM","CAPABILITY_AUTO_EXPAND"],"TemplateBody":"{\n \"AWSTemplateFormatVersion\": \"2010-09-09\",\n \"Description\": \"{\\\"createdOn\\\":\\\"Linux\\\",\\\"createdBy\\\":\\\"Amplify\\\",\\\"createdWith\\\":\\\"12.10.1\\\",\\\"stackType\\\":\\\"root\\\",\\\"metadata\\\":{}}\",\n \"Parameters\": {\n \"[***]cketName\": {\n \"Description\": \"Name of the common deployment bucket provided by the parent stack\",\n \"Type\": \"String\",\n \"Default\": \"DeploymentBucket\"\n },\n \"[***]eName\": {\n \"Type\": \"String\",\n \"Default\": \"AuthRoleName\"\n },\n \"[***]leName\": {\n \"Type\": \"String\",\n \"Default\": \"UnauthRoleName\"\n }\n },\n \"Resources\": {\n \"DeploymentBucket\": {\n \"Type\": \"AWS::S3::Bucket\",\n \"DeletionPolicy\": \"Retain\",\n \"Properties\": {\n \"BucketName\": {\n \"Ref\": \"DeploymentBucketName\"\n },\n \"BucketEncryption\": {\n \"ServerSideEncryptionConfiguration\": [\n {\n \"ServerSideEncryptionByDefault\": {\n \"SSEAlgorithm\": \"AES256\"\n }\n }\n ]\n }\n }\n },\n \"AuthRole\": {\n \"Type\": \"AWS::IAM::Role\",\n \"Properties\": {\n \"RoleName\": {\n \"Ref\": \"AuthRoleName\"\n },\n \"AssumeRolePolicyDocument\": {\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"\",\n \"Effect\": \"Deny\",\n \"Principal\": {\n \"Federated\": \"cognito-identity.amazonaws.com\"\n },\n \"Action\": \"sts:AssumeRoleWithWebIdentity\"\n }\n ]\n },\n \"PermissionsBoundary\": \"####"\n }\n },\n \"UnauthRole\": {\n \"Type\": \"AWS::IAM::Role\",\n \"Properties\": {\n \"RoleName\": {\n \"Ref\": \"UnauthRoleName\"\n },\n \"AssumeRolePolicyDocument\": {\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"\",\n \"Effect\": \"Deny\",\n \"Principal\": {\n \"Federated\": \"cognito-identity.amazonaws.com\"\n },\n \"Action\": \"sts:AssumeRoleWithWebIdentity\"\n }\n ]\n },\n \"PermissionsBoundary\": \"####"\n }\n }\n },\n \"Outputs\": {\n \"Region\": {\n \"Description\": \"CloudFormation provider root stack Region\",\n \"Value\": {\n \"Ref\": \"AWS::Region\"\n },\n \"Export\": {\n \"Name\": {\n \"Fn::Sub\": \"${AWS::StackName}-Region\"\n }\n }\n },\n \"StackName\": {\n \"Description\": \"CloudFormation provider root stack ID\",\n \"Value\": {\n \"Ref\": \"AWS::StackName\"\n },\n \"Export\": {\n \"Name\": {\n \"Fn::Sub\": \"${AWS::StackName}-StackName\"\n }\n }\n },\n \"StackId\": {\n \"Description\": \"CloudFormation provider root stack name\",\n \"Value\": {\n \"Ref\": \"AWS::StackId\"\n },\n \"Export\": {\n \"Name\": {\n \"Fn::Sub\": \"${AWS::StackName}-StackId\"\n }\n }\n },\n \"DeploymentBucketName\": {\n \"Description\": \"CloudFormation provider root stack deployment bucket name\",\n \"Value\": {\n \"Ref\": \"DeploymentBucketName\"\n },\n \"Export\": {\n \"Name\": {\n \"Fn::Sub\": \"${AWS::StackName}-DeploymentBucketName\"\n }\n }\n },\n \"AuthRoleArn\": {\n \"Value\": {\n \"Fn::GetAtt\": [\n \"AuthRole\",\n \"Arn\"\n ]\n }\n },\n \"UnauthRoleArn\": {\n \"Value\": {\n \"Fn::GetAtt\": [\n \"UnauthRole\",\n \"Arn\"\n ]\n }\n },\n \"AuthRoleName\": {\n \"Value\": {\n \"Ref\": \"AuthRole\"\n }\n },\n \"UnauthRoleName\": {\n \"Value\": {\n \"Ref\": \"UnauthRole\"\n }\n }\n }\n}","Parameters":[{"ParameterKey":"DeploymentBucketName","ParameterValue":"amplify-####-dev-####-deployment"},{"ParameterKey":"AuthRoleName","ParameterValue":"amplify-####-dev-####-authRole"},{"ParameterKey":"UnauthRoleName","ParameterValue":"amplify-####-dev-####-unauthRole"}],"Tags":[{"Key":"[***]tack","Value":"dev"},{"Key":"[***]ication","Value":"####"}]}])
ResourceNotReady: Resource is not in the state stackCreateComplete
2024-02-26T16:50:11.540Z|info : amplify-provider-awscloudformation.aws-cfn.getStackEvents.cfnModel.describeStackEvents([{"StackName":"####"}])
2024-02-26T16:50:11.656Z|error : Initialization of project failed
DeploymentFault: Initialization of project failed
```

### Additional information

_No response_

### Before submitting, please confirm:

- [X] I have done my best to include a minimal, self-contained set of instructions for consistently reproducing the issue.
- [X] I have removed any sensitive information from my code snippets and submission.

Contributor guide

Open the contributing guide

Research direction

Start with the amplify init flow and the logged CloudFormation createStack request, focusing on the generated DeploymentBucket resource and the point where initialization fails before creating the local backend folder. Confirm the behavior against the reported Control Tower S3 requirements; done means init provides a supported way to customize or override the deployment bucket configuration before stack creation.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, typescript
Domain
cli, cloud, infrastructure
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.