{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Account Factory setup\n", "\n", "In this notebook we will be creating an account factory service using CloudFormation templates and Service Catalog to increase the agility and decrease the time it takes to create accounts in you AWS Organization.\n", "\n", "### Initialize Notebook" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import boto3\n", "import botocore\n", "import json\n", "import time\n", "import os\n", "\n", "import project_path\n", "from lib import workshop\n", "\n", "s3 = boto3.resource('s3')\n", "s3_client = boto3.client('s3')\n", "cfn = boto3.client('cloudformation')\n", "lambda_client = boto3.client('lambda')\n", "sc = boto3.client('servicecatalog')\n", "\n", "session = boto3.session.Session()\n", "region = session.region_name\n", "account_id = boto3.client('sts').get_caller_identity().get('Account')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### [Create S3 Bucket](https://docs.aws.amazon.com/AmazonS3/latest/gsg/CreatingABucket.html)\n", "\n", "We will create an S3 bucket that will be used throughout the workshop for storing our data.\n", "\n", "[s3.create_bucket](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.Client.create_bucket) boto3 documentation" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "bucket = workshop.create_bucket(region, session, 'account-')\n", "print(bucket)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Download Account Factory files for setup\n", "\n", "Files for this notebook taken from the [Account Factory](https://github.com/aws-samples/account-factory) repo hosted on [aws-samples](https://github.com/aws-samples/). " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!wget https://raw.githubusercontent.com/aws-samples/account-factory/master/AccountCreationLambda.py\n", "!wget https://raw.githubusercontent.com/aws-samples/account-factory/master/Accountbaseline.yml\n", "!wget https://raw.githubusercontent.com/aws-samples/account-factory/master/accountbuilder.yml" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### View Account Creation script" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!pygmentize AccountCreationLambda.py" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Zip the Account Creation script for use with AWS Lambda\n", "\n", "The account creation script will be used when baselining a new account in your AWS Organization. We need to zip the file and upload all files to a known S3 bucket for use later in the notebook." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%bash\n", "zip -r AccountCreationLambda.zip AccountCreationLambda.py" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### [Upload to S3](https://docs.aws.amazon.com/AmazonS3/latest/dev/Welcome.html)\n", "\n", "Next, we will upload the files needed for the account factory to S3 to be used later in the workshop.\n", "\n", "[s3.upload_file](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.Client.upload_file) boto3 documentation" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "files = ['Accountbaseline.yml', 'accountbuilder.yml', 'AccountCreationLambda.zip']\n", "\n", "for file_name in files:\n", " session.resource('s3').Bucket(bucket).Object(file_name).upload_file(file_name)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### [Create Service Catalog Portfolio](https://docs.aws.amazon.com/servicecatalog/latest/adminguide/portfoliomgmt-create.html)\n", "\n", "[AWS Service Catalog](https://docs.aws.amazon.com/servicecatalog/latest/adminguide/introduction.html) enables organizations to create and manage catalogs of IT services that are approved for use on AWS. These IT services can include everything from virtual machine images, servers, software, and databases to complete multi-tier application architectures. AWS Service Catalog allows organizations to centrally manage commonly deployed IT services, and helps organizations achieve consistent governance and meet compliance requirements. End users can quickly deploy only the approved IT services they need, following the constraints set by your organization.\n", "\n", "To provide users with products, begin by creating a portfolio for those products.\n", "\n", "[servicecatalog.create_portfolio](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/servicecatalog.html#ServiceCatalog.Client.create_portfolio)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!cat accountbuilder.yml" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "response = sc.create_portfolio(\n", " AcceptLanguage='en',\n", " DisplayName='Account Management',\n", " Description='Portfolio for managing account creation',\n", " ProviderName='AWS Workshop Owner'\n", ")\n", "\n", "portfolio_id = response['PortfolioDetail']['Id']" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print('https://{0}.console.aws.amazon.com/servicecatalog/home?region={0}#/portfolio/details?portfolioId={1}'.format(region, portfolio_id))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### [Create Account Builder Service Catalog Product](https://docs.aws.amazon.com/servicecatalog/latest/adminguide/catalogs_products.html)\n", "\n", "You create products by packaging an AWS CloudFormation template with metadata, update products by creating a new version based on an updated template, and group products together into portfolios to distribute them to users. We will be packaging up the `accountbuilder.yml` file as a product to create new accounts with your AWS Organization.\n", "\n", "[servicecatalog.create_product](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/servicecatalog.html#ServiceCatalog.Client.create_product)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "template = 'https://s3.amazonaws.com/{0}/{1}'.format(bucket, files[1])\n", "print(template)\n", "\n", "response = sc.create_product(\n", " AcceptLanguage='en',\n", " Name='Account Builder',\n", " Owner='AWS Workshop Owner',\n", " Description='Account Builder product to on-board new accounts',\n", " Distributor='Central IT',\n", " SupportDescription='Reach out for any issues to the details below.',\n", " SupportEmail='admin@example.com',\n", " SupportUrl='https://support.example.com',\n", " ProductType='CLOUD_FORMATION_TEMPLATE',\n", " Tags=[\n", " {\n", " 'Key': 'Code',\n", " 'Value': 'AS'\n", " },\n", " ],\n", " ProvisioningArtifactParameters={\n", " 'Name': 'v1',\n", " 'Description': 'Version 1 of account builder',\n", " 'Info': {\n", " 'LoadTemplateFromURL': template\n", " },\n", " 'Type': 'CLOUD_FORMATION_TEMPLATE'\n", " }\n", ")\n", "\n", "product_id = response['ProductViewDetail']['ProductViewSummary']['ProductId']\n", "print(product_id)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### [Add Account Builder product to portfolio](https://docs.aws.amazon.com/servicecatalog/latest/adminguide/catalogs_portfolios_adding-products.html)\n", "\n", "To provide users with products, begin by creating a portfolio for those products.\n", "\n", "[servicecatalog.associate_product_with_portfolio](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/servicecatalog.html#ServiceCatalog.Client.associate_product_with_portfolio)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "response = sc.associate_product_with_portfolio(\n", " AcceptLanguage='en',\n", " ProductId=product_id,\n", " PortfolioId=portfolio_id\n", ")\n", "\n", "print(response)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### [Configure Self Service Access to Portfolios](https://docs.aws.amazon.com/servicecatalog/latest/adminguide/using-service-actions.html)\n", "\n", "AWS Service Catalog enables you to reduce administrative maintenance and end-user training while adhering to compliance and security measures. With self-service actions, as the administrator you can enable end users to perform operational tasks, troubleshoot issues, run approved commands, or request permissions in AWS Service Catalog.\n", "\n", "We will use the `Admin` group in this example but choose the appropriate role for this portfolio in your own environment." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "iam_group_arn = 'arn:aws:iam::{0}:group/Admin'.format(account_id)\n", "\n", "response = sc.associate_principal_with_portfolio(\n", " AcceptLanguage='en',\n", " PortfolioId=portfolio_id,\n", " PrincipalARN=iam_group_arn,\n", " PrincipalType='IAM'\n", ")\n", "\n", "print(response)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Access the portfolio and launch Account Builder\n", "\n", "Clicking on the link below we will launch a new AWS account for the Organization. Use the values below and click `Next` to add the `Parameters` specific to the account you will be creating.\n", "\n", "* Name: `TestAccount`\n", "* Version `v1`\n", "\n", "On the `Parameters` name fill out the required fields and click `Next`. Here you can add [TagOptions](https://docs.aws.amazon.com/servicecatalog/latest/adminguide/tagoptions.html) and [Notifications](https://docs.aws.amazon.com/servicecatalog/latest/adminguide/constraints-notification.html) and finally click `Launch` to create the new account.\n", "\n", "For the `Parameters` section when launching fill out fields with your specific account information. The parameters below give you an example of what to put in a few of the values.\n", "\n", "* `stackname`: `Accountbaseline.yml`\n", "* `sourcebucket`: {{bucket created above}}\n", "* `newrole`: You can leave the default or give it a unique name.\n", "* `newrolepolicy`: Free formed text of a valid AWS IAM Policy. The default is `Admin` access. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print('https://{0}.console.aws.amazon.com/servicecatalog/home?region={0}#/products'.format(region))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Clean Up" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "response = sc.disassociate_product_from_portfolio(\n", " AcceptLanguage='en',\n", " ProductId=product_id,\n", " PortfolioId=portfolio_id\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "response = sc.delete_product(\n", " AcceptLanguage='en',\n", " Id=product_id\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "response = sc.disassociate_principal_from_portfolio(\n", " AcceptLanguage='en',\n", " PortfolioId=portfolio_id,\n", " PrincipalARN=iam_group_arn\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "response = sc.delete_portfolio(\n", " AcceptLanguage='en',\n", " Id=portfolio_id\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "workshop.delete_bucket_completely(bucket)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "conda_python3", "language": "python", "name": "conda_python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.5" } }, "nbformat": 4, "nbformat_minor": 2 }