Skip to content

Commit fe3ebb6

Browse files
authored
Merge pull request #31 from jitsecurity/sc-30273-aws-automation-for-terraform
add aws deployment
2 parents b13b4ff + 0170e26 commit fe3ebb6

11 files changed

Lines changed: 726 additions & 0 deletions

File tree

Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
# JIT AWS Integration Automation
2+
3+
A Terraform module for automating AWS integration with JIT (Just-in-Time) security platform. This module supports both single AWS account and AWS Organization-wide integrations.
4+
5+
## Features
6+
7+
- **Dual Integration Types**: Support for both single account and organization-wide deployments
8+
- **Multi-Region Support**: Monitor multiple AWS regions simultaneously
9+
- **US/EU API Support**: Compatible with both US and EU JIT API endpoints
10+
- **Error Handling**: Built-in validation and error handling with postconditions
11+
12+
## Integration Types
13+
14+
### Single Account Integration
15+
Deploys JIT integration to a single AWS account using CloudFormation stack.
16+
17+
### Organization Integration
18+
Deploys JIT integration across an entire AWS Organization using a CloudFormation stack that creates internal StackSets, automatically including all current and future accounts in the organization.
19+
20+
## Prerequisites
21+
22+
1. **JIT API Credentials**: Client ID and Secret from JIT platform
23+
2. **AWS Permissions**: Appropriate AWS permissions for CloudFormation operations
24+
3. **Terraform**: Version 1.5 or higher
25+
4. **For Organization Integration**: AWS Organizations service must be enabled
26+
27+
## Quick Start
28+
29+
### Single Account Integration
30+
31+
```hcl
32+
module "jit_aws_account_integration" {
33+
source = "path/to/aws_integration_automation"
34+
35+
# JIT Configuration
36+
jit_client_id = var.jit_client_id
37+
jit_secret = var.jit_secret
38+
jit_region = "us" # Use "eu" for European API endpoint
39+
40+
# Integration Type
41+
integration_type = "account"
42+
43+
# AWS Configuration
44+
aws_regions_to_monitor = ["us-east-1", "us-west-2"]
45+
46+
# Stack Configuration
47+
stack_name = "JitAccountIntegration"
48+
account_name = "Production Account"
49+
resource_name_prefix = "JitProd"
50+
51+
# CloudFormation Configuration
52+
capabilities = ["CAPABILITY_NAMED_IAM"]
53+
}
54+
```
55+
56+
### Organization Integration
57+
58+
```hcl
59+
module "jit_aws_org_integration" {
60+
source = "path/to/aws_integration_automation"
61+
62+
# JIT Configuration
63+
jit_client_id = var.jit_client_id
64+
jit_secret = var.jit_secret
65+
jit_region = "us" # Use "eu" for European API endpoint
66+
67+
# Integration Type
68+
integration_type = "org"
69+
70+
# Organization Configuration
71+
organization_root_id = "r-xxxxxxxxxxxx"
72+
should_include_root_account = true
73+
74+
# AWS Configuration
75+
aws_regions_to_monitor = ["us-east-1", "us-west-2", "eu-west-1"]
76+
77+
# Stack Configuration
78+
stack_name = "JitOrgIntegration"
79+
resource_name_prefix = "JitOrg"
80+
81+
# CloudFormation Configuration
82+
capabilities = ["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM", "CAPABILITY_AUTO_EXPAND"]
83+
}
84+
```
85+
86+
## Input Variables
87+
88+
| Name | Description | Type | Default | Required |
89+
|------|-------------|------|---------|:--------:|
90+
| `jit_client_id` | Client ID for Jit API authentication | `string` | n/a | yes |
91+
| `jit_secret` | Secret for Jit API authentication | `string` | n/a | yes |
92+
| `integration_type` | Type of AWS integration (`account` or `org`) | `string` | n/a | yes |
93+
| `jit_region` | Jit API region (`us` or `eu`) | `string` | `"us"` | no |
94+
| `aws_regions_to_monitor` | List of AWS regions to monitor | `list(string)` | `["us-east-1"]` | no |
95+
| `stack_name` | Name for the CloudFormation stack | `string` | `"JitIntegrationStack"` | no |
96+
| `account_name` | Optional account name alias for Jit platform | `string` | `""` | no |
97+
| `resource_name_prefix` | Prefix for CloudFormation resources (1-40 chars, alphanumeric, hyphens, underscores) | `string` | `null` (auto: "Jit" for account, "JitOrg" for org) | no |
98+
| `organization_root_id` | AWS Organization Root ID (required for org type, format: `r-xxxxxxxxxx`) | `string` | `""` | no |
99+
| `should_include_root_account` | Include root account in organization integration | `bool` | `false` | no |
100+
| `capabilities` | CloudFormation capabilities required | `list(string)` | `["CAPABILITY_NAMED_IAM"]` | no |
101+
102+
## State Token Management
103+
104+
This module implements a **create-only** behavior for the JIT oauth/state-token endpoint using the REST API provider:
105+
106+
1. **First Run**: Creates a new state token via JIT API
107+
2. **Subsequent Runs**: Reuses the existing state token from Terraform state
108+
3. **No Updates**: The state token is never updated or regenerated unless explicitly recreated
109+
110+
### State Token Implementation
111+
112+
The module uses the `restapi_object` resource for state token management:
113+
114+
- Creates state token via JIT API endpoint `/oauth/state-token`
115+
- Stores token in Terraform state automatically
116+
- Uses `ignore_changes` lifecycle rule to prevent updates
117+
118+
### Important Notes
119+
120+
- State token is managed entirely within Terraform state
121+
- Token persists across Terraform runs and is only created once
122+
- To regenerate a state token, you must manually destroy and recreate the `restapi_object.jit_state_token` resource along with the created AWS stack.
123+
- **External ID Persistence**: The state token (external_id) should be created only once. Changing AWS regions, account configurations, or other integration parameters will not affect the existing integration's configuration or regenerate the token
124+
- **External ID Uniqueness**: The external_id is generated by JIT and cannot be reused across integrations. After a successful integration, changing or regenerating the external_id value will cause issues with the existing integration and may break the connection between JIT and your AWS environment
125+
126+
## CloudFormation Templates
127+
128+
The module automatically selects the appropriate CloudFormation template:
129+
130+
- **Account Integration**: `https://jit-aws-prod.s3.amazonaws.com/jit_aws_integration_stack.json`
131+
- **Organization Integration**: `https://jit-aws-prod.s3.amazonaws.com/jit_aws_org_integration_stack.json`
132+
133+
## Required Capabilities
134+
135+
### Single Account Integration
136+
```terraform
137+
capabilities = ["CAPABILITY_NAMED_IAM"]
138+
```
139+
140+
### Organization Integration
141+
```terraform
142+
capabilities = ["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM", "CAPABILITY_AUTO_EXPAND"]
143+
```
144+
145+
The organization integration requires additional capabilities because:
146+
- `CAPABILITY_AUTO_EXPAND`: For creating nested stacks and StackSets within the CloudFormation template
147+
- `CAPABILITY_IAM`: For creating IAM resources
148+
- `CAPABILITY_NAMED_IAM`: For creating IAM resources with custom names
149+
150+
## Resource Name Prefix
151+
152+
The `resource_name_prefix` parameter controls the prefix used for CloudFormation resources:
153+
154+
- **Default for Account Integration**: "Jit"
155+
- **Default for Organization Integration**: "JitOrg"
156+
- **Custom Prefix**: Provide your own prefix (1-40 characters, alphanumeric, hyphens, underscores only)
157+
- **Validation**: The module validates the prefix format automatically
158+
159+
## API Endpoints
160+
161+
The module supports both JIT API regions:
162+
163+
- **US Region**: `https://api.jit.io` (default)
164+
- **EU Region**: `https://api.eu.jit.io`
165+
166+
## Error Handling
167+
168+
The module includes comprehensive error handling:
169+
170+
- **Authentication Validation**: Ensures JIT API authentication succeeds with postconditions
171+
- **Input Validation**: Validates required parameters and formats using Terraform validation blocks
172+
- **Integration Type Validation**: Ensures integration_type is either "account" or "org"
173+
- **Region Validation**: Ensures jit_region is either "us" or "eu"
174+
- **Organization Root ID Validation**: Validates proper format for organization root IDs
175+
- **Lifecycle Management**: Prevents accidental destruction of resources
176+
177+
## Complete Working Examples
178+
179+
The `examples/` directory contains complete working examples organized by integration type:
180+
181+
### Single Account Integration
182+
- **Directory**: [`examples/single_account/`](examples/single_account/)
183+
- **Main File**: `account_integration.tf`
184+
- **Variables**: `variables.tf`
185+
- **Configuration**: `terraform.tfvars`
186+
187+
To use the single account example:
188+
```bash
189+
cd examples/single_account/
190+
cp terraform.tfvars.example terraform.tfvars
191+
# Edit terraform.tfvars with your values
192+
terraform init
193+
terraform plan
194+
terraform apply
195+
```
196+
197+
### Organization Integration
198+
- **Directory**: [`examples/aws_organization/`](examples/aws_organization/)
199+
- **Main File**: `organization_integration.tf`
200+
- **Variables**: `variables.tf`
201+
- **Configuration**: `terraform.tfvars`
202+
203+
To use the organization example:
204+
```bash
205+
cd examples/aws_organization/
206+
cp terraform.tfvars.example terraform.tfvars
207+
# Edit terraform.tfvars with your values
208+
terraform init
209+
terraform plan
210+
terraform apply
211+
```
212+
213+
## How Organization Integration Works
214+
215+
The organization integration creates a **single CloudFormation stack** that internally:
216+
217+
1. **Creates an IAM Role** for JIT to assume across the organization
218+
2. **Creates a StackSet** (`JitOrganizationsStacksSetRocket`) that automatically deploys to all accounts in the organization
219+
3. **Optionally creates a stack** in the root account if `should_include_root_account = true`
220+
221+
The CloudFormation template handles the StackSet creation and deployment automatically using AWS Organizations' `SERVICE_MANAGED` permission model.
222+
223+
## Security Considerations
224+
225+
1. **Sensitive Variables**: `jit_client_id`, `jit_secret`, and `organization_root_id` are marked as sensitive
226+
2. **State Files**: Ensure Terraform state files are stored securely (e.g., S3 with encryption)
227+
3. **State Token**: Stored in Terraform state - secure your state backend appropriately
228+
4. **IAM Permissions**: Follow principle of least privilege for AWS IAM permissions
229+
230+
## Troubleshooting
231+
232+
### Common Issues
233+
234+
1. **Authentication Failure**
235+
- Verify JIT client ID and secret are correct
236+
- Check if the correct JIT region is specified
237+
238+
2. **Organization Root ID Error**
239+
- Ensure the organization root ID is in the correct format (`r-xxxxxxxxxxxx`)
240+
- Verify AWS Organizations is enabled and accessible
241+
242+
3. **CloudFormation Capabilities Error**
243+
- For organization integration, ensure you have all three capabilities: `["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM", "CAPABILITY_AUTO_EXPAND"]`
244+
- For single account integration, use: `["CAPABILITY_NAMED_IAM"]`
245+
246+
4. **CloudFormation Stack Errors**
247+
- Verify AWS permissions for CloudFormation operations
248+
- Check CloudFormation events in the AWS console for detailed error messages
249+
- For organization integration, ensure AWS Organizations service is properly configured
250+
251+
5. **Parameter Validation Errors**
252+
- Verify `resource_name_prefix` meets length and character requirements (1-40 chars, alphanumeric, hyphens, underscores)
253+
- Check that `organization_root_id` follows the correct pattern (`r-` followed by 4-32 alphanumeric characters)
254+
- Ensure `integration_type` is exactly "account" or "org"
255+
- Ensure `jit_region` is exactly "us" or "eu"
256+
257+
### Debug Information
258+
259+
Enable Terraform debug logging for detailed troubleshooting:
260+
261+
```bash
262+
export TF_LOG=DEBUG
263+
terraform apply
264+
```
265+
266+
## Requirements
267+
268+
| Name | Version |
269+
|------|---------|
270+
| terraform | >= 1.5 |
271+
| aws | >= 5.0 |
272+
| http | >= 3.0 |
273+
| local | >= 2.0 |
274+
| restapi | >= 1.19.1 |
275+
276+
## Contributing
277+
278+
1. Follow existing code patterns and documentation standards
279+
2. Test changes with both integration types using the provided examples
280+
3. Update examples and documentation as needed
281+
4. Ensure all variables have proper validation where applicable
282+
283+
## License
284+
285+
This module is part of the JIT customer scripts repository. Please refer to the main repository license for usage terms.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Example: AWS Organization Integration with Jit
2+
# This example shows how to integrate an entire AWS organization with Jit
3+
4+
terraform {
5+
required_version = ">= 1.5"
6+
7+
required_providers {
8+
aws = {
9+
source = "hashicorp/aws"
10+
version = ">= 5.0"
11+
}
12+
}
13+
}
14+
15+
# Configure the AWS Provider
16+
provider "aws" {
17+
region = var.aws_region
18+
}
19+
20+
# Organization Integration Module
21+
module "jit_aws_org_integration" {
22+
source = "../../"
23+
24+
# Jit API Configuration
25+
jit_client_id = var.jit_client_id # Set via environment variable or terraform.tfvars
26+
jit_secret = var.jit_secret # Set via environment variable or terraform.tfvars
27+
jit_region = "us" # Use "eu" for European API endpoint
28+
29+
# Integration Configuration
30+
integration_type = "org"
31+
aws_regions_to_monitor = var.regions_to_monitor
32+
33+
# Organization Configuration
34+
organization_root_id = var.organization_root_id # Your AWS Organization Root ID
35+
should_include_root_account = var.should_include_root_account # Whether to include the management account
36+
37+
# Stack Configuration
38+
stack_name = "JitOrgIntegration"
39+
resource_name_prefix = var.resource_name_prefix # Optional: Prefix for CloudFormation resources
40+
41+
# CloudFormation Configuration
42+
capabilities = ["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM", "CAPABILITY_AUTO_EXPAND"]
43+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# JIT API Credentials
2+
# Follow the guide here - https://docs.jit.io/reference/credentials
3+
# Create creds using "Engineering Manager" role
4+
jit_client_id = "JIT_API_KEY_CLIENT_ID"
5+
jit_secret = "JIT_API_KEY_SECRET"
6+
7+
# Should manage also the root account in Jit (false to avoid it)
8+
should_include_root_account = true
9+
10+
# The organization's root ID - can be obtained under AWS Organizations -> AWS Accounts
11+
organization_root_id = "r-xxxx"
12+
13+
# AWS regions to monitor using Jit
14+
regions_to_monitor = ["us-east-1", "us-west-2"]
15+
16+
# AWS region to deploy the integration to
17+
aws_region = "us-east-1"
18+
19+
# Prefix for the resource name
20+
resource_name_prefix = "JitOrg"
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
2+
# Variables that should be defined in your root module or terraform.tfvars
3+
variable "jit_client_id" {
4+
description = "Jit API Client ID"
5+
type = string
6+
sensitive = true
7+
}
8+
9+
variable "jit_secret" {
10+
description = "Jit API Secret"
11+
type = string
12+
sensitive = true
13+
}
14+
15+
variable "organization_root_id" {
16+
description = "AWS Organization Root ID"
17+
type = string
18+
sensitive = true
19+
}
20+
21+
variable "should_include_root_account" {
22+
description = "Whether to include the root account in the monitoring."
23+
type = bool
24+
default = false
25+
}
26+
27+
variable "regions_to_monitor" {
28+
description = "AWS regions to monitor using Jit"
29+
type = list(string)
30+
}
31+
32+
variable "aws_region" {
33+
description = "AWS region to deploy the integration to"
34+
type = string
35+
}
36+
37+
variable "resource_name_prefix" {
38+
description = "Prefix for the resource name"
39+
type = string
40+
default = "JitOrg"
41+
}

0 commit comments

Comments
 (0)