Package: gh-action-open-id-in-aws
Welcome togh_action_open_id_in_awsDocumentationOverviewTo use GitHub Actions to deploy applications to AWS, we have to setup the permission properly.The old school method is to useSecret Environment Variableto store theAWS IAM Usercredentials. You can storeaccess key abd secret keyto theAWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEYenvironment variables. This is also the solution used by CircleCI.Around Nov 2021, AWS and GitHub made the official Open ID Connection (OIDC) available. It simplifies the process of granting AWS permissions to GitHub Actions. This is the AWS recommended way, and AWS explicitly mentioned that it isNOT recommended to use long term IAM user credential for CI/CD.This Python tool automates the process of setting up the GitHub action open id connection in AWS.Reference:Configuring OpenID Connect in Amazon Web Services: GitHub official doc.Sample IAM OIDC CloudFormation Template: AWS maintained github action.How to UseSetup GitHub OIDC Connect in an AWS account the first timeTo setup GitHub action open id connection in AWS the first time, you can do the following. This code snippet creates an GitHub OIDC Identity Provider and an IAM role to let the Identity Provider to assume using AWS CloudFormation:fromgh_action_open_id_in_aws.implimportsetup_github_action_open_id_connection_in_awssetup_github_action_open_id_connection_in_aws(aws_profile="your_aws_profile_here",stack_name="cloudformation-stack-name-here",github_org="your-github-organization-name",github_repo="your_github_repo_name",role_name="the_iam_role_name_to_be_assumed_by_github_actions",)Note that the created IAM role won’t have any permission, you need to configure it yourself. Usually, GitHub action is used for CI/CD, you may need the following permissions to perform common CI/CD tasks.:Manage (Create / Update / Delete) IAM Role / PolicyManage (Create / Update / Delete) AWS CloudFormation stack.Manage (Create / Update / Delete) AWS S3 Bucket to read / write deployment artifacts.Manage (Create / Update / Delete) AWS Parameter Store to read and write parameters.Manage (Create / Update / Delete) AWS ECR to push and pull container images and share it to workload AWS accounts.Manage (Create / Update / Delete) AWS EC2 AMI and share it to workload AWS accounts.Manage (Create / Update / Delete) AWS SNS Topic to send notifications.Pro Tips:The GitHub IAM Role permission should define a common name prefix to identify devops resources from other resources, avoid using"Resource": "*".Setup AWS Permission for Multiple GitHub RepositoriesIf you have more Github repo need to access the same AWS accounts, and you want to give them different permission, you can do this. This code snippet reuse the OIDC Provider you created before (make sure you did the previous example before) and create a different IAM role, and configure IAM policy permission for the new GitHub repo:fromboto_session_managerimportBotoSesManagerfromgh_action_open_id_in_aws.implimportsetup_github_action_open_id_connection_in_awsaws_profile="your_aws_profile_here"bsm=BotoSesManager(profile_name=aws_profile)role_name="the_new_iam_role_name_to_be_assumed_by_github_actions"setup_github_action_open_id_connection_in_aws(aws_profile=aws_profile,stack_name="cloudformation-stack-name-here",github_org="your-github-organization-name",github_repo="another_github_repo_name",role_name=role_name,oidc_provider_arn=f"arn:aws:iam::{bsm.aws_account_id}:oidc-provider/token.actions.githubusercontent.com",)# let's say you want to give the new GitHub repo admin permissionbsm.iam_client.attach_role_policy(RoleName=role_name,PolicyArn="arn:aws:iam::aws:policy/AdministratorAccess",)GitHub Actions for Multi-AWS Accounts CI/CD IAM Permission Best PracticeIf you have multiple GitHub Repositories using GitHub Actions to deploy applications to multiple environments in multiple AWS accounts, here is the best practice:Supposes that you have three workload AWS Accountsdev_aws,test_aws,prod_aws, and adevops_awsAWS account to store versioned code artifacts. These accounts could be different AWS accounts, either could be the same AWS account isolated by naming convention.Supposes that you have oneadmin_repoGitHub repo to setup and test the cross AWS account IAM permission, and have multiple project GitHub repoproject1_repo,project2_repo, etc …Run the following code to setup the GitHub Action OIDC provider indevops_awsaccount. It will create an IAM role without any permission. Please keep it as it is, we are not going to use it for any project.fromgh_action_open_id_in_aws.implimportsetup_github_action_open_id_connection_in_awssetup_github_action_open_id_connection_in_aws(# this AWS principal should have permission to deploy CloudFormation and IAMaws_profile="aws_profile_for_devops_aws",stack_name="admin-repo-with-hyphen",github_org="your-github-org",github_repo="admin_repo",role_name="admin_repo_role_name",)For each project GitHub repo, run the following code to setup the IAM role indevops_awsAWS account, only for the given GitHub repo. Of course you can use${GitHubOrg}/*to give all GitHub repos in the same GitHub org the same permission, but this is not recommended. And then, you should configure the IAM role permission manually for the project GitHub repo.fromgh_action_open_id_in_aws.implimportsetup_github_action_open_id_connection_in_awssetup_github_action_open_id_connection_in_aws(# this AWS principal should have permission to deploy CloudFormation and IAMaws_profile="aws_profile_for_devops_aws",stack_name="project1-repo-with-hyphen",github_org="your-github-org",github_repo="project1_repo",role_name="project1_repo_role_name",)Then refer to thecross_aws_account_iam_rolePython library to setup the cross AWS account IAM roles for theproject1_repo_role_nameindevops_awsAWS Account.Note:In general, there are two ways to setup cross AWS account IAM permission in GitHub actions:ONLY setup OIDC provider and IAM role indevops_awsaccount, and let the IAM role indevops_awsaccount to assume IAM role indev_aws,test_aws,prod_awsaccount. This is therecommended way.Setup OIDC provider and IAM role indevops_aws,dev_aws,test_aws,prod_awsaccount. And useaws-actions/configure-aws-credentialsGitHub Action to switch between them. This isNOT recommended, because it introduce more complexity and more IAM permission to manage in workload AWS accounts, which increases the risk.Test your SetupBelow is a sample GitHub Actions workflow file to test your setup. You have to create four GitHub secretsDEVOPS_AWS_ACCOUNT_ID,DEV_AWS_ACCOUNT_ID,TEST_AWS_ACCOUNT_ID,PROD_AWS_ACCOUNT_ID:name:...on:...env:AWS_REGION:us-east-1jobs:job_id:runs-on:ubuntu-lateststeps:..- name:Configure AWS credentials for DEVOPSuses:aws-actions/configure-aws-credentials@v3with:role-to-assume:arn:aws:iam::${{ secrets.DEVOPS_AWS_ACCOUNT_ID }}:role/devops_aws_iam_rolerole-session-name:sample_role_sessionaws-region:${{ env.AWS_REGION }}-name:Configure AWS credentials for DEVuses:aws-actions/configure-aws-credentials@v3with:role-to-assume:arn:aws:iam::${{ secrets.DEV_AWS_ACCOUNT_ID }}:role/dev_aws_iam_rolerole-session-name:sample_role_sessionaws-region:${{ env.AWS_REGION }}-name:Configure AWS credentials for TESTuses:aws-actions/configure-aws-credentials@v3with:role-to-assume:arn:aws:iam::${{ secrets.TEST_AWS_ACCOUNT_ID }}:role/test_aws_iam_rolerole-session-name:sample_role_sessionaws-region:${{ env.AWS_REGION }}-name:Configure AWS credentials for PRODuses:aws-actions/configure-aws-credentials@v3with:role-to-assume:arn:aws:iam::${{ secrets.PROD_AWS_ACCOUNT_ID }}:role/prod_aws_iam_rolerole-session-name:sample_role_sessionaws-region:${{ env.AWS_REGION }}Developer GuideThis section is for developers who want to contribute to this project.What under the hood is a CloudFormation template. Thegh_action_open_id_in_aws/cf.pyfile contains the AWS CDK source code. Thecdk/cdk_synth.pyscript can generate the JSON CloudFormation template using AWS CDK. The developer then can copy the output template to thegh_action_open_id_in_aws/cft-{year}-{month}-{day}.jsonfile and do local testing.Installgh_action_open_id_in_awsis released on PyPI, so all you need is to:$pipinstallgh-action-open-id-in-awsTo upgrade to latest version:$pipinstall--upgradegh-action-open-id-in-aws