Skip to content

Commit 39245ab

Browse files
authored
Merge pull request #1 from rhythmictech/init
init
2 parents 189efff + 9ffafb7 commit 39245ab

9 files changed

+432
-0
lines changed

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
# .tfvars files
99
*.tfvars
10+
!example/**/*.tfvars
1011

1112
# pem files
1213
*.pem

Diff for: cloudformation.yml.tpl

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
Resources:
2+
distConfig:
3+
Type: AWS::ImageBuilder::DistributionConfiguration
4+
Properties:
5+
Name: ${name} - Distribution Config
6+
%{~ if description != null ~}
7+
Description: ${description}
8+
%{~ endif ~}
9+
Distributions:
10+
%{~ for region in regions ~}
11+
- AmiDistributionConfiguration:
12+
Name: '${name} - AmiCopyConfiguration - {{ imagebuilder:buildDate }}'
13+
%{~ if description != null ~}
14+
Description: ${description}
15+
%{~ endif ~}
16+
AmiTags:
17+
${ indent(14, chomp(yamlencode(tags))) }
18+
%{~ if shared_account_ids != null ~}
19+
LaunchPermissionConfiguration:
20+
UserIds:
21+
${ indent(14, chomp(yamlencode(shared_account_ids))) }
22+
%{~ endif ~}
23+
%{~ if license_config_arns != null ~}
24+
LicenseConfigurationArns:
25+
${ indent(12, chomp(yamlencode(license_config_arns)))}
26+
%{~ endif ~}
27+
Region: ${region}
28+
%{~ endfor ~}
29+
Tags:
30+
${ indent(8, chomp(yamlencode(tags))) }
31+
infraConfig:
32+
Type: AWS::ImageBuilder::InfrastructureConfiguration
33+
Properties:
34+
Name: ${name}-infrastructure-configuration
35+
%{~ if description != null ~}
36+
Description: ${description}
37+
%{~ endif ~}
38+
InstanceProfileName: ${instance_profile}
39+
%{~ if instance_types != null ~}
40+
InstanceTypes:
41+
${ indent(8, chomp(yamlencode(instance_types))) }
42+
%{~ endif ~}
43+
%{~ if key_pair != null ~}
44+
KeyPair: ${key_pair}
45+
%{~ endif ~}
46+
%{~ if log_bucket != null ~}
47+
Logging:
48+
S3Logs:
49+
S3BucketName: ${log_bucket}
50+
%{~ if log_prefix != null ~}
51+
S3KeyPrefix: ${log_prefix}
52+
%{~ endif ~}
53+
%{~ endif ~}
54+
%{~ if security_group_ids != null ~}
55+
SecurityGroupIds:
56+
${ indent(8, chomp(yamlencode(security_group_ids))) }
57+
%{~ endif ~}
58+
%{~ if sns_topic_arn != null ~}
59+
SnsTopicArn: ${sns_topic_arn}
60+
%{~ endif ~}
61+
%{~ if subnet != null ~}
62+
SubnetId: ${subnet}
63+
%{~ endif ~}
64+
Tags:
65+
${ indent(8, chomp(yamlencode(tags))) }
66+
TerminateInstanceOnFailure: ${terminate_on_failure}
67+
imageBuildPipeline:
68+
Type: AWS::ImageBuilder::ImagePipeline
69+
Properties:
70+
Name: ${name}
71+
%{~ if description != null ~}
72+
Description: ${description}
73+
%{~ endif ~}
74+
DistributionConfigurationArn: !Ref "distConfig"
75+
ImageRecipeArn: ${recipe_arn}
76+
ImageTestsConfiguration:
77+
${ indent(8, chomp(yamlencode(test_config))) }
78+
InfrastructureConfigurationArn: !Ref "infraConfig"
79+
Schedule:
80+
${ indent(8, chomp(yamlencode(schedule))) }
81+
Status: ${status}
82+
Tags:
83+
${ indent(8, chomp(yamlencode(tags))) }
84+
Outputs:
85+
PipelineArn:
86+
Description: ARN of the created component
87+
Value: !Ref "imageBuildPipeline"

Diff for: example/basic/common.tf

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
##################################################
2+
# Provider/Backend/Workspace Check
3+
##################################################
4+
provider "aws" {
5+
region = var.region
6+
}
7+
8+
terraform {
9+
required_version = ">= 0.12.25"
10+
required_providers {
11+
aws = "~> 2.61.0"
12+
}
13+
}
14+
15+
variable "owner" {
16+
description = "Team/person responsible for resources defined within this project"
17+
type = string
18+
}
19+
20+
variable "region" {
21+
description = "Region resources are being deployed to"
22+
type = string
23+
}

Diff for: example/basic/global.auto.tfvars

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
# Project defaults
3+
region = "us-east-1"
4+
owner = "test"
5+

