Thread
#aws
    b

    brainy-furniture-43093

    6 months ago
    Hello everyone, My situation: I built a CodePipeline project in my DEV environment that on a push to a specific branch in my source code repo is kicked off, it immediately launches a CodeBuild environment that downloads Go and Pulumi, runs unit tests, builds my source code into a zip file then deploys my now built code and all of my Pulumi infrastructure to my dev environment, modifying dev resources on that DEV account. I have given that CodeBuild a specific IAM role with access to the s3 bucket that Pulumi uses for state, my bucket with my source code and all other resources Pulumi modifies during deployment. So far all works great. My Problem: Next, after a manual approval step I attempt to deploy my Pulumi infrastructure in my prod environment. This environment is in a PROD account, and I am trying to modify those resources from my CodeBuild in my DEV account where the CodePipeline runs. To try and accomplish this I have attempted to create an IAM role in my PROD account that I can assume in my DEV account. Prod account:
    CodeBuildProdRole:
        Type: AWS::IAM::Role
        Properties:
          RoleName: !Sub ${ProjectName}-codepipeline-deploy-prod-role
          Description: CodePipeline role to deploy dev artifacts and infrastructure changes to production
          AssumeRolePolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Principal:
                  AWS: !Sub arn:aws:iam::${DevAccountId}:role/${ProjectName}-codepipeline-deploy-prod-role
                Action: sts:AssumeRole
          Path: /
          Policies:
            - PolicyName: !Sub ${ProjectName}-codepipeline-deploy-prod-role-policy
              PolicyDocument:
                Version: "2012-10-17"
                Statement:
                - Effect: Allow
                  Resource: !Sub arn:aws:iam::${DevAccountId}:role/${ProjectName}-codepipeline-deploy-prod-role
                  Action: sts:AssumeRole
                - Effect: Allow
                  Action:
                  - s3:*
                  Resource:
                  - arn:aws:s3:::PROD s3 bucket for Pulumi state
                  - arn:aws:s3:::PROD s3 bucket for Pulumi state/*
                ...
    DEV account:
    CodeBuildProdRole:
        Type: AWS::IAM::Role
        Properties:
          RoleName: !Sub ${ProjectName}-codepipeline-deploy-prod-role
          Description: CodePipeline role to deploy dev artifacts and infrastructure changes to production
          AssumeRolePolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Principal:
                  Service: <http://codebuild.amazonaws.com|codebuild.amazonaws.com>
                Action:
                  - sts:AssumeRole
          Policies:
            - PolicyName: !Sub ${ProjectName}-codepipeline-deploy-prod-role-policy
              PolicyDocument:
                Version: "2012-10-17"
                Statement:
                  - Effect: Allow
                    Action: sts:AssumeRole
                    # The role I want to assume from the PROD account
                    Resource: !Sub arn:aws:iam::${ProdAccountId}:role/${ProjectName}-codepipeline-deploy-prod-role
                ...
    When I run Pulumi login (PROD s3 bucket for Pulumi state) I get this access denied error
    [Container] 2022/03/10 20:58:23 Running command pulumi login s3://(PROD s3 bucket for Pulumi state)
    Logged in to (id) as root (s3://(PROD s3 bucket for Pulumi state))
    
    [Container] 2022/03/10 20:58:23 Running command pulumi stack select prod
    error: failed to load checkpoint: blob (key ".pulumi/stacks/prod.json") (code=Unknown): AccessDenied: Access Denied
    I would imagine I need to do the equivalent of
    export AWS_PROFILE="PROD"
    which I do in my terminal to switch account for my user, but I would like to do this for a role. I would rather not start generating credentials on the fly and dynamically populate them as environment variables into CodeBuild. So is there a way I can tell Pulumi to assume a certain role in another account if the role it is currently using is the Principal to the role I want it to use, also making sure it modifies resources in the PROD account although it is running in the DEV account? Any help is much appreciated. Thank you! Ado
    b

    billowy-army-68599

    6 months ago
    thanks for the detailed write up. You indeed need to assume role using something like the AWS CLI to fix this. It's not necessarily a pulumi problem
    l

    little-cartoon-10569

    6 months ago
    Large posts like this can be posted in a thread, with the first post being just a summary. This is taking up a lot of space in the channel. Also, you can use Slack's "Create a code snippet" feature to highlight code and make it expandable.
    b

    billowy-army-68599

    6 months ago
    if you have valid AWS credentials, you'd use
    aws sts assume-role
    to get temporary credentials for your prod role.
    l

    little-cartoon-10569

    6 months ago
    It looks like the roles you've created allow codebulid to assume a role which then allows them to assume another role. Are you then assuming that role?
    b

    brainy-furniture-43093

    6 months ago
    @billowy-army-68599 Thanks for the help! aws sts assume-role in the CodeBuild did indeed get the job done 🎉 This was the code in the CodeBuild buildspec.yaml
    - CREDENTIALS=$(aws sts assume-role --role-arn arn:aws:iam::${ProdAccountID}:role/${ProdRoleName} --role-session-name "codebuild-prod" --query "Credentials")
          - read -r AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN <<<$( echo $CREDENTIALS | jq -r '"\(.AccessKeyId) \(.SecretAccessKey) \(.SessionToken)"' )
          - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
          - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
          - export AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN
    @little-cartoon-10569 Good point, I will do that next time. And yes, CodeBuild is assuming a role in its own account that allows it to assume a role in another account, I believe it's called role chaining.