Import Resources to Stack Fails

0

I want to import an existing log group into an existing stack. There is a problem with logical Ids that prevents this from happening.

  1. I create a log group named "/aws/appsync/apis/abc123"
  2. Create a simple stack
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Conditions": {
        "NonProd": {"Fn::Equals":["prod","false"]}
    },
    "Resources": {
        "LLGEDZS": {
            "Type": "AWS::Logs::LogGroup",
            "Properties": {}
        },
    "ALogGroup": {
      "Condition": "NonProd",
      "Properties": {
        "LogGroupName": {
          "Fn::Sub": "/aws/appsync/apis/abc123"
        }
      },
      "Type": "AWS::Logs::LogGroup"
    }
    }
}
  1. The condition changes to true. "NonProd": {"Fn::Equals":["prod","prod"]}
  2. A change set is created to add a log group with name "/aws/appsync/apis/abc123".
  3. This fails because the resource already exists.
  4. Try to import "ALogGroup" into the stack but the logical id already exists and it won't import.

How do I proceed to import the log group?

enrush
asked 9 months ago321 views
2 Answers
3
Accepted Answer

I got your point, it looks like you are expecting cloudformation to consider conditions while importing resources into stack so that it can know those differences and allow you to import that resource when condition is true. I researched on this but unfortunately, there is nothing I found which could help here. However, there is a workaround which is fairly easy and is as below:

Do it in two steps, remove the block of import resource while deploying the stack in the environment where you think condition would be true. Update the template with import resource block(you know the condition would be true here), then import resources into stack.

Not sure if you could agree on this approach as there may be other caveats too but this is the only way through which you can have your templates consistent across all the environments and also achieve the end result, which you are trying to do.

profile pictureAWS
EXPERT
answered 9 months ago
profile pictureAWS
EXPERT
iBehr
reviewed 9 months ago
  • Yes exactly. The first paragraph is spot on! This seems like a limitation.

1

When you import already existing resources to a stack, each resource to import must have a DeletionPolicy attribute in your template. Also consider changing the logical id, this can be anything but make sure resource name(in your case log group name) matches.

Something like this:

"DeletionPolicy": "Retain"

Please refer Importing existing resources into a stack for additional details and examples.

=====Edit=====

So here is how I would do:

Step-1: Log group: /aws/lambda/test -> Created via test lambda function call, not through cloudformation.

Step-2: Created a stack with following template(just an example, where I'm creating a resource, one log group per say):

AWSTemplateFormatVersion: '2010-09-09'
Resources:
  ALogGroup:
    Properties:
      LogGroupName:
        Fn::Sub: "/aws/lambda/test4"
      RetentionInDays: 7
    Type: AWS::Logs::LogGroup

Step-3: Updated template as below to import existing log group "/aws/lambda/test"

AWSTemplateFormatVersion: '2010-09-09'
Resources:
  ALogGroup:
    Properties:
      LogGroupName:
        Fn::Sub: "/aws/lambda/test4"
      RetentionInDays: 7
    Type: AWS::Logs::LogGroup
  BLogGroup:
    Properties:
      LogGroupName:
        Fn::Sub: "/aws/lambda/test"
      RetentionInDays: 7
    Type: AWS::Logs::LogGroup
    DeletionPolicy: "Retain"  

Step-4: Go to stack actions -> import resources into the stack -> Upload this updated template -> gave name of the log group to import ie. /aws/lambda/test -> imported

BLogGroup got imported successfully and now part of this stack.

Step-4: Now update the stack by updating the RetentionInDays value to desired value for BLogGroup. make sure you specify any value from this list only Possible values are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1096, 1827, 2192, 2557, 2922, 3288, and 3653. Reference

Hope you find this useful.

Abhishek

profile pictureAWS
EXPERT
answered 9 months ago
  • Hi Abhishek, thanks so much for the response. I did that in step 6. It doesn't work because Cloudformation doesn't see this resource as a new logical id

  • I was updating this answer as I missed to mention one point as this one "Also consider changing the logical id, this can be anything but make sure resource name(in your case log group name) matches." Hope this helps, let me know how it goes.

  • That seems hacky. I have to change the logical id of all the stages for all the log groups I want to import because a condition changed.

  • How was this logroup created at first place?

  • A Lambda function creates a log group by default. So even though the template has the NonProd condition, the log group gets created anyway in Prod.

    Now I want to set a retention period on the logs in Prod and I'm hitting this problem.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions