Provision a Terraform product in AWS Service Catalog by using a code repository - AWS Prescriptive Guidance

Provision a Terraform product in AWS Service Catalog by using a code repository

Created by Dr. Rahul Sharad Gaikwad (AWS) and Tamilselvan P (AWS)

Environment: PoC or pilot

Technologies: Infrastructure; DevOps

Workload: All other workloads

AWS services: AWS Service Catalog; Amazon EC2

Summary

AWS Service Catalog supports self-service provisioning with governance for your HashiCorp Terraform configurations. If you use Terraform, you can use Service Catalog as the single tool to organize, govern, and distribute your Terraform configurations within AWS at scale. You can access Service Catalog key features, including cataloging of standardized and pre-approved infrastructure as code (IaC) templates, access control, cloud resources provisioning with least privilege access, versioning, sharing to thousands of AWS accounts, and tagging. End users, such as engineers, database administrators, and data scientists, see a list of products and versions they have access to, and they can deploy them through a single action.

This pattern helps you deploy AWS resources by using Terraform code. The Terraform code in the GitHub repository is accessed through Service Catalog. Using this approach, you integrate the products with your existing Terraform workflows. Administrators can create Service Catalog portfolios and add AWS Launch Wizard products to them by using Terraform.

The following are the benefits of this solution:

  • Because of the rollback feature in Service Catalog, if any issues occur during deployment, you can revert the product to a previous version.

  • You can easily identify the differences between product versions. This helps you resolve issues during deployment.

  • You can configure a repository connection in Service Catalogue, such as to GitHub, GitLab, or AWS CodeCommit. You can make product changes directly through the repository.

For information about the overall benefits of AWS Service Catalog, see What is Service Catalog.

Prerequisites and limitations

Prerequisites

  • An active AWS account.

  • A GitHub, BitBucket, or other repository that contains Terraform configuration files in ZIP format.

  • AWS Serverless Application Model Command Line Interface (AWS SAM CLI), installed.

  • AWS Command Line Interface (AWS CLI), installed and configured.

  • Go, installed.

  • Python version 3.9 , installed. AWS SAM CLI requires this version of Python.

  • Permissions to write and run AWS Lambda functions and permissions to access and manage Service Catalog products and portfolios.

Architecture

Target technology stack

  • AWS Service Catalog

  • AWS Lambda

Target architecture

Architecture diagram of provisioning a Terraform product in Service Catalog from a code repo

The diagram shows the following workflow:

  1. When a Terraform configuration is ready, a developer creates a .zip file that contains all of the terraform code. The developer uploads the .zip file into the code repository that is connected to Service Catalog.

  2. An administrator associates the Terraform product to a portfolio in Service Catalog. The administrator also creates a launch constraint that allows end users to provision the product.

  3. In Service Catalog, end users launch AWS resources by using the Terraform configuration. They can choose which product version to deploy.

Tools

AWS services and tools

  • AWS Lambda is a compute service that helps you run code without needing to provision or manage servers. It runs your code only when needed and scales automatically, so you pay only for the compute time that you use.

  • AWS Service Catalog helps you centrally manage catalogs of IT services that are approved for AWS. End users can quickly deploy only the approved IT services they need, following the constraints set by your organization.

Other services

  • Go is an open source programming language that Google supports.

  • Python is a general-purpose computer programming language.

Code repository

If you require sample Terraform configurations that you can deploy through Service Catalog, you can use the configurations in the GitHub Amazon Macie Organization Setup Using Terraform repository. Use of the code samples in this repository is not required.

Best practices

  • Instead of providing the values for variables in the Terraform configuration file (terraform.tfvars), configure variable values when launching product through Service Catalog.

  • Grant access to the portfolio only to specific users or administrators.

  • Follow the principle of least privilege and grant the minimum permissions required to perform a task. For more information, see Grant least privilege and Security best practices in the IAM documentation.

Epics

TaskDescriptionSkills required

(Optional) Install Docker.

If you want to run the AWS Lambda functions in your development environment, install Docker. For instructions, see Install Docker Engine in the Docker documentation.

DevOps engineer

Install the AWS Service Catalog Engine for Terraform.

  1. Enter the following command to clone the AWS Service Catalog Engine for Terraform repository.

    git clone https://github.com/aws-samples/service-catalog-engine-for-terraform-os.git
  2. Navigate to the the root directory of the cloned repository.

  3. Enter the following command. This installs the engine.

    run ./bin/bash/deploy-tre.sh -r

    The AWS Region set in your default profile is not used during the automated installation. Instead, you provide the Region when you run this command.

