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

CDK_AWS_PARTITION: Does not fix the OIDC region and audience. #1091

Open
oliott opened this issue Aug 22, 2024 · 7 comments
Open

CDK_AWS_PARTITION: Does not fix the OIDC region and audience. #1091

oliott opened this issue Aug 22, 2024 · 7 comments

Comments

@oliott
Copy link

oliott commented Aug 22, 2024

Hi,

Setting the environment variable CDK_AWS_PARTITION as specified here: AWS China partition support, does not make sure that the audience and aws-region of this action: aws-actions/configure-aws-credentials@v4 are configured correctly.

This results in the following:

pipeline-definition.yml
# AUTOMATICALLY GENERATED FILE, DO NOT EDIT MANUALLY.
# Generated by AWS CDK and [cdk-pipelines-github](https://github.com/cdklabs/cdk-pipelines-github)

name: deploy-china-partition
on:
  push:
    branches:
      - main
  workflow_dispatch: {}
jobs:
# ... other steps
  Assets-FileAsset1:
    name: Publish Assets Assets-FileAsset1
    needs:
      - Build-Build
    permissions:
      contents: read
      id-token: write
    runs-on: ubuntu-latest
    outputs:
      asset-hash: ${{ steps.Publish.outputs.asset-hash }}
    steps:
      - name: Download cdk.out
        uses: actions/download-artifact@v4
        with:
          name: cdk.out
          path: cdk.out
      - name: Install
        run: npm install --no-save cdk-assets
      - name: Authenticate Via OIDC Role
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-region: us-west-1
          role-duration-seconds: 1800
          role-skip-session-tagging: true
          role-to-assume: arn:aws-cn:iam::000000000000:role/DummyOIDCRole
      - id: Publish
        name: Publish Assets-FileAsset1
        run: /bin/bash ./cdk.out/assembly-DummyStage/publish-Assets-FileAsset1-step.sh
# ... other steps

The aws-region part can be fixed by setting publishAssetsAuthRegion, when creating the pipeline. However the audience is not set to sts.amazonaws.com.cn which is a requirement for the OIDC authentication to work: OIDC Audience. Because of this the github action to assume the OIDC role will fail.

Relevant issues:

Reproducible python code:

requirements.txt
aws-cdk-lib==2.154.0
constructs>=10.0.0,<11.0.0
cdk-pipelines-github
cdk.json
{
  "app": "python3 app.py",
  "watch": {
    "include": [
      "**"
    ],
    "exclude": [
      "README.md",
      "cdk*.json",
      "requirements*.txt",
      "source.bat",
      "**/__init__.py",
      "**/__pycache__",
      "tests"
    ]
  },
  "context": {
    "@aws-cdk/aws-lambda:recognizeLayerVersion": true,
    "@aws-cdk/core:checkSecretUsage": true,
    "@aws-cdk/core:target-partitions": [
      "aws",
      "aws-cn"
    ],
    "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
    "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
    "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
    "@aws-cdk/aws-iam:minimizePolicies": true,
    "@aws-cdk/core:validateSnapshotRemovalPolicy": true,
    "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
    "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
    "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
    "@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
    "@aws-cdk/core:enablePartitionLiterals": true,
    "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
    "@aws-cdk/aws-iam:standardizedServicePrincipals": true,
    "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
    "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
    "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
    "@aws-cdk/aws-route53-patters:useCertificate": true,
    "@aws-cdk/customresources:installLatestAwsSdkDefault": false,
    "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
    "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
    "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
    "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
    "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
    "@aws-cdk/aws-redshift:columnId": true,
    "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true,
    "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
    "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
    "@aws-cdk/aws-kms:aliasNameRef": true,
    "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true,
    "@aws-cdk/core:includePrefixInUniqueNameGeneration": true,
    "@aws-cdk/aws-efs:denyAnonymousAccess": true,
    "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true,
    "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true,
    "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true,
    "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true,
    "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true,
    "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true,
    "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true,
    "@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true,
    "@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true,
    "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true
  }
}
app.py
#!/usr/bin/env python3

import aws_cdk as cdk
import os

from constructs import Construct
from cdk_pipelines_github import GitHubWorkflow, AwsCredentials, JsonPatch

app = cdk.App()

TEST_ACCOUNT_ID = os.environ['TEST_ACCOUNT_ID']
TEST_OIDC_ROLE_NAME = os.environ['TEST_OIDC_ROLE_NAME']

class DummyStack(cdk.Stack):
    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        cdk.aws_sqs.Queue(
            self,
            "IssueGithubPipelinesQueue",
            visibility_timeout=cdk.Duration.seconds(300),
        )


class DummyPipelineStage(cdk.Stage):
    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        DummyStack(self, f"TestStack", **kwargs)


