aws-amplify / amplify-cli

The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development.
Apache License 2.0
2.8k stars 819 forks source link

Override S3 Auth Public Policy on `init` #13619

Open bigbenbeer opened 4 months ago

bigbenbeer commented 4 months ago

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:

ykethan commented 4 months ago

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.

bigbenbeer commented 4 months ago

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.

ykethan commented 4 months ago

@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

bigbenbeer commented 3 months ago

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?