This is a Terraform module to configure GitLab as an IAM OIDC identity provider in AWS. It enables GitLab to access resources within an AWS account without requiring AWS credentials.
Name | Version |
---|---|
terraform | ~> 1.0 |
aws | ~> 4.0 |
tls | 3.3.0 |
The following snippet shows the minimum required configuration to create a working OIDC connection between GitLab and AWS.
provider "aws" {
region = var.aws_region
}
module "aws_oidc_gitlab" {
for_each = var.gitlab
source = "../../"
iam_role_name = "gitlab_action_oidc_aws"
attach_admin_policy = true
create_oidc_provider = true
iam_policy_arns = []
gitlab_url = "https://gitlab.com"
audience = "https://gitlab.com"
match_field = each.value.match_field
match_value = each.value.match_value
}
-
attach_admin_policy
is the flag to enable or disable the attachment of the AdministratorAccess policy to the IAM role. aws_managed_policy_arns
is a list of AWS Managed IAM policy ARNs to attach to the IAM role such as S3FullAccessgitlab_url
is the address of your GitLab instance, such as https://gitlab.com or http://gitlab.example.com.audience
is the same asgitlab_url
match_value
It should be your Gitlab Instance URl such as https://gitlab.example.com or a filter to a specific gitlab group, branch or tag such as project_path:mygroup/myproject:ref_type:branch:ref:main.match_field
If you use a filter to specific GitLab group, branch or tag asmatch_value
, usesub
. Useaud
if you use GitLab instance url such as https://gitlab.com asmatch_value
By default, any GitLab user would be able to assume the role if he knows this IAM role's ARN. So, we need to lock it down by adding a condition in the assume-role policy document. Go to the tab Trust relationships and replace the existing condition with:
Here is how I declare the conditions in the module configuration.
condition {
test = "StringEquals"
values = var.match_value
variable = "${aws_iam_openid_connect_provider.gitlab[0].url}:${var.match_field}"
}
Below condition allows any GitLab project to retrieve temporary credentials from AWS Security Token Service (STS). Use aud
if you use GitLab instance url such as https://gitlab.com as match_value
. aud
means the URL of the GitLab instance. This is defined when the identity provider is first configured in your cloud provider.
condition {
test = "StringEquals"
values = var.match_value # https//gitlab.com
variable = "${aws_iam_openid_connect_provider.gitlab[0].url}:${var.match_field}" # gitlab.com:aud
}
Trusted Entities look liks
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::585584209241:oidc-provider/gitlab.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"gitlab.com:aud": "https://gitlab.com"
}
}
}
]
}
sub
is a concatenation of metadata describing the GitLab CI/CD workflow including the group, project, branch, and tag. The sub field is in the following format:
project_path:{gitlab_group_id}/{project_name}:ref_type:{type}:ref:{branch_name}
Filter | Example |
---|---|
Filter to main branch | project_path:mygroup/myproject:ref_type:branch:ref:main |
Filter to any branch | Wildcard supported. project_path:mygroup/myproject:ref_type:branch:ref:* |
Filter to specific project | project_path:mygroup/myproject:ref_type:branch:ref:main |
Filter to all projects under a group | Wildcard supported. project_path:mygroup/*:ref_type:branch:ref:main |
Filter to a Git tag | Wildcard supported. project_path:mygroup/*:ref_type:tag:ref:1.0 |
Trusted Entities look like
"Condition": {
"StringEquals": {
"gitlab.com:sub": "project_path:{group_id}/{project_name}:ref_type:branch:ref:main
}
}
Name | Description | Type | Default | Required |
---|---|---|---|---|
gitlab_url | The address of your GitLab instance, such as https://gitlab.com or http://gitlab.example.com. | string |
"https://gitlab.com" |
yes |
audience | The address of your GitLab instance, such as https://gitlab.com or http://gitlab.example.com. | string |
"https://gitlab.com" |
yes |
iam_role_policy_arns | List of IAM policy ARNs to attach to the IAM role. | list(string) |
[] |
optional |
create_oidc_provider | Flag to enable/disable the creation of the GitHub OIDC provider. | bool |
true |
yes |
match_field | Issuer, the domain of your GitLab instance. Change to sub if you want to use the filter to any project | string |
aud | yes |
match_value | It should be your Gitab Instance URl by default. But if you want to use filer to a specific group, branch or tag, use this format project_path:mygroup/myproject:ref_type:branch:ref:main | list |
GitLab Instance URL | yes |
Name | Description | Type | Default | Required |
---|---|---|---|---|
attach_admin_policy | Flag to enable/disable the attachment of the AdministratorAccess policy. | bool |
false |
no |
iam_role_name | Name of the IAM role to be created. This will be assumable by GitLab. | string |
"gitlab_action_role" |
no |
iam_role_path | Path under which to create IAM role. | string |
"/" |
no |
max_session_duration | Maximum session duration in seconds. | number |
3600 |
no |
Name | Description |
---|---|
iam_role_arn | ARN of the IAM role. |
variables:
REGION: us-east-1
ROLE_ARN: arn:aws:iam::${AWS_ACCOUNT_ID}:role/gitlab_action_role
image:
name: amazon/aws-cli:latest
entrypoint:
- '/usr/bin/env'
assume role:
script:
- >
STS=($(aws sts assume-role-with-web-identity
--role-arn ${ROLE_ARN}
--role-session-name "GitLabRunner-${CI_PROJECT_ID}-${CI_PIPELINE_ID}"
--web-identity-token $CI_JOB_JWT_V2
--duration-seconds 3600
--query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken]'
--output text))
- export AWS_ACCESS_KEY_ID="${STS[0]}"
- export AWS_SECRET_ACCESS_KEY="${STS[1]}"
- export AWS_SESSION_TOKEN="${STS[2]}"
- export AWS_REGION="$REGION"
- aws sts get-caller-identity
- aws s3 ls
- aws iam list-users
© 2021 Daniel Morris
Made available under the terms of the Apache License 2.0.