github_pipeline = GitHubWorkflow(
    app,
    "GithubPipeline",
    synth=cdk.pipelines.ShellStep(
        "Build",
        commands=[
            "npm install -g aws-cdk",
            "python -m pip install -r requirements.txt",
            "cdk synth",
        ],
    ),
    aws_creds=AwsCredentials.from_open_id_connect(
        git_hub_action_role_arn=f"arn:aws-cn:iam::{TEST_ACCOUNT_ID}:role/{TEST_OIDC_ROLE_NAME}"
    ),
    workflow_name="deploy-china-partition",
    workflow_path=".github/workflows/deploy-china-partition.yml",
    publish_assets_auth_region="cn-northwest-1",
)
github_pipeline.workflow_file.patch(
    JsonPatch.add(
        '/env',
        {
            'AWS_STS_REGIONAL_ENDPOINTS' : 'regional',
            'TEST_ACCOUNT_ID' : '${{ vars.TEST_ACCOUNT_ID }}',
            'TEST_OIDC_ROLE_NAME' : '${{ vars.TEST_OIDC_ROLE_NAME }}',
        }
    )
)
wave = github_pipeline.add_wave("MultiRegion")

stage = DummyPipelineStage(
    app,
    "DummyStage",
    env=cdk.Environment(account=TEST_ACCOUNT_ID, region="cn-north-west-1"),
)

wave.add_stage(
    stage,
)


app.synth()

Version

Python 3.10.0
cdk-pipelines-github version: cdk-pipelines-github==0.4.124

Modifications/environment/deployment

I Have made no modifactions to code environment or deployment that should affect this.

Issue

Setting the environment variable CDK_AWS_PARTITION does not setup the OIDC Github Action correctly.

Local testing:

  1. (Make sure you have python, pip and cdk isntalled).
  2. copy, cdk.json, app.py, and requirements.txt
  3. python3 -m venv .venv
  4. source .venv/bin/activate
  5. pip install -r requirements.txt
  6. export TEST_ACCOUNT_ID=<account-id> && export TEST_OIDC_ROLE_NAME=<oicd-role-name>
  7. cdk synth

View the output workflow file in .github/workflows/.

EDITS:

  1. Updated the python file by changing the env variables for the workflow. Added cdk.json. Added description on how to test locally.
@kaizencc
Copy link
Contributor

kaizencc commented Sep 5, 2024

@mbergkvist since you were the one helping out with the AWS_PARTITION i'm wondering if you can help here?
@oliott thanks for bringing this to our attention but i don't currently have time to work on this. i would be happy to review a PR from you or anyone else in the community though. sorry about that -- this is a cdklabs project that relies heavily on community contributions for new features.

@mbergkvist
Copy link
Contributor

mbergkvist commented Sep 6, 2024

@oliott audience is not set, but that has not been an issue for me. Before we go down that path, can you try to add

env:
  AWS_STS_REGIONAL_ENDPOINTS: regional

to the deploy file? In TS it's done with

pipeline.workflowFile.patch(JsonPatch.add('/env', { AWS_STS_REGIONAL_ENDPOINTS: 'regional' }));

If that doesn't help, please provide the error you get and also how you've setup the trust in the git_hub_action_role.

@oliott
Copy link
Author

oliott commented Sep 6, 2024

Hi thanks for taking time to respond and looking at this. I tried setting this:

env:
  AWS_STS_REGIONAL_ENDPOINTS: regional

But does not really fix the issue. I can paste the entire workflow yaml file here:

.github/workflows/deploy-china-partition.yml
# AUTOMATICALLY GENERATED FILE, DO NOT EDIT MANUALLY.
# Generated by AWS CDK and [cdk-pipelines-github](https://github.com/cdklabs/cdk-pipelines-github)

name: deploy-china-partition
on:
  push:
    branches:
      - main
  workflow_dispatch: {}
