Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
morga471 committed Feb 4, 2026
1 parent 0c92f76 commit 803ff77
Show file tree
Hide file tree
Showing 18 changed files with 436 additions and 0 deletions.
30 changes: 30 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Local .terraform directories
**/.terraform/*

# .tfstate files
*.tfstate
*.tfstate.*

# Crash log files
crash.log
crash.*.log

# Exclude all .tfvars files, which are likely to contain sensitive data
*.tfvars
*.tfvars.json

# Ignore override files
override.tf
override.tf.json
*_override.tf
*_override.tf.json

# Ignore CLI configuration files
.terraformrc
terraform.rc

# Ignore Mac .DS_Store files
.DS_Store

# Ignore lock files
.terraform.lock.hcl
8 changes: 8 additions & 0 deletions .pre-commit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.83.5
hooks:
- id: terraform_fmt
- id: terraform_docs
- id: terraform_validate
- id: terraform_tflint
55 changes: 55 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# AWS Service Catalog Terraform Module

This module provides a standardized way to provision and manage AWS Service Catalog products using Terraform.

## Features

- **Product Provisioning**: Provision EC2, RDS, ECS, and S3 products from existing Service Catalog portfolios
- **Lifecycle Management**: Update and terminate provisioned products
- **Service Actions**: Execute service actions (start, stop, reboot, etc.) on provisioned products
- **Automatic Discovery**: Lookup portfolios and products by naming patterns
- **Stack Outputs**: Access CloudFormation stack outputs from provisioned products

## Module Structure

- `ec2/` - Provision EC2 instances from Service Catalog
- `ec2-actions/` - Execute service actions on EC2 provisioned products
- `rds/` - Provision RDS databases from Service Catalog
- `rds-actions/` - Execute service actions on RDS provisioned products
- `ecs/` - Provision ECS services from Service Catalog
- `ecs-actions/` - Execute service actions on ECS provisioned products
- `s3/` - Provision S3 buckets from Service Catalog
- `s3-actions/` - Execute service actions on S3 provisioned products
- `common/` - Shared components and utilities

## Usage

See individual submodule README files for detailed usage examples.

### Basic EC2 Example

```hcl
module "ec2_instance" {
source = "path/to/aws-servicecatalog/ec2"
provisioned_product_name = "my-web-server"
portfolio_name_pattern = "edl-portfolio"
product_name_pattern = "linux-product"
parameters = {
InstanceType = "t3.medium"
KeyName = "my-key"
SubnetId = "subnet-12345"
}
tags = {
Environment = "production"
Team = "platform"
}
}
```

## Requirements

- Terraform >= 1.0
- AWS Provider >= 5.0
35 changes: 35 additions & 0 deletions REQUIREMENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Requirements

## Terraform Version
- Terraform >= 1.0

## Provider Requirements
- AWS Provider >= 5.0

## Permissions

The IAM role/user executing this module must have the following permissions:

### Service Catalog Permissions
- `servicecatalog:DescribePortfolio`
- `servicecatalog:ListPortfolios`
- `servicecatalog:SearchProducts`
- `servicecatalog:DescribeProduct`
- `servicecatalog:ProvisionProduct`
- `servicecatalog:UpdateProvisionedProduct`
- `servicecatalog:TerminateProvisionedProduct`
- `servicecatalog:DescribeProvisionedProduct`
- `servicecatalog:DescribeRecord`
- `servicecatalog:ExecuteProvisionedProductServiceAction`
- `servicecatalog:ListServiceActionsForProvisioningArtifact`

### Additional Permissions
- `cloudformation:DescribeStacks` - To retrieve stack outputs
- `ssm:DescribeDocument` - For service actions using SSM documents
- `ssm:StartAutomationExecution` - For executing service actions

## Prerequisites

- Existing Service Catalog portfolios must be deployed and shared with the AWS account
- User must have access to the portfolio (via principal association)
- Products must be associated with the portfolio
52 changes: 52 additions & 0 deletions ec2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# AWS Service Catalog - EC2 Module

Provisions EC2 instances from AWS Service Catalog.

## Usage

```hcl
module "ec2_instance" {
source = "path/to/aws-servicecatalog/ec2"
provisioned_product_name = "my-web-server"
portfolio_name_pattern = "edl-portfolio"
product_name_pattern = "linux-product"
parameters = {
InstanceType = "t3.medium"
KeyName = "my-key"
SubnetId = "subnet-12345"
VpcId = "vpc-12345"
}
tags = {
Environment = "production"
Application = "web"
}
}
```

## Requirements

| Name | Version |
|------|---------|
| terraform | >= 1.0 |
| aws | >= 5.0 |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| provisioned_product_name | Name of the provisioned product | `string` | n/a | yes |
| parameters | Product parameters | `map(string)` | `{}` | no |
| portfolio_name_pattern | Pattern to search for portfolio | `string` | `"edl-portfolio"` | no |
| product_name_pattern | Pattern to search for product | `string` | `"linux-product"` | no |
| tags | Additional tags | `map(string)` | `{}` | no |

## Outputs

| Name | Description |
|------|-------------|
| provisioned_product_id | The ID of the provisioned product |
| provisioned_product_arn | The ARN of the provisioned product |
| stack_outputs | CloudFormation stack outputs |
9 changes: 9 additions & 0 deletions ec2/base_settings.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
data "aws_partition" "current" {}

locals {
account_id = data.aws_caller_identity.current.account_id
region = data.aws_region.current.name
partition = data.aws_partition.current.partition
}
16 changes: 16 additions & 0 deletions ec2/base_tags.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
locals {
standard_tags = {
ManagedBy = "Terraform"
Module = local.module_name
}

enforced_tags = merge(
local.standard_tags,
var.enforced_tags
)

tags = merge(
local.enforced_tags,
var.tags
)
}
43 changes: 43 additions & 0 deletions ec2/data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Lookup portfolio by name pattern
data "aws_servicecatalog_portfolio" "this" {
count = var.portfolio_id == null ? 1 : 0

id = var.portfolio_id != null ? var.portfolio_id : null
accept_language = var.accept_language

filter {
key = "Name"
value = var.portfolio_name_pattern
}
}

# Search for product in portfolio
data "aws_servicecatalog_product" "this" {
id = var.product_id != null ? var.product_id : try(data.aws_servicecatalog_portfolio.this[0].id, null)

accept_language = var.accept_language

filter {
key = "FullTextSearch"
value = var.product_name_pattern
}
}

# Get the latest provisioning artifact (product version)
data "aws_servicecatalog_provisioning_artifacts" "this" {
accept_language = var.accept_language
product_id = data.aws_servicecatalog_product.this.id
}

# Get CloudFormation stack outputs if provisioned product exists
data "aws_cloudformation_stack" "this" {
count = var.retrieve_stack_outputs ? 1 : 0

name = format("SC-%s-%s", aws_servicecatalog_provisioned_product.this.id, aws_servicecatalog_provisioned_product.this.name)

depends_on = [aws_servicecatalog_provisioned_product.this]
}

data "aws_iam_policy_document" "empty" {
# Empty policy document for conditional logic
}
Empty file added ec2/defaults.tf
Empty file.
Empty file added ec2/locals.tf
Empty file.
59 changes: 59 additions & 0 deletions ec2/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
output "provisioned_product_id" {
description = "The ID of the provisioned product"
value = aws_servicecatalog_provisioned_product.this.id
}

output "provisioned_product_name" {
description = "The name of the provisioned product"
value = aws_servicecatalog_provisioned_product.this.name
}

output "provisioned_product_arn" {
description = "The ARN of the provisioned product"
value = aws_servicecatalog_provisioned_product.this.arn
}

output "provisioned_product_type" {
description = "The type of the provisioned product"
value = aws_servicecatalog_provisioned_product.this.type
}

output "provisioned_product_status" {
description = "The status of the provisioned product"
value = aws_servicecatalog_provisioned_product.this.status
}

output "provisioned_product_status_message" {
description = "The status message for the provisioned product"
value = aws_servicecatalog_provisioned_product.this.status_message
}

output "cloudformation_stack_arn" {
description = "The ARN of the CloudFormation stack"
value = aws_servicecatalog_provisioned_product.this.cloudformation_stack_arn
}

output "launch_role_arn" {
description = "The ARN of the launch role"
value = aws_servicecatalog_provisioned_product.this.launch_role_arn
}

output "stack_outputs" {
description = "CloudFormation stack outputs"
value = var.retrieve_stack_outputs ? try(data.aws_cloudformation_stack.this[0].outputs, {}) : {}
}

output "portfolio_id" {
description = "The ID of the portfolio used"
value = local.portfolio_id
}

output "product_id" {
description = "The ID of the product used"
value = data.aws_servicecatalog_product.this.id
}

output "provisioning_artifact_id" {
description = "The ID of the provisioning artifact used"
value = local.provisioning_artifact_id
}
Empty file added ec2/resources.tf
Empty file.
5 changes: 5 additions & 0 deletions ec2/variables.parameters.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
variable "parameters" {
description = "Parameters to pass to the Service Catalog product. Map of parameter names to values"
type = map(string)
default = {}
}
Loading

0 comments on commit 803ff77

Please sign in to comment.