Skip to content

Commit

Permalink
create windows module
Browse files Browse the repository at this point in the history
  • Loading branch information
morga471 committed Mar 3, 2026
1 parent 7947e47 commit 09b4be7
Show file tree
Hide file tree
Showing 22 changed files with 612 additions and 0 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
244 changes: 244 additions & 0 deletions modules/ec2/windows/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
# Service Catalog EC2 Module

## Overview

This module provisions EC2 instances via AWS Service Catalog. It provides a simplified Terraform interface to the Service Catalog EC2 product, handling all the complexity of parameter mapping, networking lookups, and provisioning.

This is a product-specific wrapper around the base [`product`](../product/) module, adding EC2-specific parameters and defaults.

## Features

- **Simplified Interface**: Clean Terraform variables instead of raw Service Catalog parameters
- **Automatic VPC/Subnet Resolution**: Looks up VPC and subnet information by name tags
- **Latest Version by Default**: Automatically uses the latest active provisioning artifact
- **Flexible Parameter Override**: Pass additional parameters via the `parameters` variable
- **Standard Tagging**: Consistent tagging across all resources
- **EC2-Specific Validations**: Built-in validation for EC2 parameters

## Usage

### Basic Example

```hcl
module "ec2_instance" {
source = "git::https://your-repo/terraform-modules/aws-servicecatalog//modules/ec2?ref=v1.0.0"
# Service Catalog Configuration
portfolio_id = "port-pgj3zvoqca7ya"
product_id = "prod-43foqxjcq5isw"
# Instance Identity
provisioned_product_name = "app-web-01"
project_name = "csvd_myproject_dev-229685449397"
# Networking
vpc_name = "vpc-dev-us-east-1"
subnets_name = "*-apps-*"
# EC2 Configuration
instance_type = "t3a.medium"
os_name = "RHEL9"
power_schedule = "Weekday_Core_Hours_7-7"
requires_backup = "yes"
# Contact Information
creator = "jsmith"
contact_email = "jsmith@example.com"
inc_poc_email = "team@example.com"
fisma_id = "OCIO_CSVD (CEN16.09)"
tags = {
Environment = "dev"
Application = "web-server"
}
}
```

### Advanced Example with Custom Parameters

```hcl
module "ec2_instance" {
source = "git::https://your-repo/terraform-modules/aws-servicecatalog//modules/ec2?ref=v1.0.0"
portfolio_id = "port-pgj3zvoqca7ya"
product_id = "prod-43foqxjcq5isw"
provisioned_product_name = "app-db-01"
project_name = "csvd_database_prod-229685449397"
vpc_name = "vpc-prod-us-east-1"
subnets_name = "subnet-data-*"
instance_type = "r5.xlarge"
os_name = "RHEL9"
power_schedule = "24x7"
requires_backup = "yes"
creator = "dbadmin"
contact_email = "dbadmin@example.com"
inc_poc_email = "dba-team@example.com"
fisma_id = "OCIO_DATA (DAT01.01)"
# Custom parameters not covered by named variables
parameters = {
VolumeAppsSize = "200"
SecurityGroupNames = "sg-database,sg-monitoring"
pDescription = "Production database server"
Volume1Mount = "/data01"
Volume1Size = "500"
}
# Service Catalog Options
timeout = "30m"
notification_arns = ["arn:aws:sns:us-east-1:123456789012:sc-notifications"]
retain_physical_resources = true
tags = {
Environment = "prod"
Application = "database"
CostCenter = "engineering"
}
}
```

## Requirements

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

## Providers

No providers are used directly - all AWS resources are provisioned by the underlying `product` module.

## Variables

### Required Variables

| Name | Description | Type |
|------|-------------|------|
| `provisioned_product_name` | Name of the provisioned product (1-128 characters) | `string` |

### Service Catalog Configuration