DevOps engineer, AWS administrator
TaskDescriptionSkills required

Create a connection to the GitHub repository.

  1. Sign in to the AWS Management Console, and then open the Developer Tools console. You can access the Developer Tools console by choosing a service such as AWS CodePipeline, AWS CodeCommit, or AWS CodeDeploy.

  2. In the left navigation pane, choose Settings, and then choose Connections.

  3. Choose Create connection.

  4. Select the repository where you maintain the Terraform source code. For example, you can choose Bitbucket, GitHub, or GitHub Enterprise Server.

  5. Enter a name for the connection, and then choose Connect.

  6. When you are prompted, authenticate the repository.

    After authentication is complete, the connection is created and the status changes to active.

AWS administrator
TaskDescriptionSkills required

Create the Service Catalog product.

  1. Open the AWS Service Catalog console.

  2. Navigate to the Administration section, and then choose Product list.

  3. Choose Create product.

  4. On the Create product page in the Product details section, choose the External product type. Service Catalog uses this product type to support Terraform Community Edition products.

  5. Enter a name and owner for the Service Catalog product.

  6. Select Specify your code repository using a CodeStar provider.

  7. Enter the following information for your repository:

    • Connect to your provider using AWS CodeConnections – Select the connection you created previously.

    • Repository – Select the repository.

    • Branch – Select the branch.

    • Template file path – Choose the path where the code template file is stored. The file name should end with tar.gz.

  8. Under Version name and description, provide information about the product version.

  9. Choose Create product.

AWS administrator

Create a portfolio.

  1. Open the AWS Service Catalog console.

  2. Navigate to the Administration section, and then choose, choose Portfolios.

  3. Choose Create portfolio

  4. Enter the following values:

    • Portfolio nameSample terraform

    • Portfolio descriptionSample portfolio for Terraform configurations

    • Owner – Your contact information, such as email

  5. Choose Create.

AWS administrator

Add the Terraform product to the portfolio.

  1. Open the AWS Service Catalog console.

  2. Navigate to the Administration section, and then choose Product list.

  3. Select the Terraform product that you created previously.

  4. Choose Actions, and then choose Add product to portfolio.

  5. Choose the Sample terraform portfolio.

  6. Choose Add product to portfolio.

AWS administrator

Create the access policy.

  1. Open the AWS Identity and Access Management (IAM) console.

  2. In the navigation pane, choose Policies.

  3. In the content pane, choose Create policy.

  4. Choose the JSON option.

  5. Enter the sample JSON policy in Access policy in the Additional information section of this pattern.

  6. Choose Next.

  7. On the Review and create page, in the Policy name box, enter TerraformResourceCreationAndArtifactAccessPolicy.

  8. Choose Create policy.

AWS administrator

Create a custom trust policy.

  1. Open the AWS Identity and Access Management (IAM) console.

  2. In the navigation pane, choose Roles.

  3. Choose Create role.

  4. Under Trusted entity type, choose Custom trust policy.

  5. In the JSON policy editor, enter the sample JSON policy in Trust policy in the Additional information section of this pattern.

  6. Choose Next.

  7. Under Permissions policies, choose the TerraformResourceCreationAndArtifactAccessPolicy that you previously created.

  8. Choose Next.

  9. Under Role details, in the Role name box, enter SCLaunch-product

    Important: The role name must begin with SCLaunch.

  10. Choose Create role.

AWS administrator

Add a launch constraint to the Service Catalog product.

  1. Sign in to the AWS Management Console as a user with administrative permissions.

  2. Open the AWS Service Catalog console.

  3. In the navigation pane, choose Portfolios.

  4. Choose the portfolio that you created previously.

  5. On the Portfolio details page, choose the Constraints tab, and then choose Create constraint.

  6. For Product, select the Terraform product you created previously.

  7. Under Launch constraint, for Method, choose Enter role name.

  8. In the Role name box, enter SCLaunch-product.

  9. Choose Create.

AWS administrator

Grant access to the product.

  1. Open the AWS Service Catalog console.

  2. In the navigation pane, choose Portfolios.

  3. Choose the portfolio that you created previously.

  4. Choose the Access tab, and then choose Grant access.

  5. Choose the Roles tab, and then select the role that should have access to deploy this product.

  6. Choose Grant Access.

