简体   繁体   中英

How to add an existing resource to stack using Python AWS-CDK?

I tried deploying with the following definition but got ExampleRole already exists error.

from aws_cdk import aws_iam as iam
from aws_cdk import core

app = core.App()
stack = core.Stack(app, "MyStack")

existing_role = iam.Role(
    stack,
    id="ExampleRole",
    assumed_by=iam.AccountPrincipal(123456789),
    role_name="ExampleRole",
)
existing_role.apply_removal_policy(core.RemovalPolicy.RETAIN)

app.synth()

What is the correct procedure using CDK only?

You can use iam.Role.from_role_arn() to import an existing IAM role by ARN;

existing_role = iam.Role.from_role_arn(
    stack,
    id="ExampleRole",
    role_arn="arn:aws:iam::123456789012:role/......",
)
existing_role.apply_removal_policy(core.RemovalPolicy.RETAIN)

I've seen cases where functions like SQS from_queue_arn() and similar ones return a read-only reference to the resource, so you can't actually modify it with your CDK code; however, from_role_arn has a mutable=True parameter which says

mutable ( Optional [ bool ]) – Whether the imported role can be modified by attaching policy resources to it. Default: true

So I'm not sure if it will work for you or not.

Root cause: you created stack, but you fetched role outside of it and therefore it is "orphan" and AWS CDK app cannot understand what it should do with it.

This problem should be addressed in three steps (bottom-up approach):

  • project structure
  • stack.py
  • app.py
  • deploy

I am using CDK v2.

0.1. Project structure

.
├── app.py
├── cdk.json
├── requirements.txt
├── .gitignore
└── stacks
    ├── stack.py
    └── __init__.py

This is a basic project structure which allows you to interact with AWS CDK.

0.2. requirements.txt

# CDK v2 update: npm install -g aws-cdk@next

aws-cdk-lib==2.0.0-rc.14
boto3

I added the content of requirements.txt just to be sure that we are on the same page. Also, it is good to update your AWS CDK npm to have the most recent version. This command should be run in cmd.

  1. stack.py
import aws_cdk as cdk
from aws_cdk import aws_iam as _iam


class MyNewStack(cdk.Stack):

    def __init__(self, scope, construct_id, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Fetch existing resources
        role = _iam.Role.from_role_arn(self, "my_existing_role",
                                       role_arn="role_arn_copied_from_webui_as-string", 
                                       mutable=False)

Here we create a stack where we list all our resources (new or already existing) using the CDK API. Link is given below to see all available options.

  1. app.py
from stacks.Stack import *

# Initializing the CDK app
app = cdk.App()
env = cdk.Environment(account=os.getenv('CDK_DEFAULT_ACCOUNT'), region=os.getenv('CDK_DEFAULT_REGION'))

# Stacks
MyNewStack(app, "stack-name-to-be-displayed-in-cloudformation", env=env)

# Required to get files updated in cdk.out
app.synth()

Here we initialize the CDK app and create instance of the class which we built previously.

  1. Deploy
$cdk ls
$cdk synth
$cdk deploy stack-name-to-be-displayed-in-cloudformation

Before deployment, it is highly recommended to run cdk ls , cdk synth , cdk diff to see if everything is okay.

Please let me know in case I can help you more. Hope you find it useful. Cheers!

References to documentation and more:

  1. Intro CDK: https://docs.aws.amazon.com/cdk/latest/guide/home.html
  2. CDK API reference: https://docs.aws.amazon.com/cdk/api/v2/python/modules.html
  3. Better way to structure projects: https://www.sentiatechblog.com/aws-cdk-structure-components
  4. CDK Patterns (real-life examples): https://cdkpatterns.com/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM