amplify-cli icon indicating copy to clipboard operation
amplify-cli copied to clipboard

Override S3 Auth Public Policy on `init`

Open bigbenbeer opened this issue 11 months ago • 4 comments

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.

bigbenbeer avatar Feb 26 '24 20:02 bigbenbeer

Hey @bigbenbeer, thank you for reaching out. Amplify CLI currently does not support modifying the deployment bucket created on a amplify init. Marking this as feature-request for further evaluation.

ykethan avatar Feb 26 '24 21:02 ykethan

Is there any workaround for now besides disabling the security rules inside Control Tower? The issue is currently blocking us from using Amplify at all. We are unable to start a new project.

bigbenbeer avatar Feb 26 '24 21:02 bigbenbeer

@bigbenbeer curious if Amplify Gen 2 maybe ideal for your use case here as it utilizes CDK. Refer to https://docs.amplify.aws/gen2/ for additional information. As CDK bootstrap allows customizing the asset bucket: https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping.html#bootstrapping-customizing

ykethan avatar Feb 27 '24 20:02 ykethan

My app is built on Flutter which Gen 2 does not seem to support yet. Is there an ETA on when Gen 2 will become available for Flutter?

bigbenbeer avatar Apr 03 '24 19:04 bigbenbeer