| Name | Description | Type | Default |
|------|-------------|------|---------|
| `portfolio_id` | Portfolio ID containing the EC2 product | `string` | `"port-pgj3zvoqca7ya"` |
| `product_id` | Product ID for the EC2 product | `string` | `"prod-43foqxjcq5isw"` |
| `path_id` | Path identifier (version). Uses latest if not provided | `string` | `null` |
| `timeout` | Timeout for provisioning operations | `string` | `"15m"` |
| `accept_language` | Language code for API calls | `string` | `"en"` |
| `ignore_errors` | Ignore errors during provisioning | `bool` | `false` |
| `notification_arns` | SNS topic ARNs for notifications | `list(string)` | `[]` |
| `retain_physical_resources` | Retain resources when deleted | `bool` | `false` |
| `stack_set_provisioning_preferences` | StackSet preferences | `object` | `null` |

### EC2 Configuration

| Name | Description | Type | Default |
|------|-------------|------|---------|
| `instance_type` | EC2 instance type | `string` | `"t3.small"` |
| `os_name` | Operating system version | `string` | `"RHEL9"` |
| `requires_backup` | Backup requirement (yes/no) | `string` | `"no"` |
| `power_schedule` | Power schedule name | `string` | `""` |

### Common Parameters

| Name | Description | Type | Default |
|------|-------------|------|---------|
| `project_name` | Project name (must end with account ID) | `string` | `""` |
| `creator` | Creator's JBID | `string` | `""` |
| `contact_email` | Provisioning user's email | `string` | `""` |
| `inc_poc_email` | Incident POC email | `string` | `""` |
| `fisma_id` | FISMA ID | `string` | `""` |

### Networking

| Name | Description | Type | Default |
|------|-------------|------|---------|
| `vpc_name` | Name tag of the VPC | `string` | `""` |
| `subnets_name` | Name tag pattern for subnets | `string` | `"*-apps-*"` |

### Other

| Name | Description | Type | Default |
|------|-------------|------|---------|
| `parameters` | Additional Service Catalog parameters | `map(string)` | `{}` |
| `tags` | Tags to apply to the provisioned product | `map(string)` | `{}` |

## Outputs

| Name | Description |
|------|-------------|
| `provisioned_product_id` | The ID of the provisioned product |
| `provisioned_product_name` | The name of the provisioned product |
| `provisioned_product_arn` | The ARN of the provisioned product |
| `provisioned_product_type` | The type of the provisioned product |
| `provisioned_product_status` | The status of the provisioned product |
| `provisioned_product_status_message` | The status message |
| `launch_role_arn` | The ARN of the launch role |
| `portfolio_id` | The ID of the portfolio used |
| `product_id` | The ID of the product used |
| `provisioning_artifact_id` | The ID of the provisioning artifact used |
| `vpc_id` | The VPC ID where the instance is provisioned |
| `availability_zone` | The availability zone used |
| `availability_zone_names` | List of all availability zone names |
| `availability_zone_ids` | List of all availability zone IDs |
| `availability_zone_suffixes` | List of availability zone suffixes |

## Module Architecture

This module is built on top of the generic [`product`](../product/) module:

```
ec2 module (this)
product module (base Service Catalog logic)
AWS Service Catalog
CloudFormation Stack (EC2 instance)
```

The `ec2` module:
1. Accepts EC2-specific variables
2. Maps them to Service Catalog parameters
3. Passes them to the `product` module via `product_parameters`
4. Exposes outputs from the `product` module

## Parameter Mapping

The module automatically maps Terraform variables to Service Catalog parameters:

| Terraform Variable | Service Catalog Parameter |
|-------------------|---------------------------|
| `provisioned_product_name` | `NameTag` |
| `project_name` | `ProjectName` |
| `creator` | `Creator` |
| `contact_email` | `ContactEmail` |
| `inc_poc_email` | `IncPocEmail` |
| `fisma_id` | `FISMAID` |
| `instance_type` | `InstanceType` |
| `os_name` | `OSName` |
| `requires_backup` | `RequiresBackup` |
| `power_schedule` | `PowerSchedule` |
| `vpc_name` | Resolved to `VpcId` |
| `subnets_name` | Resolved to `AZName` |