AWS administrator

Launch the product.

  1. Sign in to the AWS Management Console as a user with permissions to deploy the Service Catalog product.

  2. Open the AWS Service Catalog console.

  3. In the navigation pane, choose Products.

  4. Choose the produce you created previously, and then choose Launch product.

  5. Enter a product name and define any required parameters.

  6. Choose Launch product.

DevOps engineer
TaskDescriptionSkills required

Validate the deployment.

There are two AWS Step Functions state machines for the Service Catalog provisioning workflow:

  • ManageProvisionedProductStateMachine –Service Catalog invokes this state machine when provisioning a new Terraform product and when updating an existing Terraform provisioned product.

  • TerminateProvisionedProductStateMachine –Service Catalog invokes this state machine when terminating an existing Terraform provisioned product.

You check the logs for the ManageProvisionedProductStateMachine state machine to confirm that the product was provisioned.

  1. Sign in to the AWS Management Console, and then open the AWS Step Functions console.

  2. In the left navigation pane, choose State machines.

  3. Choose ManageProvisionedProductStateMachine.

  4. In the Executions list, enter the provisioned product ID to locate the execution.

    Note: The state file backend bucket names start with sc-terraform-engine-state-.

  5. Validate that all the required resources have been created in the account.

DevOps engineer
TaskDescriptionSkills required

Delete provisioned products.

  1. Sign in to the AWS Management Console as a user with permissions to deploy the Service Catalog product.

  2. Open the AWS Service Catalog console.

  3. In the left navigation, choose Provisioned products.

  4. Select the product you created.

  5. In the Actions list, choose Terminate.

  6. In the confirmation text box, enter terminate, and then choose Terminate provisioned product.

  7. Repeat these steps to terminate all provisioned products.

DevOps engineer

Remove the AWS Service Catalog Engine for Terraform.

  1. Sign in to the AWS Management Console as a user with administrative permissions.

  2. Open the Amazon S3 console.

  3. In the navigation pane, choose Buckets.

  4. Select the sc-terraform-engine-logging-XXXX bucket.

  5. Choose Empty.

  6. Repeat steps 4–5 for the following buckets:

    • sc-terraform-engine-state-XXXX

    • terraform-engine-bootstrap-XXXX

  7. Open the AWS CloudFormation console, and then validate you're in the correct AWS Region.

  8. In the left navigation, choose Stacks.

  9. Select SAM-TRE, and then choose Delete. Wait until the stack has been  deleted.

  10. Select Bootstrap-TRE, and then choose Delete. Wait until the stack has been deleted.

AWS administrator

Related resources

AWS documentation

Terraform documentation

Additional information

Access policy

{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": "s3:GetObject", "Resource": "*", "Condition": { "StringEquals": { "s3:ExistingObjectTag/servicecatalog:provisioning": "true" } } }, { "Action": [ "s3:CreateBucket*", "s3:DeleteBucket*", "s3:Get*", "s3:List*", "s3:PutBucketTagging" ], "Resource": "arn:aws:s3:::*", "Effect": "Allow" }, { "Action": [ "resource-groups:CreateGroup", "resource-groups:ListGroupResources", "resource-groups:DeleteGroup", "resource-groups:Tag" ], "Resource": "*", "Effect": "Allow" }, { "Action": [ "tag:GetResources", "tag:GetTagKeys", "tag:GetTagValues", "tag:TagResources", "tag:UntagResources" ], "Resource": "*", "Effect": "Allow" } ] }

Trust policy

{ "Version": "2012-10-17", "Statement": [ { "Sid": "GivePermissionsToServiceCatalog", "Effect": "Allow", "Principal": { "Service": "servicecatalog.amazonaws.com" }, "Action": "sts:AssumeRole" }, { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::account_id:root" }, "Action": "sts:AssumeRole", "Condition": { "StringLike": { "aws:PrincipalArn": [ "arn:aws:iam::accounti_id:role/TerraformEngine/TerraformExecutionRole*", "arn:aws:iam::accounti_id:role/TerraformEngine/ServiceCatalogExternalParameterParserRole*", "arn:aws:iam::accounti_id:role/TerraformEngine/ServiceCatalogTerraformOSParameterParserRole*" ] } } } ] }