+++
title = "Using AWS Service Catalog"
weight = 15
home_region = "eu-west-1"
codecommit_repo_name = "subnet"
codecommit_repo_branch = "main"
product_name = "subnet"
product_version = "v1"
portfolio_name = "networking-mandatory"
+++
---
## What are we going to do?
We are going to perform the following steps:
- Define a product with a version and a portfolio
- Add the source code for our product
- Provision the product _{{% param product_name %}}_ into a spoke account
## Step by step guide
Here are the steps you need to follow to "{{% param title %}}"
### Define a product with a version and a portfolio
- Navigate to the {{% service_catalog_factory_code_commit_repo_link %}}
- Open the *Add file* menu and click the *Create file* button
- Copy the following snippet into the main input field:
{{< highlight js >}}
Schema: factory-2019-04-01
Products:
- Name: "subnet"
Owner: "networking@example.com"
Description: "subnet for networking"
Distributor: "networking team"
SupportDescription: "Speak to networking@example.com about exceptions and speak to cloud-engineering@example.com about implementation issues"
SupportEmail: "cloud-engineering@example.com"
SupportUrl: "https://wiki.example.com/cloud-engineering/networking/subnet"
Tags:
- Key: "type"
Value: "governance"
- Key: "creator"
Value: "cloud-engineering"
- Key: "cost-center"
Value: "governance"
Versions:
- Name: "v1"
Description: "v1 of subnet"
Active: True
Source:
Provider: "CodeCommit"
Configuration:
RepositoryName: "subnet"
BranchName: "main"
Portfolios:
- "mandatory"
Portfolios:
- DisplayName: "mandatory"
Description: "Portfolio containing the mandatory networking components"
ProviderName: "cloud-engineering"
Associations:
- "arn:aws:iam::${AWS::AccountId}:role/"
Tags:
- Key: "type"
Value: "governance"
- Key: "creator"
Value: "cloud-engineering"
- Key: "cost-center"
Value: "governance"
{{< / highlight >}}
- Update the Associations in the pasted text to include the IAM role name you are assuming in your account.
- Set the *File name* to *portfolios/networking.yaml*
- Set your *Author name*
- Set your *Email address*
- Set your *Commit message*
{{% notice tip %}}
Using a good / unique commit message will help you understand what is going on later.
{{% /notice %}}
- Click the *Commit changes* button:
{{< figure src="/tasks/CommitChanges.png" >}}
#### What did we just do?
The YAML file we created in the CodeCommit repository told the framework to perform several actions:
- create a product named _{{% param product_name %}}_
- add a _{{% param product_version %}}_ of our product
- create a portfolio named _{{% param portfolio_name %}}_
- add the product: _{{% param product_name %}}_ to the portfolio: _{{% param portfolio_name %}}_
#### Verify the change worked
Once you have made your changes the {{% service_catalog_factory_pipeline_link %}} should have run. If you were very quick in making the change, the pipeline
may still be running. If it has not yet started feel free to the hit the *Release change* button.
Once it has completed it should show the *Source* and *Build* stages in green to indicate they have completed
successfully:
{{< figure src="/tasks/SuccessfulFactoryRun.png" >}}
### Add the source code for our product
When you configured your product version, you specified the following version:
{{< highlight js >}}
Versions:
- Name: "v1"
Description: "v1 of subnet"
Active: True
Source:
Provider: "CodeCommit"
Configuration:
RepositoryName: "subnet"
BranchName: "main"
{{< / highlight >}}
This tells the framework the source code for the product comes from the _{{% param codecommit_repo_branch %}}_ branch of a
_CodeCommit_ repository of the name _{{% param codecommit_repo_name %}}_.
We now need to create the CodeCommit repository and add the AWS CloudFormation template we are going to use for our
product.
- Navigate to {{% codecommit_link %}}
- Click *Create repository*
{{< figure src="/tasks/CreateRepository.png" >}}
- Input the name `{{% param codecommit_repo_name %}}`
{{< figure src="/tasks/InputTheName.png" >}}
- Click *Create*
{{< figure src="/tasks/ClickCreate.png" >}}
- Scroll down to the bottom of the page and hit the *Create file* button
{{< figure src="/tasks/create_file.png" >}}
- Copy the following snippet into the main input field:
{{< highlight js >}}
AWSTemplateFormatVersion: '2010-09-09'
Description: |
Builds out a VPC for use
Parameters:
SubnetCIDR:
Type: String
Description: |
Subnet to use for the Subnet
VPCID:
Type: String
Description: |
VPC to create Subnet in
Resources:
Subnet:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: VPCID
CidrBlock:
Ref: SubnetCIDR
AvailabilityZone: !Select
- 0
- !GetAZs
Ref: 'AWS::Region'
{{< / highlight >}}
- Set the *File name* to `product.template.yaml`
- Set your *Author name*
- Set your *Email address*
- Set your *Commit message*
{{% notice tip %}}
Using a good / unique commit message will help you understand what is going on later.
{{% /notice %}}
Creating that file should trigger your
{{% codepipeline_pipeline_link "subnet-v1-pipeline" %}}.
Once the pipeline has completed it should show the stages in green to indicate they have completed successfully:
{{< figure src="/tasks/SuccessfulFactoryProductRun.png" >}}
{{% notice tip %}}
You should see your commit message on this screen, it will help you know which version of ServiceCatalogFactory repository the
pipeline is processing.
{{% /notice %}}
Once you have verified the pipeline has run you can go to {{% service_catalog_products_list_link %}} to view your newly
created version.
You should see the product you created listed:
{{< figure src="/tasks/SeeYourTask1Product.png" >}}
Click on the product and verify *{{% param product_version %}}* is there
{{< figure src="/tasks/SeeYourTask1ProductVersion1.png" >}}
{{% notice note %}}
If you cannot see your version please raise your hand for some assistance
{{% /notice %}}
You have now successfully created a version for your product!
#### Verify the product was added to the portfolio
Now that you have verified the pipeline has run you can go to {{% service_catalog_portfolios_list_link %}} to view your
portfolio.
- Click on *{{% param portfolio_name %}}*
{{< figure src="/tasks/PortfolioReinventCloudEngineeringGovernance.png" >}}
- Click on the product *_{{% param product_name %}}_*
- Click on the version *_{{% param product_version %}}_*
{{< figure src="/tasks/ClickAwsConfigS3BucketServerSideEncryptionEnabledV1.png" >}}
### Provision the product _{{% param product_name %}}_ into a spoke account
- Navigate to the {{% service_catalog_puppet_code_commit_repo_link %}} again
- Click on *manifest.yaml*
- Click *Edit*
- Append the following snippet to the end of the main input field:
{{< highlight js >}}
launches:
subnet:
portfolio: "networking-mandatory"
product: "subnet"
version: "v1"
depends_on:
- name: vpc
type: stack
affinity: stack
parameters:
VPCID:
ssm:
name: "/networking/vpc/account-parameters/${AWS::AccountId}/${AWS::Region}/VPCId"
SubnetCIDR:
default: '10.0.0.0/24'
deploy_to:
tags:
- tag: "type:prod"
regions: "default_region"
{{< / highlight >}}
- The main input field should look like this (remember to set your account_id):
{{< highlight js >}}
accounts:
- account_id: ""
name: "puppet-account"
default_region: "eu-west-1"
regions_enabled:
- "eu-west-1"
tags:
- "type:prod"
- "partition:eu"
stacks:
delete-default-networking-function:
name: "delete-default-networking-function"
version: "v1"
capabilities:
- CAPABILITY_NAMED_IAM
deploy_to:
tags:
- tag: "type:prod"
regions: "default_region"
vpc:
name: "vpc"
version: "v1"
depends_on:
- name: "delete-default-networking"
type: "lambda-invocation"
affinity: "lambda-invocation"
deploy_to:
tags:
- tag: "type:prod"
regions: "default_region"
outputs:
ssm:
- param_name: "/networking/vpc/account-parameters/${AWS::AccountId}/${AWS::Region}/VPCId"
stack_output: VPCId
lambda-invocations:
delete-default-networking:
function_name: DeleteDefaultNetworking
qualifier: $LATEST
invocation_type: Event
depends_on:
- name: "delete-default-networking-function"
type: "stack"
affinity: "stack"
invoke_for:
tags:
- regions: "default_region"
tag: "type:prod"
assertions:
assert-no-default-vpcs:
expected:
source: manifest
config:
value: []
actual:
source: boto3
config:
client: 'ec2'
call: describe_vpcs
arguments: {}
use_paginator: true
filter: Vpcs[?IsDefault==`true`].State
depends_on:
- name: "delete-default-networking"
type: "lambda-invocation"
affinity: "lambda-invocation"
assert_for:
tags:
- regions: regions_enabled
tag: type:prod
launches:
subnet:
portfolio: "networking-mandatory"
product: "subnet"
version: "v1"
depends_on:
- name: vpc
type: stack
affinity: stack
parameters:
VPCID:
ssm:
name: "/networking/vpc/account-parameters/${AWS::AccountId}/${AWS::Region}/VPCId"
SubnetCIDR:
default: '10.0.0.0/24'
deploy_to:
tags:
- tag: "type:prod"
regions: "default_region"
{{< / highlight >}}
#### Committing the manifest file
- Set your *Author name*
- Set your *Email address*
- Set your *Commit message*
{{% notice tip %}}
Using a good / unique commit message will help you understand what is going on later.
{{% /notice %}}
- Click the *Commit changes* button:
{{< figure src="/tasks/CommitChanges.png" >}}
#### What did we just do?
The YAML file we created in the previous step told the framework to perform the following actions:
- provision a product named _{{% param product_name %}}_ into the default region of the account
When you added the following:
{{< highlight js >}}
launches:
subnet:
portfolio: "networking-mandatory"
product: "subnet"
version: "v1"
depends_on:
- name: vpc
type: stack
affinity: stack
parameters:
VPCID:
ssm:
name: "/networking/vpc/account-parameters/${AWS::AccountId}/${AWS::Region}/VPCId"
SubnetCIDR:
default: '10.0.0.0/24'
deploy_to:
tags:
- tag: "type:prod"
regions: "default_region"
{{< / highlight >}}
You told the framework to provision _{{% param product_version %}}_ of _{{% param product_name %}}_ from the portfolio
_{{% param portfolio_name %}}_ into every account that has the tag _type:prod_
{{< highlight js "hl_lines=7-9" >}}
accounts:
- account_id: ""
name: "puppet-account"
default_region: "eu-west-1"
regions_enabled:
- "eu-west-1"
tags:
- "type:prod"
- "partition:eu"
{{< / highlight >}}
Within each account there will be a copy of the product provisioned into the default region:
{{< highlight js "hl_lines=4" >}}
accounts:
- account_id: ""
name: "puppet-account"
default_region: "eu-west-1"
regions_enabled:
- "eu-west-1"
tags:
- "type:prod"
- "partition:eu"
{{< / highlight >}}
#### Verifying the provisioned product
Once you have made your changes the {{% service_catalog_puppet_pipeline_link %}} should have run. If you were quick in making the change, the pipeline
may still be running. If it has not yet started feel free to the hit the *Release change* button.
Once it has completed it should show the stages in green to indicate they have completed successfully:
{{< figure src="/tasks/SuccessfulPuppetRun.png" >}}
Once you have verified the pipeline has run you can go to {{% service_catalog_provisioned_products_link %}} to view your
provisioned product. Please note when you arrive at the provisioned product page you will need to select account from
the filter by drop down in the top right:
{{< figure src="/tasks/FilterByAccount.png" >}}
You have now successfully provisioned a product