Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gov partition and service principal #2

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ When the Amazon ECS task container instance transitions to the `RUNNING` state,

The authentication procedure for enrolling the Amazon ECS container instance into the ADO agent pool is accomplished by using a personal access token (PAT). There is no need to configure AWS credentials because the access to AWS resources is handled via the Amazon ECS task and task execution [Identity and Access Management (IAM)](https://aws.amazon.com/iam) roles, thus eliminating the need to configure AWS credentials in ADO.

Alternative Authentication in Azure DevOps includes usage of Entra ID Service Principal. Using the Service Principal information, request Entra ID OAuth 2.0 Token which can then be used instead of the PAT.

### Prerequisites

Here are the prerequisites to use this solution for your Azure Pipelines agents:
Expand Down
15 changes: 15 additions & 0 deletions ado_agent_repo/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,22 @@ if [ -z "$AZP_TOKEN_FILE" ]; then
fi

AZP_TOKEN_FILE="/azp/.token"

# Instead of storing the PAT in the AWS Secret, you can store the Service Principal Credential
# $SP_APP_ID Replace with your Service Principal Application ID in terraform.tfvars
# $SP_APP_TENANT_ID Replace with your Tenant ID

if [ -z "$SP_APP_ID" ]; then
echo -n $AZP_TOKEN > "$AZP_TOKEN_FILE"
else
# If using Service Principal, use the Secret to and Service Principal to request an Entra ID Token
curl -s -X POST -H 'Content-Type: application/x-www-form-urlencoded' \
"https://login.microsoftonline.com/$SP_APP_TENANT_ID/oauth2/v2.0/token" \
-d "client_id=$SP_APP_ID" \
-d 'grant_type=client_credentials' \
-d 'scope=https%3A%2F%2Fmanagement.core.windows.net%2F%2F.default' \
-d "client_secret=$AZP_TOKEN" | jq -r '.access_token' > "$AZP_TOKEN_FILE"
fi
fi

unset AZP_TOKEN
Expand Down
13 changes: 8 additions & 5 deletions data.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
data "aws_partition" "current" {}

data "aws_iam_policy_document" "ecs-assume-role-policy" {
statement {
Expand Down Expand Up @@ -71,7 +72,7 @@ data "aws_iam_policy_document" "lambda_create_task_role_policy" {
"logs:CreateLogStream",
"logs:PutLogEvents"
]
resources = ["arn:aws:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:*"]
resources = ["arn:${data.aws_partition.current.partition}:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:*"]
}

statement {
Expand All @@ -85,7 +86,9 @@ data "aws_iam_policy_document" "lambda_create_task_role_policy" {
actions = [
"ecs:RunTask"
]
resources = [module.ecs.ecs_task_def_arn]
resources = [
"${module.ecs.ecs_task_def_arn}*"
]
}

statement {
Expand Down Expand Up @@ -118,7 +121,7 @@ data "aws_iam_policy_document" "lambda_get_task_role_policy" {
"logs:GetLogEvents",
"logs:FilterLogEvents"
]
resources = ["arn:aws:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:*"]
resources = ["arn:${data.aws_partition.current.partition}:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:*"]
}

statement {
Expand All @@ -139,7 +142,7 @@ data "aws_iam_policy_document" "lambda_get_task_role_policy" {
actions = [
"ecs:DescribeTasks"
]
resources = ["arn:aws:ecs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:task/${local.prefix}-ecs-cluster-${var.environment}/*"]
resources = ["arn:${data.aws_partition.current.partition}:ecs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:task/${local.prefix}-ecs-cluster-${var.environment}/*"]
}
statement {
actions = [
Expand All @@ -151,4 +154,4 @@ data "aws_iam_policy_document" "lambda_get_task_role_policy" {
]
}

}
}
2 changes: 1 addition & 1 deletion main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ module "ecs_ado_api" {
api_path_part = "create-task"
api_stage_name = "dev"
api_stage_description = "ECS Ado API Deployment"
apigw_lambda_arn = "arn:aws:apigateway:${data.aws_region.current.name}:lambda:path/2015-03-31/functions/${module.create_task_lambda.lambda_function_arn}/invocations"
apigw_lambda_arn = "arn:${data.aws_partition.current.partition}:apigateway:${data.aws_region.current.name}:lambda:path/2015-03-31/functions/${module.create_task_lambda.lambda_function_arn}/invocations"
function_name = module.create_task_lambda.lambda_function_name
tags = local.resource_tags
}
2 changes: 1 addition & 1 deletion modules/apigw/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ resource "aws_lambda_permission" "api_lambda" {
action = "lambda:InvokeFunction"
function_name = var.function_name
principal = "apigateway.amazonaws.com"
source_arn = "arn:aws:execute-api:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:${aws_api_gateway_rest_api.api.id}/*/*/*"
source_arn = "arn:${data.aws_partition.current.partition}:execute-api:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:${aws_api_gateway_rest_api.api.id}/*/*/*"
}

resource "aws_api_gateway_deployment" "api_deployment" {
Expand Down
3 changes: 3 additions & 0 deletions modules/codebuild/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,7 @@ resource "aws_codebuild_project" "terraform_codebuild_project" {
type = var.build_project_source
buildspec = var.build_spec
}

lifecycle { ignore_changes = [project_visibility] }

}
2 changes: 1 addition & 1 deletion modules/ecr/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ resource "aws_ecr_repository_policy" "terraform_ecr_repository_policy" {
"Effect" : "Allow",
"Principal" : {
"AWS" : [
"arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"
"arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:root"
]
},
"Action" : [
Expand Down
7 changes: 7 additions & 0 deletions modules/ecs/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ resource "aws_ecs_task_definition" "ecs_task_def" {
containerPort = var.container_port
hostPort = var.container_host_port
}]
healthCheck = {
retries = 3
command = [ "CMD-SHELL", "pgrep -u agent Agent.Listener || exit 1" ]
timeout: 10
interval: 60
startPeriod: 5
}
logConfiguration = {
logDriver = "awslogs"
options = {
Expand Down
12 changes: 6 additions & 6 deletions modules/iam-role/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ resource "aws_iam_policy" "codepipeline_policy" {
"codecommit:ListBranches",
"codecommit:UploadArchive"
],
"Resource": "arn:aws:codecommit:${data.aws_region.current.id}:${data.aws_caller_identity.current.account_id}:${var.source_repository_name}"
"Resource": "arn:${data.aws_partition.current.partition}:codecommit:${data.aws_region.current.id}:${data.aws_caller_identity.current.account_id}:${var.source_repository_name}"
},
{
"Effect": "Allow",
Expand All @@ -95,7 +95,7 @@ resource "aws_iam_policy" "codepipeline_policy" {
"codebuild:StartBuild",
"codebuild:BatchGetProjects"
],
"Resource": "arn:aws:codebuild:${data.aws_region.current.id}:${data.aws_caller_identity.current.account_id}:project/${var.project_name}*"
"Resource": "arn:${data.aws_partition.current.partition}:codebuild:${data.aws_region.current.id}:${data.aws_caller_identity.current.account_id}:project/${var.project_name}*"
},
{
"Effect": "Allow",
Expand All @@ -105,7 +105,7 @@ resource "aws_iam_policy" "codepipeline_policy" {
"codebuild:UpdateReport",
"codebuild:BatchPutTestCases"
],
"Resource": "arn:aws:codebuild:${data.aws_region.current.id}:${data.aws_caller_identity.current.account_id}:report-group/${var.project_name}*"
"Resource": "arn:${data.aws_partition.current.partition}:codebuild:${data.aws_region.current.id}:${data.aws_caller_identity.current.account_id}:report-group/${var.project_name}*"
},
{
"Effect": "Allow",
Expand All @@ -119,7 +119,7 @@ resource "aws_iam_policy" "codepipeline_policy" {
"ecr:PutImage",
"ecr:UploadLayerPart"
],
"Resource": "arn:aws:ecr:${data.aws_region.current.id}:${data.aws_caller_identity.current.account_id}:repository/ado-ecs-ecr"
"Resource": "arn:${data.aws_partition.current.partition}:ecr:${data.aws_region.current.id}:${data.aws_caller_identity.current.account_id}:repository/ado-ecs-ecr"
},
{
"Effect": "Allow",
Expand Down Expand Up @@ -167,7 +167,7 @@ data "aws_iam_policy_document" "assume_role_policy" {

resource "aws_iam_role_policy_attachment" "ecsTaskExecutionRole_policy" {
role = aws_iam_role.ecsTaskExecutionRole.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role"
policy_arn = "arn:${data.aws_partition.current.partition}:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role"
}

resource "aws_iam_role_policy_attachment" "ecsTaskExecutionRole_assume_policy" {
Expand All @@ -191,7 +191,7 @@ resource "aws_iam_policy" "ecs_task_role_policy" {
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:iam:::role/${var.infrastructure_deployer_role_name}"
"Resource": "arn:${data.aws_partition.current.partition}:iam:::role/${var.infrastructure_deployer_role_name}"
}
]
}
Expand Down
3 changes: 2 additions & 1 deletion modules/kms/data.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
#Amazon Web Services, Inc. or Amazon Web Services EMEA SARL or both.

data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
data "aws_region" "current" {}
data "aws_partition" "current" {}
2 changes: 1 addition & 1 deletion modules/kms/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ data "aws_iam_policy_document" "kms_key_policy_doc" {

principals {
type = "AWS"
identifiers = ["arn:aws:iam::${local.account_id}:root"]
identifiers = ["arn:${data.aws_partition.current.partition}:iam::${local.account_id}:root"]
}
}

Expand Down
2 changes: 1 addition & 1 deletion modules/lambda/iam.tf
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ resource "aws_iam_policy" "lambda_execution_role_policy" {
"logs:PutLogEvents"
]
Effect = "Allow"
Resource = "arn:aws:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:*"
Resource = "arn:${data.aws_partition.current.partition}:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:*"
},
{
Action = [
Expand Down
4 changes: 3 additions & 1 deletion terraform.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ container_env_vars = [
{ name = "PORT", value = "80" },
{ name = "AZP_URL", value = "https://dev.azure.com/change-me/" },// Replace with your ADO Org URL
{ name = "AZP_POOL", value = "ecscluster" }, // Replace with your ADO Agent Pool name
#{ name = "SP_APP_ID", value = ""}, // Replace with your Service Principal Application ID
#{ name = "SP_APP_TENANT_ID", value = ""}, // Replace with your Tenant ID
]
container_port = 80
container_host_port = 80
Expand All @@ -34,4 +36,4 @@ lambda_timeout = "90"
subnet_ids = "subnet-change-me" // Replace with subnet-id from your account
security_groups = "sg-change-me" // Replace with security-group-id from your account

ado_org = "change-me" // Replace with your ADO Org ID
ado_org = "change-me" // Replace with your ADO Org Name