-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
Make the CLI experience of multi-account CDK apps awesome #3401
Comments
An interesting point: the CloudFormation cross-account actions defined in #3208 create a new stack that contains the IAM roles needed to deploy into the target account. How do we want to model authorization for that use-case? Maybe passing the profile in |
(Probably an option to specify the CloudFormation role ARN should also be added.) |
That's already possible (you can pass a role when creating the action). |
I don’t think it is in the context of this issue, i.e., using profiles for
various accounts. Each account would require its own CF role.
… (Probably an option to specify the CloudFormation role ARN should also be
added.)
That's already possible (you can pass a role when creating the action).
|
I'm pretty sure the credentials that the |
As a developer I could only have the permission to start a CloudFormation
deploy. I can tell CloudFormation to assume an other role with elevated
permissions. See the `—role-arn` option of the cdk command
… I'm pretty sure the credentials that the profiles include refer to an IAM
user or role already, so I'm not sure what "specifying a role" would mean
in this context.
|
Ah, got it. Thanks for the explanation. Yes, that's something that this feature should definitely include. |
It could be as easy as specifying an optional . |
Is the wildcard option truly working?
Seems to do this no matter what I do I only tried wildcards cause the cdk deploy command mentions it. |
Yes, this is a common gotcha. The "No stack found matching 'README.md'" should be a hint :). The
or
|
ha thanks good to know |
Thanks for this. |
I am curious what people think about this idea which came up as part of the CI/Cd design: My current thinking is that when you bootstrap an environment using the cdk you will be able to specify a trusted account that will be able to deploy into this environment and then the cli will just assume a role in the target and deploy into it. No profiles needed... |
There will be two scenarios where CDK is used:
If we can attach a policy to pipelines that sufficient rights are granted everything would be fine. The same should go for developers. Let me define a role that allows them to execute cloudformation in each account and make the generation of cloudformation possible without cyclic reference checking. Using profiles would be a pain in the long way, as I already have three different entries in my ~/.aws/credentials file for some accounts right now and the other developers have named their credentials differently, however we try to enforce a common naming scheme right now. I never liked profiles and they feel kinda off, but I can understand why they are needed.
should be better for tooling then
|
I wouldn't assume too much about how the CDK is used, tends to force people into patterns that might not apply to them. Defining a trusted account sounds great as an option and applies to many use cases I can think of, but it may be a pain in more restricted environments, where whoever does the deploying doesn't have enough access to also establish a trust between accounts. I think that the original idea of deeper integration with existing AWS authentication mechanism is right, because it's in line with how other AWS tools work, like aws-cli and the SDKs. Maybe the CDK needs a local configuration file/option that isn't packaged with the app. One that is specific to whoever is currently using the CDK. Similar to profiles, actually. It could even be stored in the same directory, This is almost possible now. What I currently do is use context variables, from cdk.json and command line. In cdk.json I have a structure like:
And then in code I create the stack by looping through the above, like:
I also mix SDK and CDK (because in Python it's easy) and need to know in code which profile is in use, so I run the CDK with:
But:
Because I mix the CDK and SDK in the same code, I'd like the ability to pass the credentials used by the CDK to the SDK. But that can be worked around. Because of the second point above, I'm thinking that maybe Again, the option of defining a trusted account and sidestepping all this personal configuration sounds great, as long as it's not the only option. |
Commenting to register my support in making multi-account support better. I'm also interested in seeing how this could be used to support cellular architectures, where new accounts can be spun up, on the fly, using a service like AWS Organizations. I suspect that designing this feature around supporting cellular accounts might have a rising-tide effect for less demanding use-cases. |
Can the example from the aws-events overview section on Cross-account targets actually be run from the command line using cdk CLI? I'm trying to do something similar to this with cross-account targets and I don't know how to access two different accounts in a single pass. This feature is to make the experience awesome. I'd be OK right now with any experience that works. https://docs.aws.amazon.com/cdk/api/latest/docs/aws-events-readme.html#cross-account-targets |
I came here with exactly the same question as @gsdwait Any info? |
I also face the challenge, in organisation we centalize the logs,notification and alarms. Setup in one shot the tooling for client and admin account will ease a lot the deployement. |
@saltman424 @faridux We solved it with a plugin: https://github.com/hupe1980/cdk-multi-profile-plugin |
It would be great if we could specify an IAM Role to assume in the Example
|
The problem here is that you would need to add en EventBusPolicy which would look like that: new events.CfnEventBusPolicy(this, `myapp-event-bus-policy`, {
eventBusName: bus.eventBusName,
action: `events:PutEvents`,
principal: `*`,
statementId: `myapp-event-bus-policy-statement`,
condition: {
type: `StringEquals`,
key: `aws:PrincipalOrgID`,
value: orgPrincipal.organizationId,
}
}) But this causes an So kind of stuck for now when it comes to EventBridge's cross-account eventing. |
I'm working on mulit-account / multiregion deployments, with a pipeline that deploys the stacks, when i commit to a repository. My build stage does a cdk synth, the interates through the manifest.json, picks up the region/account details, and deploys the templates using a boto3.client. create_stack ( after switching to an 'automation' role ) that exisits in all my accounts..
|
Something as simple as introducing an 'app' tag could work but it would
need to be validated as unique.
…On Sat., Mar. 7, 2020, 22:43 Andrew, ***@***.***> wrote:
I'm working on mulit-account / multiregion deployments, with a pipeline
that deploys the stacks, when i commit to a repository. My build stage does
a cdk synth, the interates through the manifest.json, picks up the
region/account details, and deploys the templates using a boto3.client.
create_stack ( after switching to an 'automation' role ) that exisits in
all my accounts..
Its worked well, but i'm faced with a 'new' problem. My deployment process
works fine, for creating new stacks, or even editing them.. CF just deals
to stuff. However i have got no effective way to remove a stack that
already exists. If i remove a stack from my app, that wont' result in it be
deleting it.
I have been toying on some different ideas on how to deal with this. I
could for example register the exisitance of my stack in a small dynamodb
table, when the stack is reployed, i coudl find the differnces and delete
it.
I was hoping for something more 'native' than this though.
`import json
import boto3
import argparse
parser = argparse.ArgumentParser(description='Get Credentials')
parser.add_argument('--profile', help="profile", default='default')
args = parser.parse_args()
session = boto3.session.Session(profile_name=args.profile)
with open('manifest.json') as manifest_file:
data = json.load(manifest_file)
for artifact in data['artifacts']:
if artifact == 'Tree':
continue
template = data['artifacts'][artifact]['properties']['templateFile']
environment = data['artifacts'][artifact]['environment']
region = environment.split('/')[3]
account = environment.split('/')[2]
print("\n ********* Deploying Templates to accounts ***************")
print(artifact, region, account)
with open(template) as cftemp:
cftemplate = json.load(cftemp)
sts = session.client('sts')
assumedrole = 'arn:aws:iam::' + account + ':role/TAR-Automation' # this
needs to be
sessionname = 'cdkxadeployment'
try:
taskcreds = sts.assume_role(RoleArn = assumedrole,RoleSessionName = sessionname )
tasksession = boto3.session.Session( aws_access_key_id=taskcreds['Credentials']['AccessKeyId'],
aws_secret_access_key=taskcreds['Credentials']['SecretAccessKey'],
aws_session_token=taskcreds['Credentials']['SessionToken'] )
cf = tasksession.client('cloudformation')
print(tasksession)
except Exception as e:
print('\tThe account:', account, " can not be accessed")
print(e)
continue # this would occur if there is an auth issue / account does not exisit
try:
stack = cf.create_stack(
StackName = artifact,
TemplateBody = json.dumps(cftemplate),
Capabilities = ['CAPABILITY_NAMED_IAM'],
OnFailure ='DELETE'
)
print(stack)
except Exception as e:
print(e)`
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#3401?email_source=notifications&email_token=AAFQYFOQFGRPQSH66AWCWM3RGMWA5A5CNFSM4IGHXG32YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEOENFUY#issuecomment-596169427>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAFQYFPV3FXCBUMW6PFW2Q3RGMWA5ANCNFSM4IGHXG3Q>
.
|
For my use-case my credentials are for the 'root' Organisation account, and I am wanting to be able to deploy into the 'production' account linked to my organisation. Since I use aws-vault to manage my creds (which I believe makes them available by ENV var) I don't want to have to provide any profile names, etc. Ideally some 'automagic' assume role stuff would occur, and then the deploy would succeed as though I had directly used credentials for the production account:
Based on the blog post above, I can edit my config file as follows, which allows CDK to deploy easily cross-account:
|
If your CodeBuild has:
Would be nice if CDK just assumed the the deploy-role from the other account even though current credentials are for a different account. Otherwise, I think I have to create a role over in the other account just so CDK can then assume the deploy-role. |
A more 12-factor style solution would be extending the existing AWS environment processing with a new The CDK source would then be free of any dev specific AWS_PROFILE settings or similar: new Stack(app, 'Production', {
env: {
env_prefix: 'PROD',
},
});
new Stack(app, 'Development', {
env: {
env_prefix: 'DEV',
},
}); The dev specific configs would support all existing configs, including Using an IAM role in the AWS CLI: [profile deploy-dev]
role_arn = arn:aws:iam::523456789099:role/developmentadminrole
source_profile = user1
[profile deploy-prod]
role_arn = arn:aws:iam::123456789012:role/productionadminrole
source_profile = user1 Tying all of the above together would be applying config via prefixed AWS environment variables: $ export PROD_AWS_PROFILE="deploy-prod"
$ export DEV_AWS_PROFILE="deploy-dev"
# now we can deploy using "the ideal customer experience":
$ cdk deploy '*' Otherwise, simply adding |
This was solved with new-style synthesis (the default in CDK v2). |
|
@skinny85 Is there any way for this to work with AWS CLI credential profiles? I only see the ( |
Yes. You need to pass the |
Got it, thank you. I'll have to script something to associate stacks with credential profiles. (I was hoping for something that supported |
You shouldn't have to - if you set things up so that your base account that you're deploying from is trusted by the target accounts (see here for details), you won't need anything beyond the profile for the base account. |
After all of the issues/PRs for cross-account CodePipelines are delivered (#3208, #3323 , #3387, #3388, #3389 ), we will have a great story for making it very easy to work with cross-account CodePipelines.
However, we also need to make it easy to work with cross-account CDK apps from the perspective of authentication from the command line. Most likely, this will involve a deeper integration with AWS profiles defined in the
~/.aws/credentials
/~/.aws/config
files. A possible solution would be to allow passing profile when creating a Stack:The ideal customer experience we want here is to be able to say:
$ cdk deploy '*'
, and all of the different credentials for the different accounts the Stacks belong to will be automatically wired together.
The text was updated successfully, but these errors were encountered: