Skip to content

Commit 29ed9ac

Browse files
Merge pull request #13 from fabi200123/add-iam-role
Add IAM Instance Profile as extra specs
2 parents b85b7fc + f23f1e3 commit 29ed9ac

File tree

3 files changed

+52
-34
lines changed

3 files changed

+52
-34
lines changed

README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ To this end, this provider supports the following extra specs schema:
108108
"type": "string",
109109
"description": "The name of the Key Pair to use for the instance."
110110
},
111+
"iam_instance_profile": {
112+
"type": "string",
113+
"description": "The ARN of the IAM instance profile to use for the instance."
114+
},
111115
"iops": {
112116
"type": "integer",
113117
"description": "Specifies the number of IOPS (Input/Output Operations Per Second) provisioned for the volume. Required for io1 and io2 volumes. Optional for gp3 volumes."
@@ -183,6 +187,7 @@ An example extra specs json would look like this:
183187
{
184188
"subnet_id":"subnet-0e7a29d5cf6e54789",
185189
"ssh_key_name":"Garm-test",
190+
"iam_instance_profile": "arn:aws:iam::123456789012:instance-profile/application_abc/component_xyz/Webserver",
186191
"iops": 3000,
187192
"throughput": 200,
188193
"volume_size": 50,
@@ -205,7 +210,7 @@ An example extra specs json would look like this:
205210
}
206211
```
207212

208-
*NOTE*: The `extra_context` spec adds a map of key/value pairs that may be expected in the `runner_install_template`.
213+
> **NOTE**: The `extra_context` spec adds a map of key/value pairs that may be expected in the `runner_install_template`.
209214
The `runner_install_template` allows us to completely override the script that installs and starts the runner. In the example above, I have added a copy of the current template from `garm-provider-common`, with the adition of:
210215

211216
```bash
@@ -216,7 +221,11 @@ export PATH=$PATH:/usr/local/go/bin
216221
{{- end }}
217222
```
218223
219-
*NOTE*: `runner_install_template` is a [golang template](https://pkg.go.dev/text/template), which is used to install the runner. An example on how you can extend the currently existing template with a function that downloads, extracts and installs Go on the runner is provided above.
224+
> **NOTE**: `runner_install_template` is a [golang template](https://pkg.go.dev/text/template), which is used to install the runner. An example on how you can extend the currently existing template with a function that downloads, extracts and installs Go on the runner is provided above.
225+
226+
#### **Warnings Regarding IAM Instance Profiles**
227+
228+
When configuring Garm to use [IAM Instance Profiles](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#ec2-instance-profile) for your AWS runners, it’s important to be aware of the potential security implications. IAM Instance Profiles allow the instances to assume a role with permissions that can be broadly scoped, potentially granting more access than intended. Ensure that the IAM roles associated with your instance profiles adhere to the principle of least privilege, granting only the necessary permissions required for the runners to function. This setup is recommended only for private GitHub repositories, as using it with public repositories can expose your AWS environment to additional risks. Public repositories might inadvertently allow unauthorized access to your IAM credentials or resources. Therefore, use IAM Instance Profiles with public repositories at your own risk, and consider using alternative methods to securely manage credentials and permissions. Additionally, monitor and audit the actions performed by the instances regularly to ensure no unintended access to your AWS resources occurs.
220229
221230
To set it on an existing pool, simply run:
222231

internal/client/aws.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -244,14 +244,15 @@ func (a *AwsCli) CreateRunningInstance(ctx context.Context, spec *spec.RunnerSpe
244244
}
245245

246246
resp, err := a.client.RunInstances(ctx, &ec2.RunInstancesInput{
247-
ImageId: aws.String(spec.BootstrapParams.Image),
248-
InstanceType: types.InstanceType(spec.BootstrapParams.Flavor),
249-
MaxCount: aws.Int32(1),
250-
MinCount: aws.Int32(1),
251-
SubnetId: aws.String(spec.SubnetID),
252-
SecurityGroupIds: spec.SecurityGroupIds,
253-
UserData: aws.String(udata),
254-
KeyName: spec.SSHKeyName,
247+
ImageId: aws.String(spec.BootstrapParams.Image),
248+
InstanceType: types.InstanceType(spec.BootstrapParams.Flavor),
249+
MaxCount: aws.Int32(1),
250+
MinCount: aws.Int32(1),
251+
SubnetId: aws.String(spec.SubnetID),
252+
SecurityGroupIds: spec.SecurityGroupIds,
253+
UserData: aws.String(udata),
254+
KeyName: spec.SSHKeyName,
255+
IamInstanceProfile: spec.IAMInstanceProfile,
255256
BlockDeviceMappings: []types.BlockDeviceMapping{
256257
{
257258
DeviceName: aws.String("/dev/sda1"),

internal/spec/spec.go

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,17 @@ func newExtraSpecsFromBootstrapData(data params.BootstrapInstance) (*extraSpecs,
7474
}
7575

7676
type extraSpecs struct {
77-
SubnetID *string `json:"subnet_id,omitempty" jsonschema:"pattern=^subnet-[0-9a-fA-F]{17}$,description=The ID of the subnet formatted as subnet-xxxxxxxxxxxxxxxxx."`
78-
SSHKeyName *string `json:"ssh_key_name,omitempty" jsonschema:"description=The name of the Key Pair to use for the instance."`
79-
Iops *int32 `json:"iops,omitempty" jsonschema:"description=Specifies the number of IOPS (Input/Output Operations Per Second) provisioned for the volume. Required for io1 and io2 volumes. Optional for gp3 volumes."`
80-
Throughput *int32 `json:"throughput,omitempty" jsonschema:"description=Specifies the throughput (MiB/s) provisioned for the volume. Valid only for gp3 volumes.,minimum=125,maximum=1000"`
81-
VolumeSize *int32 `json:"volume_size,omitempty" jsonschema:"description=Specifies the size of the volume in GiB. Required unless a snapshot ID is provided."`
82-
VolumeType types.VolumeType `json:"volume_type,omitempty" jsonschema:"enum=gp2,enum=gp3,enum=io1,enum=io2,enum=st1,enum=sc1,enum=standard,description=Specifies the EBS volume type."`
83-
SecurityGroupIds []string `json:"security_group_ids,omitempty" jsonschema:"description=The security group IDs to associate with the instance. Default: Amazon EC2 uses the default security group."`
84-
DisableUpdates *bool `json:"disable_updates,omitempty" jsonschema:"description=Disable automatic updates on the VM."`
85-
EnableBootDebug *bool `json:"enable_boot_debug,omitempty" jsonschema:"description=Enable boot debug on the VM."`
86-
ExtraPackages []string `json:"extra_packages,omitempty" jsonschema:"description=Extra packages to install on the VM."`
77+
SubnetID *string `json:"subnet_id,omitempty" jsonschema:"pattern=^subnet-[0-9a-fA-F]{17}$,description=The ID of the subnet formatted as subnet-xxxxxxxxxxxxxxxxx."`
78+
SSHKeyName *string `json:"ssh_key_name,omitempty" jsonschema:"description=The name of the Key Pair to use for the instance."`
79+
IAMInstanceProfile *string `json:"iam_instance_profile,omitempty jsonschema:"description=The IAM instance profile to associate with the instance."`
80+
Iops *int32 `json:"iops,omitempty" jsonschema:"description=Specifies the number of IOPS (Input/Output Operations Per Second) provisioned for the volume. Required for io1 and io2 volumes. Optional for gp3 volumes."`
81+
Throughput *int32 `json:"throughput,omitempty" jsonschema:"description=Specifies the throughput (MiB/s) provisioned for the volume. Valid only for gp3 volumes.,minimum=125,maximum=1000"`
82+
VolumeSize *int32 `json:"volume_size,omitempty" jsonschema:"description=Specifies the size of the volume in GiB. Required unless a snapshot ID is provided."`
83+
VolumeType types.VolumeType `json:"volume_type,omitempty" jsonschema:"enum=gp2,enum=gp3,enum=io1,enum=io2,enum=st1,enum=sc1,enum=standard,description=Specifies the EBS volume type."`
84+
SecurityGroupIds []string `json:"security_group_ids,omitempty" jsonschema:"description=The security group IDs to associate with the instance. Default: Amazon EC2 uses the default security group."`
85+
DisableUpdates *bool `json:"disable_updates,omitempty" jsonschema:"description=Disable automatic updates on the VM."`
86+
EnableBootDebug *bool `json:"enable_boot_debug,omitempty" jsonschema:"description=Enable boot debug on the VM."`
87+
ExtraPackages []string `json:"extra_packages,omitempty" jsonschema:"description=Extra packages to install on the VM."`
8788
cloudconfig.CloudConfigSpec
8889
}
8990

@@ -117,20 +118,21 @@ func GetRunnerSpecFromBootstrapParams(cfg *config.Config, data params.BootstrapI
117118
}
118119

119120
type RunnerSpec struct {
120-
Region string
121-
DisableUpdates bool
122-
ExtraPackages []string
123-
EnableBootDebug bool
124-
Tools params.RunnerApplicationDownload
125-
BootstrapParams params.BootstrapInstance
126-
SecurityGroupIds []string
127-
SubnetID string
128-
SSHKeyName *string
129-
Iops *int32
130-
Throughput *int32
131-
VolumeSize *int32
132-
VolumeType types.VolumeType
133-
ControllerID string
121+
Region string
122+
DisableUpdates bool
123+
ExtraPackages []string
124+
EnableBootDebug bool
125+
Tools params.RunnerApplicationDownload
126+
BootstrapParams params.BootstrapInstance
127+
SecurityGroupIds []string
128+
SubnetID string
129+
SSHKeyName *string
130+
IAMInstanceProfile *types.IamInstanceProfileSpecification
131+
Iops *int32
132+
Throughput *int32
133+
VolumeSize *int32
134+
VolumeType types.VolumeType
135+
ControllerID string
134136
}
135137

136138
func (r *RunnerSpec) Validate() error {
@@ -235,6 +237,12 @@ func (r *RunnerSpec) MergeExtraSpecs(extraSpecs *extraSpecs) {
235237
if extraSpecs.EnableBootDebug != nil {
236238
r.EnableBootDebug = *extraSpecs.EnableBootDebug
237239
}
240+
241+
if extraSpecs.IAMInstanceProfile != nil {
242+
r.IAMInstanceProfile = &types.IamInstanceProfileSpecification{
243+
Arn: extraSpecs.IAMInstanceProfile,
244+
}
245+
}
238246
}
239247

240248
func (r *RunnerSpec) ComposeUserData() (string, error) {

0 commit comments

Comments
 (0)