Diff for: example/basic/main.tf

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
data "aws_caller_identity" "current" {
2+
}
3+
4+
locals {
5+
account_id = data.aws_caller_identity.current.account_id
6+
tags = module.tags.tags_no_name
7+
}
8+
9+
module "tags" {
10+
source = "git::https://github.com/rhythmictech/terraform-terraform-tags.git?ref=v1.0.0"
11+
12+
names = [
13+
"smiller",
14+
"imagebuilder-test"
15+
]
16+
17+
tags = merge({
18+
"Env" = "test"
19+
"Namespace" = "smiller"
20+
"notes" = "Testing only - Can be safely deleted"
21+
"Owner" = var.owner
22+
}, var.additional_tags)
23+
}
24+
25+
module "test_component" {
26+
source = "git::https://github.com/rhythmictech/terraform-aws-imagebuilder-component-ansible.git?ref=v0.1.0"
27+
28+
component_version = "1.0.0"
29+
description = "Testing component"
30+
name = "testing-component"
31+
playbook_dir = "packer-generic-images/base"
32+
playbook_repo = "https://github.com/rhythmictech/packer-generic-images.git"
33+
tags = local.tags
34+
}
35+
36+
module "test_recipe" {
37+
source = "git::https://github.com/rhythmictech/terraform-aws-imagebuilder-recipe.git?ref=v0.1.0"
38+
39+
description = "Testing recipe"
40+
name = "test-recipe"
41+
parent_image = "arn:aws:imagebuilder:us-east-1:aws:image/amazon-linux-2-x86/x.x.x"
42+
recipe_version = "1.0.0"
43+
tags = local.tags
44+
update = true
45+
46+
component_arns = [
47+
module.test_component.component_arn,
48+
"arn:aws:imagebuilder:us-east-1:aws:component/simple-boot-test-linux/1.0.0/1",
49+
"arn:aws:imagebuilder:us-east-1:aws:component/reboot-test-linux/1.0.0/1"
50+
]
51+
}
52+
53+
module "test_pipeline" {
54+
source = "../../"
55+
56+
description = "Testing pipeline"
57+
name = "test-pipeline"
58+
tags = local.tags
59+
recipe_arn = module.test_recipe.recipe_arn
60+
}

Diff for: example/basic/variables.tf

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
########################################
2+
# General Vars
3+
########################################
4+
variable "additional_tags" {
5+
default = {}
6+
description = "Additional tags to add to supported resources"
7+
type = map(string)
8+
}

Diff for: main.tf

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
locals {
2+
log_prefix_computed = (
3+
var.log_prefix != null
4+
? replace("/${var.log_prefix}/*", "//{2,}/", "/")
5+
: "/*"
6+
)
7+
}
8+
9+
data "aws_iam_policy_document" "log_write" {
10+
count = var.log_bucket != null ? 1 : 0
11+
12+
statement {
13+
actions = ["s3:PutObject"]
14+
resources = ["arn:aws:s3:::${var.log_bucket}${local.log_prefix_computed}"]
15+
}
16+
}
17+
18+
resource "aws_iam_policy" "log_write" {
19+
count = var.log_bucket != null ? 1 : 0
20+
21+
description = "IAM policy granting write access to the logging bucket for ${var.name}"
22+
name_prefix = "${var.name}-logging-policy-"
23+
policy = data.aws_iam_policy_document.log_write[count.index].json
24+
}
25+
26+
locals {
27+
core_iam_policies = [
28+
"arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore",
29+
"arn:aws:iam::aws:policy/EC2InstanceProfileForImageBuilder"
30+
]
31+
iam_policies = concat(
32+
local.core_iam_policies,
33+
aws_iam_policy.log_write[*].arn,
34+
var.additional_iam_policy_arns
35+
)
36+
}
37+
38+
data "aws_iam_policy_document" "assume" {
39+
statement {
40+
actions = ["sts:AssumeRole"]
41+
42+
principals {
43+
type = "Service"
44+
identifiers = ["ec2.amazonaws.com"]
45+
}
46+
}
47+
}
48+
49+
resource "aws_iam_role" "this" {
50+
assume_role_policy = data.aws_iam_policy_document.assume.json
51+
name_prefix = "${var.name}-imagebuilder-role-"
52+
53+
tags = merge(
54+
var.tags,
55+
{
56+
Name : "${var.name}-imagebuilder-role"
57+
}
58+
)
59+
}
60+
61+
resource "aws_iam_role_policy_attachment" "this" {
62+
count = (
63+
var.log_bucket == null
64+
? length(local.core_iam_policies) + length(var.additional_iam_policy_arns)
65+
: length(local.core_iam_policies) + length(var.additional_iam_policy_arns) + 1
66+
)
67+
68+
policy_arn = local.iam_policies[count.index]
69+
role = aws_iam_role.this.name
70+
}
71+
72+
resource "aws_iam_instance_profile" "this" {
73+
name_prefix = "${var.name}-imagebuilder-instance-profile-"
74+
role = aws_iam_role.this.name
75+
}
76+
77+
resource "aws_cloudformation_stack" "this" {
78+
name = var.name
79+
on_failure = "ROLLBACK"
80+
timeout_in_minutes = var.cloudformation_timeout
81+
82+
tags = merge(
83+
var.tags,
84+
{ Name : "${var.name}-stack" }
85+
)
86+
87+
template_body = templatefile("${path.module}/cloudformation.yml.tpl", {
88+
description = var.description
89+
instance_profile = aws_iam_instance_profile.this.name
90+
instance_types = var.instance_types
91+
key_pair = var.key_pair
92+
license_config_arns = var.license_config_arns
93+
log_bucket = var.log_bucket
94+
log_prefix = var.log_prefix
95+
name = var.name
96+
recipe_arn = var.recipe_arn
97+
regions = var.regions
98+
schedule = var.schedule
99+
security_group_ids = var.security_group_ids
100+
shared_account_ids = var.shared_account_ids
101+
sns_topic_arn = var.sns_topic_arn
102+
status = var.enabled ? "ENABLED" : "DISABLED"
103+
subnet = var.subnet
104+
terminate_on_failure = var.terminate_on_failure
105+
test_config = var.test_config
106+
107+
tags = merge(
108+
var.tags,
109+
{ Name : var.name }
110+
)
111+
})
112+
}

Diff for: outputs.tf

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
output "pipeline_arn" {
2+
value = aws_cloudformation_stack.this.outputs["PipelineArn"]
3+
}

0 commit comments

Comments
 (0)