From efc1d7c640eb904fb4b6c44f5a53176ca7948e30 Mon Sep 17 00:00:00 2001 From: Dylan Shields Date: Tue, 17 Dec 2019 23:32:26 -0800 Subject: [PATCH] Use CloudFormation quick-create link instead of tools script for resource creation --- README.md | 8 +- ...aket_default_s3_bucket.cloudformation.yaml | 12 --- ...ket_required_resources.cloudformation.yaml | 78 --------------- tools/create_braket_resources.py | 95 ------------------- 4 files changed, 4 insertions(+), 189 deletions(-) delete mode 100644 tools/braket_default_s3_bucket.cloudformation.yaml delete mode 100644 tools/braket_required_resources.cloudformation.yaml delete mode 100644 tools/create_braket_resources.py diff --git a/README.md b/README.md index d4162cbf7..cd583c38d 100644 --- a/README.md +++ b/README.md @@ -54,10 +54,10 @@ aws configure add-model --service-model "file://aqx-model.json" --service-name a 6. Create the necessary Amazon Braket resources in your AWS account. -This will create the required resources and a default S3 bucket, `braket-output-${AWS::AccountId}`, for storing Amazon Braket outputs. If you don't want to create a bucket and will create your own than drop the `--create-default-bucket` from the command below. -```bash -python tools/create_braket_resources.py --create-default-bucket -``` +Follow the link below to create the resources using CloudFormation. This will create the required IAM resources and a default S3 bucket, `braket-output-${AWS::AccountId}`, for storing Amazon Braket outputs. + +[Quick-Create in AWS CloudFormation](https://us-west-2.console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/create/review?templateURL=https://braket-external-assets-prod-us-west-2.s3-us-west-2.amazonaws.com/templates/braket-resources.yaml&stackName=BraketResources) + 7. You can now call Amazon Braket from the `braket-python-sdk`. diff --git a/tools/braket_default_s3_bucket.cloudformation.yaml b/tools/braket_default_s3_bucket.cloudformation.yaml deleted file mode 100644 index 15355a8b5..000000000 --- a/tools/braket_default_s3_bucket.cloudformation.yaml +++ /dev/null @@ -1,12 +0,0 @@ -Description: Default S3 Bucket for Amazon Braket -Resources: - IntegTestBucket: - Type: AWS::S3::Bucket - Properties: - BucketName: - Fn::Sub: "braket-output-${AWS::AccountId}" - AccessControl: Private - BucketEncryption: - ServerSideEncryptionConfiguration: - - ServerSideEncryptionByDefault: - SSEAlgorithm: AES256 diff --git a/tools/braket_required_resources.cloudformation.yaml b/tools/braket_required_resources.cloudformation.yaml deleted file mode 100644 index b61247f26..000000000 --- a/tools/braket_required_resources.cloudformation.yaml +++ /dev/null @@ -1,78 +0,0 @@ -Description: Required Amazon Braket resources -Resources: - AmazonBraketFullAccess: - Type: "AWS::IAM::Role" - Properties: - # Must be named AQxFullAccess - RoleName: AQxFullAccess - Description: Role that Amazon Braket assumes in order to read / write resources. - AssumeRolePolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Principal: - Service: - - braket.amazonaws.com - Action: - - sts:AssumeRole - Path: / - Policies: - - PolicyName: AmazonS3Access - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - "s3:PutObject" - - "s3:GetObject" - - "s3:ListBucket" - Resource: "*" - - PolicyName: SagemakerJobAccess - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - "sagemaker:CreateTrainingJob" - - "sagemaker:DescribeTrainingJob" - - "sagemaker:StopTrainingJob" - - "iam:PassRole" - Resource: "*" - - AmazonBraketJobsFullAccess: - Type: "AWS::IAM::Role" - Properties: - # Can be renamed if you desire. This is the role supplied to the create-quantum-job API - RoleName: AmazonBraketJobsFullAccess - Description: Role to supply to Amazon Braket's create-quantum-job API. - AssumeRolePolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Principal: - Service: - - sagemaker.amazonaws.com - Action: - - sts:AssumeRole - Path: / - Policies: - - PolicyName: SagemakerCreateTrainingJobPermissions - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - "cloudwatch:PutMetricData" - - "logs:CreateLogStream" - - "logs:PutLogEvents" - - "logs:CreateLogGroup" - - "logs:DescribeLogStreams" - - "s3:GetObject" - - "s3:PutObject" - - "s3:ListBucket" - - "ecr:GetAuthorizationToken" - - "ecr:BatchCheckLayerAvailability" - - "ecr:GetDownloadUrlForLayer" - - "ecr:BatchGetImage" - - "aqx:*" - Resource: "*" diff --git a/tools/create_braket_resources.py b/tools/create_braket_resources.py deleted file mode 100644 index 6e2f68307..000000000 --- a/tools/create_braket_resources.py +++ /dev/null @@ -1,95 +0,0 @@ -import argparse -import json -import os - -import boto3 -import yaml -from botocore.exceptions import ClientError - -REQUIRED_RESOURCES_CFN_FILENAME = os.path.join( - os.path.dirname(os.path.abspath(__file__)), "braket_required_resources.cloudformation.yaml" -) -REQUIRED_RESOURCES_STACK_NAME = "AmazonBraketResources" - -DEFAULT_BUCKET_CFN_FILENAME = os.path.join( - os.path.dirname(os.path.abspath(__file__)), "braket_default_s3_bucket.cloudformation.yaml" -) -DEFAULT_BUCKET_STACK_NAME = "AmazonBraketDefaultS3Bucket" - - -def main(): - parser = argparse.ArgumentParser( - description="Create the required AWS resources for Amazon Braket." - ) - parser.add_argument( - "--create-default-bucket", - dest="create_default_bucket", - action="store_true", - help="Creates a default S3 bucket for you to use with Amazon Braket, " - + "e.g. 'braket-output-${AWS::AccountId}'", - ) - args = parser.parse_args() - - boto_session = boto3.session.Session() - region = boto_session.region_name - cfn_client = boto_session.client("cloudformation") - - # Create required resources - _create_cfn_stack( - cfn_client, REQUIRED_RESOURCES_STACK_NAME, REQUIRED_RESOURCES_CFN_FILENAME, region - ) - - # Create default S3 bucket if specified - if args.create_default_bucket: - _create_cfn_stack( - cfn_client, DEFAULT_BUCKET_STACK_NAME, DEFAULT_BUCKET_CFN_FILENAME, region - ) - - -def _read_cfn_yaml_file(filename): - """Read the contents of a cloud formation template YAML file and return as a JSON string.""" - with open(filename, "r") as file: - yaml_content = file.read() - return json.dumps(yaml.load(yaml_content, Loader=yaml.BaseLoader)) - - -def _create_cfn_stack(cfn_client, stack_name, body_filename, region): - """ - Creates a CloudFormation stack. If stack already exists then it is deleted and then re-created - with the supplied template body. - """ - - template_body = _read_cfn_yaml_file(body_filename) - - print( - f"\nFollow in console: https://{region}.console.aws.amazon.com/cloudformation/home?" - + f"region={region}#/stacks/stackinfo?stackId={stack_name}" - ) - - try: - cfn_client.describe_stacks(StackName=stack_name) - print(f"Stack {stack_name} already exists, deleting it...") - cfn_client.delete_stack(StackName=stack_name) - - delete_waiter = cfn_client.get_waiter("stack_delete_complete") - delete_waiter.wait(StackName=stack_name) - print(f"Stack {stack_name} deleted") - except ClientError as e: - if e.response["Error"]["Code"] == "ValidationError": - # CFN stack doesn't exist, move on. - pass - else: - raise e - - cfn_client.create_stack( - StackName=stack_name, TemplateBody=template_body, Capabilities=["CAPABILITY_NAMED_IAM"] - ) - - print(f"Creating stack {stack_name}...") - create_waiter = cfn_client.get_waiter("stack_create_complete") - create_waiter.wait(StackName=stack_name) - print(f"Stack {stack_name} created") - - -if __name__ == "__main__": - main()