Additional parameters can be passed via the `parameters` variable, which will override any defaults.

## Notes

- The `project_name` must end with the AWS account ID (last 12 digits)
- VPC and subnet lookups are performed automatically based on name tags
- The module uses the latest active provisioning artifact by default unless `path_id` is specified
- All resources created by Service Catalog are managed by CloudFormation
- Deleting the Terraform resource will delete the CloudFormation stack unless `retain_physical_resources = true`

## Examples

See the [examples/ec2/](../../examples/ec2/) directory for complete working examples.

## Support

For issues or questions, please refer to the main [aws-servicecatalog module documentation](../../README.md).
36 changes: 36 additions & 0 deletions modules/ec2/windows/data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
data "aws_vpc" "vpc" {
count = var.vpc_name != "" ? 1 : 0
filter {
name = "tag:Name"
values = [var.vpc_name]
}
}

# Get all subnets matching name and VPC ID
data "aws_subnets" "subnets" {
count = var.vpc_name != "" && var.subnets_name != "" ? 1 : 0
filter {
name = "tag:Name"
values = [var.subnets_name]
}
filter {
name = "vpc-id"
values = [data.aws_vpc.vpc[0].id]
}
}

# get ids for each subnet for use in provisioning
data "aws_subnet" "subnets" {
for_each = var.vpc_name != "" && var.subnets_name != "" ? toset(data.aws_subnets.subnets[0].ids) : []
id = each.key
}

data "aws_availability_zones" "zones" {
state = "available"
}

data "aws_availability_zone" "zone" {
for_each = toset(data.aws_availability_zones.zones.names)
state = "available"
name = each.key
}
38 changes: 38 additions & 0 deletions modules/ec2/windows/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
locals {
# EC2-specific parameters to pass to the product module
ec2_parameters = merge(
{
InstanceType = var.instance_type
OSName = var.os_name
RequiresBackup = var.requires_backup
PowerSchedule = var.power_schedule
},
var.parameters # Allow user to override any parameter
)

# VPC and networking - only resolve if vpc_name is provided
vpc_id = var.vpc_name != "" ? data.aws_vpc.vpc[0].id : null
az_name = var.vpc_name != "" && var.subnets_name != "" && length(data.aws_subnets.subnets[0].ids) > 0 ? data.aws_subnet.subnets[sort(data.aws_subnets.subnets[0].ids)[0]].availability_zone : null

# Add networking parameters if available
network_parameters = local.vpc_id != null ? {
VpcId = local.vpc_id
AZName = local.az_name
} : {}

parameters = merge(
local.network_parameters,
local.ec2_parameters
)

base_tags = {
"boc:tf_module_name" = local.module_name
"boc:tf_module_version" = local.module_version
"boc:created_by" = "terraform"
}

tags = merge(
local.base_tags,
var.tags
)
}
33 changes: 33 additions & 0 deletions modules/ec2/windows/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# EC2 Product Module
#
# Provisions an EC2 instance via Service Catalog
# This is a thin wrapper around the product module with EC2-specific parameters

module "ec2" {
source = "../product"

# Service Catalog configuration
portfolio_id = var.portfolio_id
product_id = var.product_id
path_id = var.path_id
accept_language = var.accept_language
timeout = var.timeout
ignore_errors = var.ignore_errors
notification_arns = var.notification_arns
retain_physical_resources = var.retain_physical_resources
stack_set_provisioning_preferences = var.stack_set_provisioning_preferences

# Common parameters
provisioned_product_name = var.provisioned_product_name
project_name = var.project_name
creator = var.creator
contact_email = var.contact_email
inc_poc_email = var.inc_poc_email
fisma_id = var.fisma_id

# EC2-specific + networking parameters (merged in locals.tf)
product_parameters = local.parameters

# Tags
tags = local.tags
}
4 changes: 4 additions & 0 deletions modules/ec2/windows/module_name.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
locals {
module_name = "aws-servicecatalog/ec2"
module_version = "0.0.0"
}
Loading

0 comments on commit 09b4be7

Please sign in to comment.