jobs:
  Build-Build:
    name: Synthesize
    permissions:
      contents: read
      id-token: write
    runs-on: ubuntu-latest
    needs: []
    env: {}
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Build
        run: |-
          npm install -g aws-cdk
          python -m pip install -r requirements.txt
          cdk synth
      - name: Upload cdk.out
        uses: actions/upload-artifact@v4
        with:
          name: cdk.out
          path: cdk.out
  Assets-FileAsset1:
    name: Publish Assets Assets-FileAsset1
    needs:
      - Build-Build
    permissions:
      contents: read
      id-token: write
    runs-on: ubuntu-latest
    outputs:
      asset-hash: ${{ steps.Publish.outputs.asset-hash }}
    steps:
      - name: Download cdk.out
        uses: actions/download-artifact@v4
        with:
          name: cdk.out
          path: cdk.out
      - name: Install
        run: npm install --no-save cdk-assets
      - name: Authenticate Via OIDC Role
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-region: cn-northwest-1
          role-duration-seconds: 1800
          role-skip-session-tagging: true
          role-to-assume: arn:aws-cn:iam::000000000000:role/DummyOIDCRole
      - id: Publish
        name: Publish Assets-FileAsset1
        run: /bin/bash ./cdk.out/assembly-DummyStage/publish-Assets-FileAsset1-step.sh
  DummyStage-TestStack-Deploy:
    name: Deploy DummyStageTestStackB0404510
    permissions:
      contents: read
      id-token: write
    needs:
      - Build-Build
      - Assets-FileAsset1
    runs-on: ubuntu-latest
    steps:
      - name: Authenticate Via OIDC Role
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-region: cn-north-west-1
          role-duration-seconds: 1800
          role-skip-session-tagging: true
          role-to-assume: arn:aws-cn:iam::000000000000:role/DummyOIDCRole
      - name: Assume CDK Deploy Role
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-region: cn-north-west-1
          role-duration-seconds: 1800
          role-skip-session-tagging: true
          aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }}
          aws-session-token: ${{ env.AWS_SESSION_TOKEN }}
          role-to-assume: arn:aws:iam::000000000000:role/cdk-hnb659fds-deploy-role-000000000000-cn-north-west-1
          role-external-id: Pipeline
      - id: Deploy
        uses: aws-actions/aws-cloudformation-github-deploy@v1
        with:
          name: DummyStage-TestStack
          template: https://cdk-hnb659fds-assets-000000000000-cn-north-west-1.s3.cn-north-west-1.amazonaws.com/${{
            needs.Assets-FileAsset1.outputs.asset-hash }}.json
          no-fail-on-empty-changeset: "1"
          role-arn: arn:aws:iam::000000000000:role/cdk-hnb659fds-cfn-exec-role-000000000000-cn-north-west-1
env:
  AWS_STS_REGIONAL_ENDPOINTS: regional
  TEST_ACCOUNT_ID: ${{ vars.TEST_ACCOUNT_ID }}
  TEST_OIDC_ROLE_NAME: ${{ vars.TEST_OIDC_ROLE_NAME }}

The jobs/steps that are failing is the aws-actions/configure-aws-credentials@v4 since they do not get their audience set to sts.amazonaws.com.cn.

This is the resulting job/step running in github:

# Run aws-actions/configure-aws-credentials@v4
  with:
    aws-region: cn-northwest-1
    role-duration-seconds: 1800
    role-skip-session-tagging: true
    role-to-assume: arn:aws-cn:iam::000000000000:role/DummyOIDCRole
    audience: sts.amazonaws.com
  env:
    AWS_STS_REGIONAL_ENDPOINTS: regional
    TEST_ACCOUNT_ID: 000000000000
    TEST_OIDC_ROLE_NAME: DummyOIDCRole

So the audience ends up pointing to global regardless of me setting that environment variable.

@mbergkvist
Copy link
Contributor

@oliott Interesting. I see now that I too have audience: sts.amazonaws.com in the logs, but I've no issues with uploading assets or deploying.

Run aws-actions/configure-aws-credentials@v4
  with:
    aws-region: cn-north-1
    role-duration-seconds: 1800
    role-skip-session-tagging: true
    role-to-assume: arn:aws-cn:iam::000000000000:role/GitHubActionRole
    role-session-name: GitHubActionsPipeline
    audience: sts.amazonaws.com
  env:
    AWS_STS_REGIONAL_ENDPOINTS: regional
Assuming role with OIDC
Authenticated as assumedRoleId AROAQ4U57LWRXIREWVCNN:GitHubActionsPipeline

Could it be the subject-claims of the GitHubActionRole that is not correct?

subjectClaims: ['repo:owner/repo:ref:refs/heads/main'],

@oliott
Copy link
Author

oliott commented Sep 6, 2024

I know that the OIDC part is setup correctly because it is working as long as I specify the audience. But I have followed: Configuring OpenID Connect in Amazon Web Services. It does not clearly specify that the audience should be sts.amazonaws.com.cn for the China partition but setting it to anything else fails.

Also the documentation for the action says that the audience for China should be specified as sts.amazonaws.com.cn.

But I can check and see if I can find where the yaml for this action is created and add the audience when applicable.

@mbergkvist
Copy link
Contributor

mbergkvist commented Sep 6, 2024

I'm curious why it's working for me even though I have audience: sts.amazonaws.com.

Are you using GitHubActionRole from cdk-pipelines-github?

@oliott
Copy link
Author

oliott commented Sep 6, 2024

No I am not using GitHubActionRole I think it works because that role does not create the trust policy to contain the condition on the audience as recommended here: configuring-the-role-and-trust-policy.

"Condition": {
  "StringEquals": {
    "token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
    "token.actions.githubusercontent.com:sub": "repo:octo-org/octo-repo:ref:refs/heads/octo-branch"
  }
}

So I have a Role that has this trust policy but it is sts.amazonaws.com.cn instead since that is the sts endpoint in China. So that explains why it is working for you and not for me.

Here is the code in question that maybe should create that? src/oidc-provider.ts#L106

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants